第十六章 图形界面
进入死循环的时候 用 ctrl + C 或 ctrl + Break(机械键盘最右上角的那个键)可以终止运行。(亲测在win7 Py3.6版 IDLE中无用,直接关闭窗口即可)
16.3
while True 这部分代码在 3.6 中似乎可以不用。
16.4
颜色用三原色组合而成 [Red, Green, Blue] :[255, 255, 255] 纯白色
pygame.display.flip() 绘制好图形后,整体显示到屏幕上。
屏幕坐标:左上角为(0,0),水平向右为x增大,垂直向下y增大。
16.6
不使用while 循环,运行的也一样好。(后续章节可以看到,while 部分是循环控制的一个入口,对于单次运行,的确不需要)
16.7
colorName = random.choice(THECOLORS.keys()) 书中提示不用操心这行代码是如何工作的,但在3.6里,这行代码恰恰不能用。
这行代码的思路应该是从颜色值的“名单”里随机取出一个名字来,用来为新方框着色。先放过这行代码。
color = THECOLORS["red"] 这样的用法是可以的
代码改造一下,for循环之前,增加一个自定义的颜色列表
(pygame文件目录中colordict.py中记录了所有的颜色名和对应的颜色值)
colorList = ["red","blue","green","black"]
#color_name 这一行替换成自己的颜色列表
color_name = colorList[random.randint(0,3) ]
好了,可变色的方框实现了。 randint函数中(0,3 )会产生0、1、2、3共四种结果,这里的颜色列表共4个元素,randint参数不能取4,这是列表的索引从0开始计数的特点。
修改后的代码:
效果图:
16.8
大量矩形来画曲线 ——这个主意真的很糟糕
记得先 import math (这个坑我先踩了)
sin 函数中只接受 弧度单位,所以需要把 角度值 换算成 弧度 。
通常用 【角度值 * math.Pi/180 】 来转换
y = int(math.sin(x/640 *4*math.pi)*200 +200)
这行代码的含义是将屏幕宽度640像素平分成2个完整周期(2Pi是一个完整周期)。sin()*200 将得到值扩大200倍。 +240 相当于将水平的中心线向下移动240(y坐标向下为增大),或者说以 y = 240 做为水平中心线。
尝试改变一下显示周期,比如换成6,显示3个完整周期,如下图所示:
16.9
思路:先将 位置点 数据保存到 列表plotPoints中去,循环结束后一次性显示出来。
plotPoints.append([x,y]) 列表中是以数组形式保存坐标点数据,所以用中括号将x,y包裹起来,做一个整体数据单元保存到列表中去。
True 或 False 的首字母要大写。
线宽为2时的效果:
16.10
神秘图片——数字的输入是个耗时的大问题,当做练打字话,可以一试。
16.11
加载图片
Python的图片加载真是很方便的,两步即可完成。
1)指定好名称,加载进来。
2)再在指定的位置进行显示,
需要说明的是png图片背景透明的处理方法。在photoShop中,新建图层,并将原有图层删除。在新建图层中画一个圆形选择区,用渐变填充填一下,保存为png 格式。这样的图片无背景层,加载到屏幕中时,是上图的效果。
16.12
pygame.time.delay(2000) # delay 函数 的单位是 毫秒,2000毫秒等于2秒。
screen.blit(myBall,[150,50]) # bilt 函数 只负责新增,不负责删除旧图。
屏幕就像一张油画布,只能添加,不能擦除,颜料只会越添添多。所谓的擦除,实际上只是用背景图“覆盖”了指定区域的图形。--- 这是计算机绘图的真相。
16.14 移动的小球
通过循环语句多次执行复制、擦除操作,可以实现动画效果。
减少每次移动的步长,缩短时间间隔,增加循环次数——理论上说可以实现更平滑的动画效果,实际上受机器运算能力的限制,效果并不一定变得更好。
for step in range(1,500):
pygame.time.delay(5)
pygame.draw.rect(screen,[255,255,200],[x,y,90,90],0)
x = x + 1
screen.blit(myBall,[x,y])
pygame.display.flip()
16.15 增加速度变量
通过速度变量间接的控制运动的方向,越来越有编程的感觉了。
screen.get_width() – 90 表示距离窗口右边界90像素时,速度进行反转,我画的小球的宽度是50,所以这里的值改成50效果更副真一些。
增加y方向上的速度参数,实现满屏幕的移动。
import sys,random,pygame
pygame.init()
screen = pygame.display.set_mode([640,480])
screen.fill([255,255,200])
myBall = pygame.image.load("redBall.png")
x = 50
y = 50
xSpeed = 5
ySpeed = 5
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.time.delay(20)
pygame.draw.rect(screen,[255,255,200],[x,y,90,90],0)
x = x + xSpeed
y += ySpeed
if x> screen.get_width() -50 or x < 0 :
xSpeed = - xSpeed
if y> screen.get_height() -50 or y < 0 :
ySpeed = - ySpeed
screen.blit(myBall,[x,y])
pygame.display.flip()
关于变量名的写法:
变量名之间用下划线的写法,如x_speed 应该算法比较老式的写法了,现在流行的是用大写单词首字母的方式进行表示(C#、JaveScript中的写法),如 xSpeed,这样的打字速度似乎也能快上一点点。pygame 中的函数,比如 get_width都是下滑线连接,这是旧式习惯的延续,你的函数中怎么写,你说了算。
反弹带穿越屏幕的效果代码:
import sys,random,pygame
pygame.init()
screen = pygame.display.set_mode([640,480])
screen.fill([255,255,200])
myBall = pygame.image.load("redBall.png")
x = 50
y = 50
xSpeed = 5
ySpeed = 5
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.time.delay(20)
pygame.draw.rect(screen,[255,255,200],[x,y,90,90],0)
x += xSpeed
y += ySpeed
if x> screen.get_width() :
x = -50
if y> screen.get_height() -50 or y < 0:
ySpeed = -ySpeed
screen.blit(myBall,[x,y])
pygame.display.flip()
y += ySpeed 相当于 y = y + ySpeed,一种简化的写法。
练习7
屏幕左上角为[0,0] 位置。
[50,200] 表示的是:先水平向右(x正方向)找到第50像素的位置,再垂直向下(y正方向)找到第200像素的位置。
第十七章 动画精灵和碰撞检测
spirte 让我开始想念Flash动画编程的日子。
left,right = [100,50] # Python特有的一种赋值方法
size = width, height # 也是很特殊的用法,真得不怕搞混么?
size是一个tuple类型的对象。
17.1 建立多个小球
这章开始加入了 类定义 的内容。Class定义是第14章的内容,需要复飞的回过头去看看。
类 可以理解为是 数据 和 代码 的集合体,可以通过 . 操作符,对 类 中的属性和函数进行操作。
类 是一种数据的抽象,对它添加一项函数,则相关的实例中都将具备同一函数,从而实现编码上的简化和统一。
运动起来的小球如上图所示,所有的小球均符合相同的运动规则。如果给小球绘制不同的颜色,看起来或者更好看。无论它们的外观是什么样的,本质上它们仍是同一类的对象,这和我们的对自然界中事物的分类采用了相似的方法。
真实的碰撞检测与处理是一个复杂的问题,比如说碰撞的方向与速度对碰撞的结果会有非常大的影响。练习中的简单碰撞,每次发生碰撞全部速度都反向,看起来是比较的怪异。
对于圆形的目标,碰撞检测可以通过圆心间的距离判断来实现,对于非规则边界的目标,则是一个更复杂的话题。初学编程,过于细节的内容确实不用太细究。
(先移动,再判断的方式会造成奇怪的效果,并不可行)
clock.tick(30) # 表示每秒种执行30次,或者说暂停30次
测试了一下机器效果
clock.tick(300)
print(clock.get_fps())
用了100个小球显示效果及fps如下图所示,最大fps是91:
本章中的代码长度开始增加较多,最好的学习方式是在电脑中逐行输入一下,搞清楚每行代码的意思,改变不同的数据去观察对结果有什么影响。熟悉之后,再去查看一下相关函数的说明文档,了解掌握更多的可能用到的函数方法。
第十八章 事件
代码解读
1)backGround = pygame.Surface(screen.get_size()) # Surface相当于一张透明纸,涂上色以后,可用用来敷在画面上,实现清屏的效果。估计Surface中可以填充图片,实现复杂背景。
2)self.rect.move(self.speed) #此处的move函数是属于 rect 的函数,与ball.move()是两回事,实现的功能是按照speed大小将 rect 移动相应的距离。
3)def __init__(self, imageFile, speed, location): # 使用时变量位置要对应
myBall = Ball("redball.png",[5,0],[20,20]) # 括号内的参数 与 类 定义里的相对应。
4) K_DOWN 表示向下键,K_LEFT向左,K_RIGHT 向右,键如其名,很好记。
5)pygame.MOUSEBUTTONDOWN 、pygame.MOUSEBUTTONUP 鼠标的按下、抬起通常是成对出现的一组事件。按下鼠标后,移出窗口,再释放鼠标,则系统接收不到鼠标抬起的事件,Flash动画中存在同样的问题。
6)定时期也可以起到定间隔触发的作用。
18.3
作者在 Ball 和 MyBallClass 两个名字之间来回反复,抄代码时要注意一下。
self.rect.center = newpos # newpos 是 new position 的意思,死活不愿写成newPos,这个忍了。
my_ball.rect.centery = …. # centery 是 center 点的 Y 坐标,为什么不写成centerY.
不要以为理解错了,18.4 里立刻会告诉你
paddle.rect.centerx = …. # centerx 是 center 点的 X 坐标,写成 centerX不行么?
pygame是一个比较早期代码形成的代码包,代码的风格与现在流行的风格不一致,需要加以注意。
position (位置),很多行业中的缩写为 psn ,文中pos 的缩写方式有点中式英语的感觉。
创建自定义图形的步骤(MyPaddleClass代码分步解读):
1)按照指定大小创建一个表面
imgSurface = pygame.surface.Surface([100,20])
参数含义:宽100,高20
18.1中用下面的语句创建“表面”
background = pygame.Surface(screen.get_size()) 创建 一个与屏幕同大小的表面
2)用指定颜色对表面进行填充(或者加载一张图片)
imgSurface.fill([0,0,0])
3)转换成图片供其它元素使用。
self.image = imgSurface.convert()
游戏逻辑、循环流程、判断条件 是整个游戏的核心,代码实现、类 的设计是技术条件。二者相结合就是一个趣味性的内容。
pygame创建字体的步骤
1)创建字体对象
font = pygame.font.Font(None, 50) #字体名称,大小
2)渲染文本
scoreTxt = font.render(str(points),1,(0,0,0))
# points 得分 render 函数参数:文本内容,大小,前景色,背景色
3)指定位置
textpos = [10,10]
4)绘制文本
screen.blit(scoreTxt, txtpos)
18.5
myBall.move() 放在基础条件(球与板碰撞)之后,放在结束条件(球碰墙或低于屏幕)之前。 代码的位置与程序结果之间存在相关性,必须注意。
screen.blit(myBall.image,[width - 50*i, 20]) 从屏幕宽度(右侧)向左,依次减少一个小球的宽度,画出一个小球的图形。这里仅用到了小球的image内容,不影响正常移动的小球。
屏幕中每添加一项内谷,需要分成很多步骤来进行,对于初学是比较麻烦的一件事,但这样的做法是有好处的。当需要在某一步骤中增加更多的变化时,代码受影响的程度将会降低。这就是分步处理的好处。
代码提示有错误时,
1)先检查行前的缩进是否正常,屏幕右下角有行列号的显示。
2)检查判断语句的 冒号 是否忘记输入,换行后,未正常缩进时,通常是这个问题。
3)变量名、函数名是否正确。
4)变量的作用范围、执行顺序是否正确。一定是先定义、赋值、再使用。
想起了曾经流行的消砖块游戏,整体的框架是一致的。pygame除了对中文不友好,使用还是相对简单的。
第十九章 声音
按照代码输入后在Python3.6中听不到声音,IDLE的问题?不晓得,本章没有太多的逻辑代码方面的内容。暂且放过。
第二十章 更多GUI
pythonCard 支持到2.7版,wxPython 支持到2.6,毕竟是2010年间的产品了,快乐的跳过。
后续章节21、22章更多是格式方面的内容,可以自行阅读。
23、24章 内容略复杂,时间关系,不再细看。
接下来,我打算看《教孩子学编程Python语言版》,主要内容以Python内置的turtle 和pygame 为主。目标是实现帮助孩子建立编程兴趣,了解编程方法为主。(如果点赞多的话,或许我会另起一篇读书笔记,哈哈哈)
Python入门简单,开发不易。通过本书,可以知道,在一些开发模块的基础之上,做一些简单应用,是相对方便的,只要读懂模块的功能、符合模块的调整格式,输入正确的参数,即可以实现一些原本复杂的内容。
然而(可恶的然而),这样并不会使你成为一个编程高手。真正的高手是那些能提供出模块供大家来用的人。
接下来该做什么?
如果您打算在Python编程中更上一个台阶,建议看看细节讨论更深一些的书籍,比如 a byte of Python 或是Head First Python,以及Python cookbook。找到比如 runoob 等学习网站,把 C 语言编程的100个练习题,用Pythong做了,或是其它的练习题(高中计算机编程竞赛网站上练习很多),多多练习,当您对Python理解的更深的时候,也就是更能够灵活运用它的时候。
对于在校学生,建议学习matPlotLib模块,进行数学函数的可视化。相信这方面的时间投入不会另你后悔的。
对于在职人员,建议了解一下操作word相关的模块,可以实现表格、文档的自动化填充,或许可以给您的职场生活带来一些便利。
您对学编程的初衷是什么呢?按照自己的喜好继续前进就好,了解的越多,自然就知道接下去还有哪些方向可以前进。任何时候都不用担心开始的太晚,因为,静下心来学习,本身就是一件快乐的事情,祝您学习愉快!
本系列读书笔记就此结束,来得有点晚,但愿有帮助,谢谢大家。
更多推荐
教孩子学编程python和趣学编程_与孩子一起学编程(Python读书笔记4)
发布评论