Python学习笔记#04 - 使用pygame开发游戏alien invasion

(主要是《Python编程:从入门到实践》一书中开发《外星人入侵》游戏部分一些没讲的很清楚的地方)

rect

可以用get_rect()方法获取surface的rect对象,该方法返回一个覆盖整个suiface的矩形,所以当surface不是矩形时,我们获得的是其外接矩形。

我们可以通过rect对象查看和修改矩形参数,但是rect对象到底有哪些参数参数,都是什么意思呢,书上没有说,pygame的官方文档上也只是列出了所有参数,并没有说明每个参数的含义,只是让你注意这些参数有的是整型数,有的是一对整型数(元组)。最后通过创建一个rect对象,再查看其属性逐个推断清楚了。

创建rect对象

myrect = pygame.Rect(left, top, width, height)
myrect = pygame.Rect((left, top), (width, height))
myrect = pygame.Rect(object)

rect的参数

x,y
top, left, bottom, right
topleft, bottomleft, topright, bottomright
midtop, midleft, midbottom, midright
center, centerx, centery
size, width, height
w,h

rect的参数属性

rect对象的所有坐标均为整形数

参数 含义 类型
x 左上角横坐标 整型
y 左上角纵坐标 整型
top 顶边纵坐标 整型
left 左边横坐标 整型
bottom 底边纵坐标 整型
right 右边横坐标 整型
topleft 左上角坐标 元组
bottomleft 左下角坐标 元组
topright 右上角坐标 元组
bottomright 右下角坐标 元组
midtop 顶边中点坐标 元组
midleft 左边中点坐标 元组
midbottom 底边中点坐标 元组
midright 右边中点坐标 元组
center 中心坐标 元组
centerx 中心横坐标 整型
centery 中心纵坐标 整型
size 尺寸(宽, 高) 元组
width/w 整型
height/h 整型

flip、blit、fill、draw傻傻分不清楚

pygame.display.flip() -> None

将整个显示surface更新至屏幕

pygame.Surface.blit(source, dest, area=None, special_flags=0) -> Rect

将一个图像(surface对象)绘制在另一个图像上面。
source:指定要绘制的surface对象。
dest:即destination,确定source指定的surface对象绘制的位置,dest可以是一对坐标,指明source的左上角,也可以是一个rect对象,rect对象的左上角坐标会用作blit的位置参数,rect对象的大小不影响blit。
可选参数area:rect对象,指定source指定的surface对象要绘制的部分。
返回值是一个rect对象,表示绘制的区域。

pygame.Surface.fill(color, rect=None, special_flags=0) -> Rect

给surface对象填充纯色。
color:颜色实参可以是RGB序列(元组或列表皆可),或RGBA序列,或mapped color index(没弄懂是什么,找不到例子)。
可选参数rect:如果不提供rect实参,整个surface都会被填色。
返回值是一个rect对象,表示绘制的区域。

pygame.draw.rect(surface, color, rect) -> Rect

绘制一个矩形。
surface:指定要绘制矩形的surface对象。
color:可以是颜色对象,或整数,或元组(int, int, int, [int])。
rect:rect对象,指定要绘制矩形的位置和尺寸。
返回值是一个rect对象,表示绘制的区域。

pygame.sprite.Group.draw(Surface) -> None

绘制sprite对象。
将Group中包含的sprite对象绘制到surface对象实参上,Group中的sprite对象排列并无顺序,故绘制sprite的顺序随机。

响应按键的微妙差别

if event.type == pygame.KEYDOWN:
	if event.key == pygame.K_RIGHT:
		ship.moving_right = True
	elif event.key == pygame.K_LEFT:
		ship.moving_left = True
elif event.type == pygame.KEYUP:
	if event.key == pygame.K_RIGHT:
		ship.moving_right = False
	elif event.key == pygame.K_LEFT:
		ship.moving_left = False

使用if…elif,当按下→键后再按下←键,pygame对按键的响应还停留在属于→键的if(或elif)中,只要这时不松开→键,pygame就无法响应其它键;
连续使用if:各个按键之间是独立的,按下→键飞船向右移动,若这时不松开→键,按下←键,pygame默认响应最新的事件,飞船会向左移动。

在for 循环中,不应从列表或编组中删除条目

书中12.8.5提及

在for 循环中,不应从列表或编组中删除条目,因此必须遍历编组的副本。我们使用了方法copy() 来设置for 循环

因为Python中for循环是按照下标遍历的,假设下标为n对应元素被剔除,原来处于n+1位置的元素往前补位,来到了对应下标n的位置,但由于下标n已经遍历过了,下一轮循环遍历下标n+1的位置,处于下标n位置的元素则被遗漏,因此必须遍历编组的副本。
这里引用 Vampirelzl文章中的例子

letters = ["a", "b", "c", "d"]
flag = 1
for letter in letters:
    print(letter)
    if flag == 1:
        letters.remove(letter)
        flag = 0

运行结果

a
c
d

开始时列表[a,b,c,d]对应下标[0,1,2,3],删除了a之后,[b,c,d]下标为[0,1,2],但是由于第二轮循环下标是1,这时就访问了c,遗漏了b。

猜你喜欢

转载自blog.csdn.net/weixin_43091089/article/details/99291362