美文网首页
神马?Python也能画画!父与子的编程之旅 学习笔记(14)2

神马?Python也能画画!父与子的编程之旅 学习笔记(14)2

作者: HelloFloria | 来源:发表于2018-08-23 22:52 被阅读0次

    第十六章 图形

    (1)寻求帮助——Pygame

    (2)Pygame窗口

    新建pygame窗口

    注意这里需要用到while做一个事件循环,否则pygame窗口没有办法关闭,并且窗口会处于死机状态。

    新建好的pygame窗口

    (3)在窗口中画图

    新增了以上三行代码 运行结果 画圆的具体属性名

    从画圆的几个属性,我们可以展开来学习:

    (1)Pygame表面(surface)

    可以有多个表面,其中这里用到的是screen。另外显示表面是双缓冲的(double-buffed),我们可以在缓冲区里画圆,然后“翻转”显示表面,以显示绘制好的图像以节省时间。

    (2)Pygame的颜色

    在自然课中我们知道,混合光的三原色(红绿蓝)可以得到任何颜色;在计算机中,我们也利用类似的方法,将不同程度的红绿蓝,对应数字0~255,由一个包含了三个整数的列表给出颜色:

    1️⃣如果所有数字都是零,那么颜色全无→全黑

    2️⃣如果三个都是255,那就是三种颜色以最大亮度混合在一起→全白

    3️⃣如果是三个颜色都一样,如[155,155,155],你就会得到某种灰度

    4️⃣Pygame提供了一个命名颜色的列表,可以先增加以下代码:

    from pygame.color import THECOLORS

    然后需要用到时可以这样:

    pygame.draw.circle (scree, THECOLORS["red"], [100,100], .....)

    (3)Pygame的位置——屏幕坐标

    x轴:水平方向

    y轴:垂直方向

    假如说我们要将圆画在(640,480)大小的屏幕中间,可以将圆心放在(320,240)。

    (4)形状大小

    使用Pygame的draw函数画图像时,必须指定形状的尺寸。对于圆来说就是半径,对于另外的图形,以rect(方形)为例,则必须指定长和宽等其他尺寸:

    Rect(left, top, width, height)

    方形(距离x轴长度,距离y轴长度,长,宽)

    画图时,可以直接指定,也可以将矩形的位置和大小封装到列表里:

    my_list = [250, 150, 300, 200]

    pygame.draw.rect(screen, [255,255,255], my_list, 0)

    (5)线宽(线的宽度)

    假如线宽=0:默认将整个图案填充满;

    假如线宽=2或其他数字:给图案描边。

    (6)让Python生成现代艺术:

    代码 运行结果

    另外,可以利用THECOLORS,随机生成里面的颜色,制作一幅彩色的现代艺术:

    代码2,这里随机生成颜色遇到了困难,但搜索一下马上解决了 生成结果,还不错哦!

    (4)单个像素

    有时候我们不需要生成整个图像,只需要一个个的点或像素,我们就要像其他方法去解决,例如下面要画一个正弦曲线,其中一种解决方式是画很小的圆或矩形:

    用长宽都是1像素的矩形画正弦曲线 得出的结果

    注意到这里线宽必须为1,因为为0的话,就什么都没有了。

    连接多个点

    我们可以发现,上面的结果是零散的、并不是完整的一条曲线,这是因为我们只是模拟正弦函数的位置,用一个一个像素点去画的。要填充间隔,其中一个方法是:

    pygame.draw.lines()

    它需要五个参数:

    (1)划线的表面(surface)

    (2)颜色(color)

    (3)是否需要画另一条线使最后一个点与第一个点连接,使形状闭合(closed)

    (4)要连接的点的列表(list)

    (5)线宽(width)

    所以,我们上面可以加上:

    pygame.draw.lines(screen, [0,0,0], false, plotPoints, 1)

    完整代码,注意图中有个错,你能发现吗? 这条正弦曲线画得很好了,假如线宽为2,会不会更好看呢?

    连接更多的点

    我们还可以通过描点来画图,下面就是一个游戏例子,让我们看看将这些点连起来之后,会变成什么形状吧!

    运行代码

    把下面的坐标打到dots列表中,注意缩进;另外假如你赶时间,可以直接粘贴进去,但最好还是打一下,巩固一下列表输入的方法:

    [221,432], [225,331], [133,342], [141,310], [51,230], [74,217], [58,153], [114,164], [123,135], [176,190], [159,77], [193,93], [230,28], [267,93], [301,77], [284,190], [327,135], [336,164], [402,153], [386,217], [409,230], [319,310], [327,342], [233,331], [237,432]

    途中测试一下(暂时将True改为False) 最后结果

    逐点绘制

    这里介绍一下只需绘制一个点的方法:

    screen.set_at([x,y], [0,0,0])

    (5)图像

    以上的绘图方法只是制作图形的一种方式,还有其他获取图形的方法,其中最简便的就是利用pygame自带的image函数,将图片作为一个引入进来:

    (1)在同一个文件夹内放进一张图片(例:ball.jpeg)

    (2)在screen.fill后面加上这三行代码:

    my_ball = pygame.image.load("ball.jpeg")

    screen.blit(my_ball, [50,50]) 

    pygame.display.flip()

    (6/7)动起来——制作动画

    既然是球,那么假如它不能动,必将失去很多乐趣。现在,我们就让它动起来吧!

    在计算机中,制作一个动画,需要两个步骤:

    (1)在新位置上画出图像

    (2)把原来的图形擦掉

    那么怎么擦掉原来的图形呢?我们在上面加上以下代码:

    pygame.time.delay(2000)

    screen.blit(my_ball, [150, 50])

    pygame.draw.rect(screen, [255,255,255], [45,45,100,100], 0)

    pygame.display.flip()

    注意,这里我们只是简单地用了白色的背景覆盖住了原来的图片。假如背景不是白色,或是稍微复杂点的其他图案,则需要用其他方法解决。

    (8)更流畅的动画

    我们在原动画代码上进行加工,使之更为流畅:

    代码,结果略

    (9)让球反弹

    分解一下“反弹”动作,就是:检测图片右边缘是否在窗口右边界上,若是,则反方向前进。

    进一步分析,我们希望:

    (1)检测是否碰到边缘:使用screen.get_width()方法(检测图片右上角的距离)实现。检测边缘比较复杂,我们分为“左边碰到”和“右边碰到”两种情况:

    (1)左边碰到:非常简单,直接用横坐标x<0来检测;

    (2)右边碰到:判断依据是图片的右边界是否移动到了窗口边缘。不过,图片的位置x是按左边缘算的,所以我们用get_width()方法得出的距离,必须先减去图片的宽度(100),才能跟x进行比较。

    (2)图片在边缘来回反弹,可以用while循环实现,直到点击退出才退出反弹;

    (3)图片有加速和减速效果,可以设置变量speed,控制球的位置是+5还是+10。

    新代码如下:

    代码,效果略。

    接下来,我们也希望它不要只在一条直线上反弹,而是在垂直的方向上也有变化。这时候,我们可以增加多一个变量y_speed,用以设置垂直方向的速度:

    实现代码,效果略

    (10)让球在窗口滑动

    这个效果是这样的:当球碰到了窗口边缘,不是反弹,而是在另一边重新出现,呈现一种“滑动”的效果。

    具体过程略,思路:先实现只有x轴的情况,然后再实现x与y轴同时反弹。


    你学到了什么?

    (1)如何使用Pygame

    (2)如何创建图形窗口,并画一些形状

    (3)如何设置颜色、线宽等属性

    (4)如何复制图像到窗口

    (5)如何完成图像动画,并让其“反弹”、“翻转”


    动手试一试

    (1)使用help文档,获取pygame画其他形状的方式:

    其实非常简单,只需要在交互模式下输入这两行代码:

    >>> import pygame

    >>> help()

    就迎刃而解啦:

    (2)试着修改示例程序的图像:

    只需将123.jpg换成同名文件的不同图像即可。

    (3)试着改变x_speed和y_speed:体验不同的速度。

    (4)试着设置一堵隐形的“墙”,让图片在“墙”上反弹:

    将get_width() - 100 的数值改变(如变为 - 200)即可

    (5)修改“现代艺术”代码,将pygame.display.flip移到增加while循环,增加delay延迟,看看会发生什么:

    会得到一个个延迟生成的矩形框

    小结

    作为暑假末尾的课程,这节课学的很舒心,基本的框架逐渐上手,举一反三更是能够极大地帮助回忆以前的所学。学习从来不是一蹴而就的事情,继续加油~

    相关文章

      网友评论

          本文标题:神马?Python也能画画!父与子的编程之旅 学习笔记(14)2

          本文链接:https://www.haomeiwen.com/subject/mrdviftx.html