我们将编写一个程序来实现积木在窗口中弹跳的效果。这些积木具有不同的颜色和大小,并且只在对角线上移动。为了让积木有动画的效果,我们将在游戏循环的每一次迭代中,让这些积木移动一些像素。这就会使得积木看上去像是在屏幕上移动。
目录
(一)游戏说明
(二)代码分析
1)设置常量变量
2)用于方向、速度、颜色的常量变量
3)设置积木 数据结构
4)游戏循环
1.处理玩家退出的情况
2.移动、弹跳积木
3.绘制窗口
这个程序称不上是一个游戏,只是通过一些细微的改变实现一个积木的移动。程序中的积木就是用pygame.draw.rect()函数绘制的矩形。在这个程序中,我们有三个不同颜色的积木来回移动,并且从窗口的墙壁弹回。每个积木将在4条对角线方向中的一条上移动。当积木碰到了窗口,它就会从边缘上弹回来,并在一条新的对角线上移动。
所谓积木的移动,就是快速的绘制一个新的矩形,只不过是速度很快,我们看起来就像是在移动一样。
import pygame, sys, time
from pygame.locals import *
# Set up pygame.
pygame.init()
# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')
首先是导入模块,然后对pygame模块进行初始化。
这里我们将使用常量变量,以便我们想要修改窗口大小的时候,只需要修改WINDOWWIDTH和WINDOWHEIGHT即可。当然,如果窗口的宽度和高度从不改变,那么使用常量也可。
# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'
MOVESPEED = 4
# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
对于方向,我们也可以不使用常量,而是将这些方向常量赋值给变量,使用这些变量表示。两者的区别是:
对于速度,我们定义了MOVESPEED = 4常量变量,这告诉程序,在游戏循环的每一次迭代中,每个积木应该移动多少个像素。
对于颜色,pygame使用3个整数值的一个元组,来表示红色、绿色和蓝色数量的RGB值。整数值从0到255.
使用常量是为了有更好的可读性。
# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]
这里使用字典来表示三个积木,并且将这三个积木放到boxes列表中,这样输入boxes[0]就可以访问b1中的字典数据结构,输入boxes[0]['color']就可以访问b1中的‘color’键的值。
游戏循环负责实现移动积木的动画。
动画是这样实现的:绘制一系列略微不同的图像,这些图像一个接着一个地显示。在我们的动画中,图像都是移动的积木,略微不同的是每一个积木的位置。在每一个图像中,积木都会移动4个像素。图像显示得如此之快,以至于积木看上去就像是在屏幕上平滑地移动。如果一个积木碰到了窗口的边缘,游戏循环将会通过改变该积木的方向而令其弹回。
当玩家通过关闭窗口而退出的时候,我们需要停止游戏。我们需要在游戏循环中做到这一点,以便程序持续地检查受否有一个QUIT事件。
# Run the game loop.
while True:
# Check for the QUIT event.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
为了使窗口出现运动轨迹,需要在每一次图形改变之后清楚整个窗口:
# Draw the white background onto the surface.
windowSurface.fill(WHITE)
for b in boxes:
# Move the box data structure.
if b['dir'] == DOWNLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == DOWNRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == UPLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top -= MOVESPEED
if b['dir'] == UPRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top -= MOVESPEED
# Check whether the box has moved out of the window.
if b['rect'].top < 0:
# The box has moved past the top.
if b['dir'] == UPLEFT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = DOWNRIGHT
if b['rect'].bottom > WINDOWHEIGHT:
# The box has moved past the bottom.
if b['dir'] == DOWNLEFT:
b['dir'] = UPLEFT
if b['dir'] == DOWNRIGHT:
b['dir'] = UPRIGHT
if b['rect'].left < 0:
# The box has moved past the left side.
if b['dir'] == DOWNLEFT:
b['dir'] = DOWNRIGHT
if b['dir'] == UPLEFT:
b['dir'] = UPRIGHT
if b['rect'].right > WINDOWWIDTH:
# The box has moved past the right side.
if b['dir'] == DOWNRIGHT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = UPLEFT
# Draw the box onto the surface.
pygame.draw.rect(windowSurface, b['color'], b['rect'])
# Draw the window onto the screen.
pygame.display.update()
time.sleep(0.02)
源代码:
import pygame, sys, time
from pygame.locals import *
# Set up pygame.
pygame.init()
# Set up the window.
WINDOWWIDTH = 400
WINDOWHEIGHT = 400
windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32)
pygame.display.set_caption('Animation')
# Set up direction variables.
DOWNLEFT = 'downleft'
DOWNRIGHT = 'downright'
UPLEFT = 'upleft'
UPRIGHT = 'upright'
MOVESPEED = 4
# Set up the colors.
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# Set up the box data structure.
b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT}
b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT}
b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT}
boxes = [b1, b2, b3]
# Run the game loop.
while True:
# Check for the QUIT event.
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# Draw the white background onto the surface.
windowSurface.fill(WHITE)
for b in boxes:
# Move the box data structure.
if b['dir'] == DOWNLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == DOWNRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == UPLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top -= MOVESPEED
if b['dir'] == UPRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top -= MOVESPEED
# Check whether the box has moved out of the window.
if b['rect'].top < 0:
# The box has moved past the top.
if b['dir'] == UPLEFT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = DOWNRIGHT
if b['rect'].bottom > WINDOWHEIGHT:
# The box has moved past the bottom.
if b['dir'] == DOWNLEFT:
b['dir'] = UPLEFT
if b['dir'] == DOWNRIGHT:
b['dir'] = UPRIGHT
if b['rect'].left < 0:
# The box has moved past the left side.
if b['dir'] == DOWNLEFT:
b['dir'] = DOWNRIGHT
if b['dir'] == UPLEFT:
b['dir'] = UPRIGHT
if b['rect'].right > WINDOWWIDTH:
# The box has moved past the right side.
if b['dir'] == DOWNRIGHT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = UPLEFT
# Draw the box onto the surface.
pygame.draw.rect(windowSurface, b['color'], b['rect'])
# Draw the window onto the screen.
pygame.display.update()
time.sleep(0.02)
参考: