1.5 开始第一幅“码绘”——自定变量与函数,创一招“懵逼表情涂”
引言——想要重复绘制内容应该怎么办?
目前我们已经清晰地理解了如何用代码绘制1个懵逼脸。
现在升级一点难度,考虑一个问题:
如果要在屏幕上不同位置画N个懵逼脸,怎么办?
若采用之前一样的方法,我们可以在绘制完一个脸后,用重复的代码(不同参数)绘制另一个脸,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
// 函数setup() : 准备阶段
function setup() {
// 创建画布,宽度640像素,高度480像素
// 画布的坐标系统为,左上角坐标为(0,0),
// x方向水平向右,y方向垂直向下,单位像素
createCanvas(640,480);
}
// 函数draw():作画阶段
function draw() {
// 画第一个脸
fill(255);// 填充白色
// 1 画脸
ellipse(320,240,200,200);// 圆圈
// 2 左眼
ellipse(280,240,50,50);// 另一个圆圈
// 3 右眼
ellipse(360,240,50,50);
// 4 嘴巴
ellipse(320,300,80,40);
fill(0);// 填充黑色
// 5 左眼珠
ellipse(280,240,20,20);
// 6 右眼珠
ellipse(360,240,20,20);
// 7 头发:从左到右画一排竖线
line(260,180,260,100);
line(280,180,280,100);
line(300,180,300,100);
line(320,180,320,100);
line(340,180,340,100);
line(360,180,360,100);
line(380,180,380,100);
// 以下为重复代码,但参数不同
// 画第二个脸
fill(255);// 填充白色
// 1 画脸
ellipse(220,240,200,200);// 圆圈
// 2 左眼
ellipse(180,240,50,50);// 另一个圆圈
// 3 右眼
ellipse(260,240,50,50);
// 4 嘴巴
ellipse(220,300,80,40);
fill(0);// 填充黑色
// 5 左眼珠
ellipse(180,240,20,20);
// 6 右眼珠
ellipse(260,240,20,20);
// 7 头发:从左到右画一排竖线
line(160,180,160,100);
line(180,180,180,100);
line(200,180,200,100);
line(220,180,220,100);
line(240,180,240,100);
line(260,180,260,100);
line(280,180,280,100);
}
|
这样就能绘制两个脸:
但是......我想画20个脸,咋办?????
不嫌累的话可以试试写20遍重复代码......,希望不要勾起被老师罚抄课文的苦难记忆......
可见,这个办法的局限也是相当明显的。
用自定义函数实现功能复用
为了解决这个麻烦,我们需要获得一项新技能:自定义函数。
回顾一下1.1节中讲到的“函数”,或者说“招数/方法/行为/职能/功能”,只要有了某个函数定义,也就是概括了某种做事的流程,然后在我们想要的地方便可以“调用”它,或者说是“施放/执行/行使/发招”。例如,我们可以设想已经定义了一个“DrawConfuseFace”的函数,然后,在draw()函数中就可以直接调用这个函数两次,实现画两个懵逼脸。也就是,我们现在期望的draw()函数写法:
这当然是可行的!而且实现后效果如下:
为了实现这个drawConfuseFace函数,我们要依次搞清楚3项技能: 1.自定义函数;2.自定义变量;3.函数参数
自定义函数
在1.1节的讲解中,已经了解到“函数定义”的基本办法,也就是现有代码中函数setup()和draw()的写法即函数定义。
那么,我们仿照draw()函数的写法,在其后新写一个函数,并在draw()函数中直接调用它20遍!希望能画出20个懵逼脸。
代码如下:
然而,却只能画出来1个脸:
自定义变量
在之前实现的用鼠标控制位置的代码中,我们用到了两个变量mouseX和mouseY,它们是p5.js提供的可以在任意时刻任意位置直接访问的变量。为了更加灵活地指定位置,我们可以用自定义变量。
下列代码示例了在程序中自定义变量:
在定义了上述变量后,便可以在需要的时候使用它们,就如同使用变量mouseX和mouseY一般,例如:
此外,在变量定义中,用到了 赋值符"=",要注意,它的作用有点像是“等于”,但其实应该理解为“赋值”,其目的是将右边的表达式的计算结果赋予左边的变量,下面列出一些用法示例:
掌握了自定义变量,我们对原来的代码进行改造。原始代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
// 函数setup() : 准备阶段
function setup() {
// 创建画布,宽度640像素,高度480像素
// 画布的坐标系统为,左上角坐标为(0,0),
// x方向水平向右,y方向垂直向下,单位像素
createCanvas(640,480);
}
// 函数draw():作画阶段
function draw() {
fill(255);// 填充白色
// 1 画脸
ellipse(mouseX,mouseY,200,200);// 圆圈
// 2 左眼
ellipse(mouseX-40,mouseY,50,50);// 另一个圆圈
// 3 右眼
ellipse(mouseX+40,mouseY,50,50);
// 4 嘴巴
ellipse(mouseX,mouseY+60,80,40);
fill(0);// 填充黑色
// 5 左眼珠
ellipse(mouseX-40,mouseY,20,20);
// 6 右眼珠
ellipse(mouseX+40,mouseY,20,20);
// 7 头发:从左到右画一排竖线
line(mouseX-60,mouseY-60,mouseX-60,mouseY-140);
line(mouseX-40,mouseY-60,mouseX-40,mouseY-140);
line(mouseX-20,mouseY-60,mouseX-20,mouseY-140);
line(mouseX ,mouseY-60,mouseX ,mouseY-140);
line(mouseX+20,mouseY-60,mouseX+20,mouseY-140);
line(mouseX+40,mouseY-60,mouseX+40,mouseY-140);
line(mouseX+60,mouseY-60,mouseX+60,mouseY-140);
}
|
用自定义变量对其进行改造:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// 函数setup() : 准备阶段
function setup() {
// 创建画布,宽度640像素,高度480像素
// 画布的坐标系统为,左上角坐标为(0,0),
// x方向水平向右,y方向垂直向下,单位像素
createCanvas(640,480);
}
// 函数draw():作画阶段
function draw() {
// 定义两个变量,并对其赋值为当前鼠标坐标
// 之后的所有语句都用这两个变量来设定绘制位置
var centerX = mouseX;
var centerY = mouseY;
fill(255);// 填充白色
// 1 画脸
ellipse(centerX,centerY,200,200);// 圆圈
// 2 左眼
ellipse(centerX-40,centerY,50,50);// 另一个圆圈
// 3 右眼
ellipse(centerX+40,centerY,50,50);
// 4 嘴巴
ellipse(centerX,centerY+60,80,40);
fill(0);// 填充黑色
// 5 左眼珠
ellipse(centerX-40,centerY,20,20);
// 6 右眼珠
ellipse(centerX+40,centerY,20,20);
// 7 头发:从左到右画一排竖线
line(centerX-60,centerY-60,centerX-60,centerY-140);
line(centerX-40,centerY-60,centerX-40,centerY-140);
line(centerX-20,centerY-60,centerX-20,centerY-140);
line(centerX ,centerY-60,centerX ,centerY-140);
line(centerX+20,centerY-60,centerX+20,centerY-140);
line(centerX+40,centerY-60,centerX+40,centerY-140);
line(centerX+60,centerY-60,centerX+60,centerY-140);
}
|
如此改造后,程序运行的结果并未变化,也就是绘制一个跟随鼠标运动的懵逼脸。
但这样改造仍然有两个好处,一方面是具备了更佳的可读性,因为我们定义的变量名称centerX和centerY本身就使用了具有明确含义的词汇center,其名称就说明了它们是绘制的懵逼脸的“中心”位置;另一方面,代码具有了更好的可扩展性:这两个变量的数值可以在后续过程中任意时刻发生变化,而不会像mouseX和mouseY那样始终是鼠标位置;并且,重点是,这种改造便于我们将这一段代码改造为带参数的函数。(●ˇ∀ˇ●)
函数参数
如此一来,我们便可以在draw()函数中以带参数的形态调用drawConfuseFace()了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
// 函数setup() : 准备阶段
function setup() {
// 创建画布,宽度640像素,高度480像素
// 画布的坐标系统为,左上角坐标为(0,0),
// x方向水平向右,y方向垂直向下,单位像素
createCanvas(640,480);
}
// 函数draw():作画阶段
function draw() {
// 在鼠标位置及其上下左右绘制5个懵逼脸
drawConfuseFace(mouseX-100,mouseY);
drawConfuseFace(mouseX+100,mouseY);
drawConfuseFace(mouseX,mouseY-100);
drawConfuseFace(mouseX,mouseY+100);
drawConfuseFace(mouseX,mouseY);
}
function drawConfuseFace(posX, posY)
{
fill(255);// 填充白色
// 1 画脸
ellipse(posX,posY,200,200);// 圆圈
// 2 左眼
ellipse(posX-40,posY,50,50);// 另一个圆圈
// 3 右眼
ellipse(posX+40,posY,50,50);
// 4 嘴巴
ellipse(posX,posY+60,80,40);
fill(0);// 填充黑色
// 5 左眼珠
ellipse(posX-40,posY,20,20);
// 6 右眼珠
ellipse(posX+40,posY,20,20);
// 7 头发:从左到右画一排竖线
line(posX-60,posY-60,posX-60,posY-140);
line(posX-40,posY-60,posX-40,posY-140);
line(posX-20,posY-60,posX-20,posY-140);
line(posX ,posY-60,posX ,posY-140);
line(posX+20,posY-60,posX+20,posY-140);
line(posX+40,posY-60,posX+40,posY-140);
line(posX+60,posY-60,posX+60,posY-140);
}
|
补充:变量的作用域和生命周期
为了用好变量,还需要了理解它的作用域和生命周期。
一个变量的作用域就是指在程序代码的哪些部分能够访问到这个变量,从下图中可以看出作用域的几种典型情况:
执行效果如下:
有关作用域,可以查看这里的解释:http://www.runoob.com/js/js-scope.html
知识点
函数:http://www.runoob.com/js/js-functions.html
作用域:http://www.runoob.com/js/js-scope.html
相关资源
教程示例程序:https://github.com/magicbrush/DrawingByCodingTutorialDemos/
1.5 开始第一幅“码绘”——自定变量与函数,创一招“懵逼表情涂”相关推荐
- p5.js 我的第一幅码绘——小丑
p5.js 我的第一幅码绘--小丑 码绘相比较于手绘肯定是要繁琐,但优势在于可以做一些有意思的动态效果和交互. 效果图 小交互--癫狂状态的小丑 DC漫画里,小丑是个癫狂的角色,令人战栗.让我们展现一 ...
- 手绘与码绘的比较——实战之梵高《星空》
手绘与码绘的比较--实战之梵高<星空> 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近博主的老师在交互媒体设计课上布置了一个作业,是关于"运动"主题的作品创 ...
- 码绘VS手绘(一) 编程与手绘的对比
前言 本文主要讲解在静态图方面如何分别通过手绘和码绘两种方式来表现,以及它们之间的差异与联系,谨以此博客记录学习过程.博主新手一枚,这是博主第一次写博文,若有不足之处,还请温柔拍打~~(笔芯~~) 手 ...
- 【动态】码绘VS手绘的对比——有点萌的开关
[动态]码绘VS手绘的对比--有点萌的开关 背景简介 主题 成果展示 前期分析 制作过程 体会与思考 参考资料 背景简介 上一次简单的通过静态的手绘与码绘对两者进行了一些简单的对比,这一次更加好玩了, ...
- 码绘与手绘——表达动态
一.手绘表现动态: 这个题目一开始看来 ,手绘是处于非常劣势的地位的,因为电脑上可以实现动态的过程,就是用动画的原理,每秒绘制60帧,不断进行重绘图形,来达到运动的效果的. 而本身来讲,手绘的图片本质 ...
- 码绘VS手绘(二)动态绘图
码绘VS手绘(二)动态绘图 一.前言 二.实验内容 (一)主题 (二)实验结果 1.码绘 最终效果 程序结构 具体函数解析 2.手绘 三.总结--编程与手绘的比较 1.工具和载体 2.技法 3.理念 ...
- 手绘与码绘的比较---模拟风吹树动
手绘与码绘的比较-模拟风吹树动 一.内容介绍 本文主要介绍用手绘和码绘两种方式模仿一种自然现象–风吹树动的过程,以及在实现过程对这两种方式的比较和思考.之所以选择风吹树动,是因为每次速写画一些场景时( ...
- 手绘VS码绘——动态篇(视觉错觉)
前言 在介绍这次的实验前,先让我们看看一组图片: 相信大家看完这组图片已经有点难受的想点一下右上角的X了,其实不止你们,我在写这篇文章的时候也想关掉它-- 接下来我就按照正常的介绍流程告诉大家,这些图 ...
- 手绘 v.s. 码绘(1.2 实践报告)
目标 多角度比较手绘与码绘:技法.工具.理念.创作体验.呈现效果.载体.局限性.应用-- 思考深刻,理论完善,参考资料详实规范,必须引用文末的参考文章 使用各种论证方法,体现严谨清晰的逻辑 按时间线对 ...
最新文章
- 【学习笔记】Android 图像处理
- 支持鸿蒙的手机型号多少钱,华为鸿蒙系统支持手机型号一览
- linux 内核发布时间,求问Linux最新内核版本以及发布日期。
- 一个简单词法分析器的实现代码(java实现)
- 关于Oracle回收站的一些操作
- C#编程尽量使用接口(转)
- python源码文件以什么格式结尾结尾_查看python源码,发现里面的函数都以pass结尾,那么意义何在?...
- 隐藏文件或文件夹属性无法修改解决方案
- Net 4.0并行库实用性演练
- java中如何定位文本框_div定位在文本框下
- 移动开发者走向全能开发者的五大技能
- 联想g510升级换什么cpu好_联想G510笔记本完全拆机指南(图解)
- C语言中的EOF是什么?
- Android水波纹效果
- 先进的半导体晶圆清洗技术
- Bootstrap3 按钮状态切换
- 教你怎么解决Linux依赖包第一篇:pkgs.org资源网下载
- 【Java】JVM内存回收
- oracle 数据泵 network link使用
- ImportError: cannot import name ‘ModelOutput‘ from ‘smplx.body_models‘