p5.js(2)自画像“码绘”

主题

  • 得到一件编程创意作品,必须实现动态效果或交互效果
  • 作品可以是具象化地描绘自己的形象,也可以是任何形式表现自己的兴趣、追求、特色、经历等
  • 作品录制一段一分钟内的视频

编程语言:p5.js
编程工具:Sublime Textp5.js在线编辑器

效果展示

效果gif

画像简介

内容

  • 显然这是脸
  • 不知道你有没有注意到它分成左右两半
  • 两边的脸是不同情绪的,左边开心,右边不快,遮挡着看可能会更明显一些
  • 本意是表达两面或者不同情绪,但是可能对比不太明显

动态与交互

  • 鼠标的位置上始终有一个小心形一样的东西标志鼠标的实时位置,形象如下——
    标志鼠标

  • 鼠标移动时会有三个变化——
    两半的背景颜色分别变化,但始终右边的暗沉一些
    人物的眼睛高光部分会跟随鼠标的移动而移动,像是在看向鼠标
    人物的嘴角会变化,左半边在是否上扬间变化,右半边在是否下撇间变化

  • 鼠标点击时会有两个变化——
    人物的眼睛会闭起来,而且闭上的状态也因表达心情的不同而不同
    左右两边会出现不同的简陋特效,左边是闪烁的亮黄心心,右边是闪烁的愤怒标志,也是与心情相对应的
    鼠标点击

实现过程

实现流程

布置背景
画发,脸,耳,眉
鼠标是否点击
点击效果
未点击效果
鼠标标志 中轴线

其中所有的五官都是分左右两半分别编写的。

几个关键函数

贝塞尔函数

p5.js中的函数释义
bezier
线性贝塞尔曲线
给定点 P0、P1,线性贝塞尔曲线只是一条两点之间的直线。这条线由下式给出:
在这里插入图片描述
二次方贝塞尔曲线
路径由给定点 P0、P1、P2 的函数 B(t) 追踪
在这里插入图片描述
三次方贝塞尔曲线
P0、P1、P2、P3 四个点在平面或在三维空间中定义了三次方贝塞尔曲线。曲线起始于 P0 走向 P1,并从 P2 的方向来到 P3。一般不会经过 P1 或 P2;这两个点只是在那里提供方向资讯。 P0 和 P1 之间的间距,决定了曲线在转而趋进 P3 之前,走向 P2 方向的“长度有多长”
在这里插入图片描述
在p5.js函数中,bezier前两个参数指定曲线第一个点,后两个参数指定另一个点。中间的参数指定了定义曲线形状的控制点,编写时通过不断调节控制点的位置画出想要的效果。

curve函数

p5.js中的函数释义
在这里插入图片描述
简单地说

curve(控制点1,起点,终点,控制点2)

其中每个点都由两个参数x,y表示。控制点1控制起点,控制点2控制终点。具体绘制时先确定起点和终点的位置,再通过调节控制点改变曲线的形状。

arc函数

p5.js中的函数释义在这里插入图片描述
后两个参数表示的是起点和终点,编写时通过调节起点与终点实现不同圆弧的绘制。

线宽函数

p5.js中的函数释义在这里插入图片描述
这个函数很简单,使用方法和作用一目了然,但是有一点要注意——在这一次设置了线宽后,如果后面没有再设置,线宽将保持不变!所以如果你只是想改变一小部分绘画的线宽,在画完之后一点更要记得重新设置回来呀!

代码实现

布置背景

	//背景布置
	noStroke();
	if(mouseX<=400&&mouseX>=0) dx=mouseX/10;
	if(mouseY<=400&&mouseY>=0) dy=mouseY/10;
	fill(244,121+dx,131+dy);//粉色
	rect(0,0,200,400);
	fill(128+dx,128+dy,128);//浅灰色
	rect(200,0,400,400);

画头发、脸、耳朵

//头发
	strokeWeight(4);
	noFill();
	stroke(160,82,45);//黄土赭色
	fill(210,105,30);//巧克力色
	bezier(80, 380, -60, -100, 460, -100, 320, 380);

	//齐刘海
	strokeWeight(4);
	stroke(160,82,45);//黄土赭色
	line(110,180,130,180);
	line(140,180,200,180);
	line(210,180,230,180);
	line(245,180,290,180);
	
	//刘海隙
	noStroke();
	fill(255,245,215);//肉色
	triangle(130,180,135,140,140,180);
	triangle(200,180,205,110,210,180);
	triangle(230,180,238,135,245,180);

	stroke(160,82,45);//黄土赭色
	line(130,180,135,140);
	line(135,140,140,180);
	line(200,180,205,110);
	line(205,110,210,180);
	line(230,180,238,135);
	line(238,135,245,180);

	//脸
	strokeWeight(2);
	stroke(160,82,45);
	fill(255,245,215);//肉色
	bezier(110, 180, 100, 350, 300, 350, 290, 180);


	//耳朵
	stroke(160,82,45);
	fill(255,245,215);//肉色
	//bezier(60, 20, 30, 0, 15, 50, 50, 60);
	bezier(108, 200, 80, 180, 65, 230, 115, 240);
	bezier(292, 200, 320, 180, 335, 230, 285, 240);//关于x=200对称

画眉毛

由此处开始出现左右不对称的情况了,因为要用无关来表现人物(应该就是我)的心情了!

	//左眉毛
	strokeWeight(4);
	stroke(160,82,45);
	noFill();
	//curve(5, 70, 4, 10, 44, 10, 40, 70);
	curve(145, 260, 145, 200, 185, 200, 190, 260);

	//右眉毛
	stroke(160,82,45);
	noFill();
	line(215,195,255,188);

画眼睛嘴巴

这里进入了整个自画像有关交互和动态变化的关键点
在这里会涉及到——

  • 鼠标点击的判断
    在这里插入图片描述

mouseIsPressed 系统变量将会在滑鼠键被按下时为真(true),而没按下时为假(false)。

我们将写眼睛嘴巴的两个状态或变化,分别放在点击与不点击中,实现鼠标点击使表情变化。

  • 鼠标移动的变化
    这其中包括

    鼠标移动眼睛跟随

    鼠标移动两侧嘴角不同的变化

(背景的变化写在了背景部分中)

所以就是 m o u s e X mouseX mouseX m o u s e Y mouseY mouseY 的运用

mouseX 系统变量将会储存当时的鼠标相对于画布 (0, 0) 位置的的横向位置。如果使用的是触动而不是滑鼠的话,mouseX将会储存上一个触动点的 x 值。

mouseY 系统变量将会储存当时的鼠标相对于画布 (0, 0) 位置的的直向位置。如果使用的是触动而不是滑鼠的话,mouseY将会储存上一个触动点的 y 值

接下来展出代码(好长,做好准备)

if(mouseIsPressed)//鼠标按下
	{
		drawAngry(340,50);
		drawAngry(250,100);
		drawAngry(380,200);
		drawAngry(270,300);
		drawAngry(370,380);

		drawSun(50,80);
		drawSun(100,300);
		drawSun(150,30);
		drawSun(30,210);
		drawSun(10,380);


		//左眼
		strokeWeight(4);
		stroke(160,82,45);//黄土赭色
		line(145,210,185,225);
		line(145,240,185,225);

		//左侧嘴巴
		noFill();
		arc(200,240,100,80,HALF_PI,-PI-0.3);

		//右眼
		strokeWeight(4);
		stroke(160,82,45);//黄土赭色
		line(215,220,220,225);
		line(220,225,255,220);

		//右侧嘴巴
		line(200,280,220,285);

	}
	else
	{
		//控制眼睛移动
		if(mouseX<=400)
		{
			x=mouseX/400*10;
		}
		else
		{
			x=10;
		}
		if(mouseY<=400&&mouseY>=0)
		{
			y=mouseY/400*14;
		}
		else if(mouseY>400)
		{
			y=14;
		}
		line(160+x,215+y,160+x,225+y);

		//左眼
		strokeWeight(2);
		stroke(160,82,45);//黄土赭色
		line(145,210,185,210);
		fill(160,82,45);
		rect(155,210,20,30,5);

		strokeWeight(6);
		stroke(255);
		line(160+x,215+y,160+x,225+y);

		//右眼
		strokeWeight(2);
		stroke(160,82,45);//黄土赭色
		line(215,205,220,210);
		line(220,210,255,205);
		fill(160,82,45);
		rect(225,210,20,30,5);

		strokeWeight(6);
		stroke(255);
		line(230+x,215+y,230+x,225+y);

		//左侧嘴巴
		strokeWeight(2);
		stroke(160,82,45);//黄土赭色
		noFill();
		if(mouseX>=200&&mouseX<=400)
		{
			xml=(mouseX-200)/300;
		}
		else if(mouseX<200&&mouseX>=0)
		{
			xml=0;
		}
		arc(200,240,100,80,HALF_PI,-PI-0.3-xml);

		//右侧嘴巴
		strokeWeight(2);
		stroke(160,82,45);//黄土赭色
		if(mouseX<=200&&mouseX>=0)
		{
			xmr1=mouseX/10;
			xmr2=mouseX/40;
		}
		else
		{
			xmr1=20;
			xmr2=5;
		}
		line(200,280,210+xmr1,282.5+xmr2);
	}

d r a w S u n drawSun drawSun d r a w A n g r y drawAngry drawAngry 是我自定义的两个简陋特效函数)

画中轴线、鼠标标志、简陋特效

这几个就都是简单的绘制图形了
但有一点!之所以把中轴线和鼠标标志放在 d r a w draw draw函数的最后编写,是为了让中轴线和鼠标的小标志能在所有的图像之上,不会被覆盖~

	//中轴线
	strokeWeight(5);
	stroke(255);//白色
	line(200,0,200,400);
	
	mouseShape(mouseX,mouseY);
function drawAngry(x,y)
{
	r=random(5,20);
	d=2*r;
	noFill();
	stroke(220,20,60);
	strokeWeight(4);
	arc(x-r,y-r,r,r,0,HALF_PI);
	arc(x+r,y+r,r,r,0,HALF_PI);
	arc(x+r,y-r,r,r,0,HALF_PI);
	arc(x-r,y+r,r,r,0,HALF_PI);
}
function drawSun(x,y)
{
	r=random(5,15);
	d=2*r;
	stroke(255,241,67);
	strokeWeight(2);
	fill(255,241,67);
	ellipse(x,y,d,d);
	ellipse(x+10,y,d,d);
	ellipse(x+5,y+5,d,d);
}
function mouseShape(x,y)
{
	stroke(234,205,118);
	fill(234,205,118);
	ellipse(x,y,5,5);
	ellipse(x+10,y,5,5);
	ellipse(x+5,y+5,5,5);
}

这些代码是按照我的绘画过程粘贴的,把他们拼接起来就是完整的全部代码啦!

最后

这次的自画像任务很开放,完完全全由自己一手创作,想画什么就画什么,所以在完成作业的过程中也收获了很多创作的快乐。每当有新想法蹦出来时,一点一点地寻找实现方法,这个摸索过程十分让人沉浸。
但是绕来绕去我会的还是不多,所以只能做成这样一个简单的作品了,之后再继续加油吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值