(主要是《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。