美文网首页
神马?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