1.1 开始第一幅“码绘”——以编程作画的基本方法 - Go语言中文社区

1.1 开始第一幅“码绘”——以编程作画的基本方法


引言

请看下面两幅图,并思考:二者有何联系?

对于完全没有接触过编程的小朋友来说,估计现在表情和图中人物一样。就通常而言,编程和绘画可谓风马牛不相及。

编程与绘画的关联

现在,认真地对照下图中左右两边:

图中,左边是一段程序代码,右边是一段实际作画的过程。作画分为两个主要阶段:准备阶段和作画阶段。在准备阶段,主要就是搞定“画布”;而在作画阶段,则是按照一定的顺序画出的卡通头像的各个部分。左边的程序代码与实际作画过程完全对应。尽管不明白代码中的英文、符号和数值的具体含义,但已经可以看出,这段程序代码精确描述了画画的过程。由此,引出介绍一个基础概念,姑且算是个定义吧:

过程式编程:用代码来描述做事的过程。

对应在本教程中,过程式编程就是“用代码指挥画画的过程”。

迈出了第一步,即可以开始去理解这些代码的精确含义。

编程的基本概念

为了讲解和沟通,要了解一些基本概念,包括

语句、注释;

函数、函数定义、函数调用,参数、形式参数、实际参数;

关键词;

库、框架;

观察下图:

在图中,每一个分号结尾的一行字符就是一个”语句“,其实就是表达了做了一个小的步骤。

而每一行以双斜杠“//”为起始的一行字符就是一行“注释”,它不是实际执行的内容,而是用于解释代码。事实上,因为它不会在程序运行中实际地执行,写任何内容都不会对执行效果产生影响,但是写错误地内容会对理解这段程序制造人为障碍。因此,写注释也要注意,应该做到对代码的正确解释。

此外,上述代码可以明确分解为两个独立地段落,即:

function setup() {
// 1. 准备阶段
// ......代码略
}

function draw() {
// 2. 绘制阶段
// ......代码略
}
这是两个函数,并且是二者的函数定义,它们的名称分别为setup和draw,即它们的函数名;函数名前面的词语function是一个关键词,就是在编程中有特殊预设意义的词,这个function就是用于定义函数的关键词;函数名后的小括号也是格式要求必须要写上的,有了这个括号,就代表它是一个函数了。后面的大括号{}中则是定义了这个函数具体要执行的内容。

对于上述setup函数的定义,可以用口语翻译为:定义了一个名为setup的函数,它执行的具体行为是{}中的一系列内容。

事实上,笔者总觉得“函数”这个术语过于学术化,一看就是数学用语,很容易吓跑一大群小朋友。若叫做“功能“、”行为“、"作用”恐怕更为贴切,因为它表达的就是一个行为,即将一大段琐碎的具体过程用一个简单的称呼来概括的表达,例如函数draw中那么一大段代码,对其概括段落大意,即为”画“,也就是函数名”draw"。就“函数”这一术语的来源"function“一词,其实直观翻译便是”功能“,而非数学意义上的”函数“。

再举个例子来说明”函数“吧。看下面一段描述:

睁开眼,缓缓坐起来,伸伸懒腰,掀开铺盖,左脚先落地,试探着找到鞋子,然后右脚落地,伸入鞋子,站起来,看看窗外的阳光,说到“又是美好的一天”;

概括段落大意,可以表述为“起床”。现在,仿造上面的“函数定义”的代码格式写下来,即定义函数“起床”:

function 起床()
{
睁开眼;
缓缓坐起来;
伸伸懒腰;
掀开铺盖;
左脚先落地,试探着找到鞋子;
然后右脚落地,伸入鞋子;
站起来;
看看窗外的阳光;
说到“又是美好的一天”;
}
如此解释,是否明白?当然,上述代码只是示意而已,实际上是无法执行的,因为常用的编程语言都不能用中文写。
此外,函数setup和draw的具体定义中,也就是那一大堆语句,其实也都是函数。但在这些语句中不是去定义函数,而是在进行函数调用,或者说是对函数的执行/使用/施放/发招。例如,"createCanvas(640,480);" 就是”执行/使用/施放/发招/调用"了一个名为createCanvas的函数,括号中的640和480是“参数”,将这一句翻译程中文,即”创建一块方形画布,宽度为640像素,高度为480像素“。再如“ellipse(320,240,200,200);”,翻译过来,即“画一个椭圆,中心位于坐标(320,240),横轴长度为200像素,纵轴长度为200像素"。由此可见,函数还可以有”参数“,在函数的定义中的参数便是形式参数,即数值未确定的量;而且在实际调用时,这些参数可以指定不同的具体数值,即实际参数,从而达到不同的具体效果。作为类比,假设”吃“这个行为也定义为一个函数,那么为了表达吃不同的量,例如“吃1斤,吃2斤,吃100斤”等不同的效果,就可以把具体吃的量设定为参数,表达为类似于上述代码的形态,写为语句,即:
函数定义:
function 吃(var amount)
{
//代码略
}
函数调用:
吃(1);
吃(2);
吃(100);
下面再图示一下函数的相关概念:
这里恐怕会产生个两个疑问:
  • 疑问1. createCanvas、ellipse、line这些函数是哪冒出来的?怎么没个具体定义就能用了?
解答:这些都是来自于p5.js的。它们其实是我们所要学习的编程环境p5.js提供的,相当于有人帮忙定义好了,我们在这里只需要调用即可。上述程序中的函数ellipse(*)和line(*)亦是如此。p5.js可以看作是一个已经定义好的庞大的“”,它里面定义的一大堆函数都是可以直接调用的,这样我们就可以反复地将它们以不同顺序进行组织和调用,从而编写出各种酷程序。p5.js提供的大量函数将在后续课程中慢慢展开。一个库就相当于提供了零件/预制件/工具/手册的仓库,这些物件都是前人预先开发好的,为他人提供了直接可以使用的大量积木块,让开发更便捷。
  • 疑问2. 函数setup()和draw()仅仅是有了定义,为什么就实际产生作用,画出东西来了?这不就和刚刚提到的“函数调用了才产生实际作用”产生矛盾了?
解答:它们其实都是在p5.js的框架中调用的。p5.js不仅仅提供一大堆可以直接用的”零件“,而且还提供了一个完整的可执行程序的模板,即设计了程序的基本结构,划分好了内部的各个功能模块和协作关联,其中一些模块的功能已经完成,另一些模块则是规定好了它与其它模块之间连接的规范。于是,在编程时就只需要按照它规定的模式,将为完工的模块开发完毕即可。也就是说p5.js本身就提供了一个可执行的程序,其中setup()和draw()函数是两个需要有编程者来完成的部分,它们在整个程序中的调用方式已经预先定好了。因此,我们只需要吧setup()和draw()写出来,p5.js就能够去指挥调度它们了。
为了深化框架这两个概念的理解,我们以作画来类比:库相当于绘画工具包,里面有一系列画笔、颜料等材料,而框架相当于预先定好的要绘制作品的基本格式,例如”画布是平面的,画布用亚麻布,画框的长宽比例是4:3”等,于是,画家要做的就是用一定的“技法”去操作工具包中的各种材料,再规定好的“框架”上画出自己想要的内容。还可以用制造汽车来类比:库相当于制造车间,里面有各种零件/预制件/工具,而框架相当于汽车的基本规格,比如”有两个轴,装四个轮子,轴长和轴间距在某个范围,四个轮子上会有个承载区域,区域上需要有空间安装引擎,并装一个供司机操作的驾驶舱“,并且这个框架上可能已经预制了一些部件,比如承载版/轴和引擎。于是,汽车的设计和制作就是要完成其它未确定的部件。
了解了这些概念,再去理解最前面那堆代码就容易了:
函数setup()和draw()分别定义了绘画的两个阶段:准备阶段和绘制阶段;在setup()中,做了一件事,即语句"createCanvas(640,480);",含义就是创建画布,宽度640像素,高度480像素;而在draw()中,以一定步骤依次做了一系列事情,一部分事情是通过调用函数ellipse()完成,例如,画脸即语句“ellipse(320,240,200,200);”,含义就是画一个椭圆,中心在坐标(320,240),横轴和纵轴长度都是200像素,还有一部分事情(即画头发)是调用函数line完成,例如,画第一根头发的语句是“line(260,180,260,100);”,含义就是,画一根直线,两个端点坐标分别为(260,180)和(260,100);此外,在画眼珠前还调用了一个函数“fill(0);",其含义是堆后续绘制的几何形体时填充黑色(数值0表示黑色),于是,画出的圆形就成了黑色实心的效果。


相关资源:

示例程序代码:https://github.com/magicbrush/DrawingByCodingTutorialDemos/















版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/magicbrushlv/article/details/77840565
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-02-13 12:02:39
  • 阅读 ( 1249 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢