想做一个小游戏玩玩,飞行的小鸟,简单好玩,尝试看看。用python做游戏的话,就得要用到pygame这个模块了。先简单介绍一下pygame吧。
pygame.init() # 定义颜色 PIPE = (0,0,255) SKY = (135,206,250) BIRD = (220,20,60) GROUND = (245,245,220) # 设置游戏幕布大小 size = (800, 650) screen = pygame.display.set_mode(size) # 标题设置 pygame.display.set_caption("Flappy Block") #字体设置 arial18 = pygame.font.SysFont('arial',18, False, False) # 游戏未结束 done = False # 时钟 clock = pygame.time.Clock() # 游戏初始状态 gameState = 1 #未开始 pipes = []#定义管子的listpygame.init函数,初始化pygame模块,好让我们可以利用pygame的那些模块。比如pygame.font,pygame.draw等(上面列举到的模块)。
# 定义小鸟 class Bird(): def __init__(self): self.x = 250 # 小鸟x坐标 self.y = 250 # 小鸟y坐标 self.yV = 0 # 小鸟的位置初始化 # 定义小鸟的下降振幅 def flap(self): self.yV = -5 # 每次下降的位移 # 定义小鸟的上升振幅和y周的上下边界 def update(self): self.yV += 0.3 # 小鸟上升速度 self.y += self.yV # y轴位置等于原位置加yV振幅 # 定义小鸟的飞行 def draw(self): pygame.draw.rect(screen, BIRD, (self.x, self.y, 40, 40))#参数为(幕布,颜色,坐标,大小) # 重置小鸟 def reset(self): self.x = 250 self.y = 250 self.yV = 0 bird = Bird()# 实例一个小鸟类class Bird():定义了小鸟。__init(self)__方法初始化了小鸟的位置等信息。注意这个self,在python语言里,类的方法,会有一个默认的参数,一般通用的都是用self表示,这个self是代表类的自身。flap方法定义了小鸟每次下降的位移。update方法定义了小鸟的上升。draw方法通过调用pygame.draw.rect实现了小鸟的飞行。reset方法重置小鸟的位置。bird=Bird()是小鸟类的实例化。
# 定义管子 class Pipe(): def __init__(self): self.centerY = random.randrange(180, 520) # 管子的y轴中间值范围 (大数上面管子长,小数下面管子长) self.x = 800 # 管子的初始x轴位置 self.size = 150 # 上下两个管子之间的空间宽度的一半 # 更新管子 def update(self): # 几个全局变量 global pipes global bird global gameState self.x -= 4 # 管子的移动速度,因为小鸟其实没有动x轴的位移,小鸟其实是不前进的,只是上下跳动 # 管子的初始位置 if self.x == 300: pipes.append(Pipe()) # 显示一个新管子 if self.x <= -100: del pipes[0] # 删除一个不再显示的管子 # 小鸟撞到管子,游戏结束,第一个条件是撞到下面的管子,第二个条件是撞到上面的管子(小鸟位置固定,管子在x轴运动) #小鸟的y轴位移小于管子的y轴范围减去中间空的部分 #或者小鸟的y轴位移+40大于管子的y轴范围加上中间空的部分,40是小鸟的长度 #则小鸟撞到管子,游戏结束 if self.x >= 170 and self.x <= 290 and bird.y <= (self.centerY - self.size) \ or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size): gameState = 3 # 结束 # 小鸟飞过管子,游戏继续,两个75等于size的150 if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75): gameState = 2 # 小鸟撞到地面,游戏结束 if bird.y >= 610: gameState = 3 # 定义管子的显示 def draw(self): # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长) pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size))) # 定义下面管子的显示 pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY))) # 实例化管子,显示新管子 pipes.append(Pipe())管子的这个类,我们说说和小鸟不一样的地方。update方法实现了管子的更新显示。注意global,global使参数全局化。管子的移动是self.x=4,说明管子是从右向左运动,速率是4。(所以这个游戏里,其实是管子在左右动,而小鸟其实只是上下动,没有进行x轴的运动)。
if self.x >= 170 and self.x <= 290 \ #管子的位置在120-290之间 and bird.y <= (self.centerY - self.size) \#并且小鸟的身体碰到了上面的管子 or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size):#小鸟的身体碰到了下面的管子 gameState = 3 # 结束小鸟飞过管子
# 小鸟飞过管子,游戏继续,两个75等于self.size的150 if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75): gameState = 2
# 定义管子的显示 def draw(self): # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长) pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size))) # 定义下面管子的显示 pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY))) # 实例化管子,显示新管子 pipes.append(Pipe())现在看一下游戏的具体实现。
#定义游戏开始键 #参数为显示的地方,颜色,面板的位置和大小 pygame.draw.rect(screen,GROUND,(300,300,200,100))#开始键的面板, #参数为显示的文字,是否显示,颜色 text = arial18.render("Press space to play",True,SKY)#文字 #文字的位置设置 textX = text.get_rect().width textY = text.get_rect().height screen.blit(text,((400 - (textX / 2)),(350 - (textY / 2))))#字的填充位置同样还要设置游戏结束的按钮,只是文案稍微加上gameover。
# -------- Main Program Loop ----------- #当游戏没结束 while not done: # --- Main event loop # pygame的event方法 for event in pygame.event.get(): if event.type == pygame.QUIT: # 退出游戏 done = True # 游戏键位设置 if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: # 设置为空格键 if gameState == 1: # 游戏未开始状态为1 gameState = 2 # 游戏中状态为2 elif gameState == 3: # 游戏结束状态为3 bird.reset() # 小鸟重置 # 管子list重置 pipes = [] pipes.append(Pipe()) # 游戏中 gameState = 2 else: # 没有管子的时候,小鸟飞行 bird.flap() screen.fill(SKY) # 屏幕填色 if gameState == 1: #游戏未开始时 #定义游戏开始键 pygame.draw.rect(screen,GROUND,(300,300,200,100))#开始键的面板,参数为xy轴位置,xy方向的大小 text = arial18.render("Press space to play",True,SKY)#文字 #文字的位置设置 textX = text.get_rect().width textY = text.get_rect().height screen.blit(text,((400 - (textX / 2)),(350 - (textY / 2))))#字的填充位置 # 当游戏运行中 if gameState == 2: # 小鸟的飞行更新 bird.update() bird.draw() # 管子的更新显示 for pipe in pipes: pipe.update() pipe.draw() # 当游戏结束 if gameState == 3: for pipe in pipes: pipe.draw() bird.draw() pygame.draw.rect(screen,GROUND,(300,300,250,100))#开始键的面板 text = arial18.render("Game Over,Press space to play",True,SKY)#文字 #文字的位置设置 textX = text.get_rect().width textY = text.get_rect().height screen.blit(text,((420 - (textX / 2)),(350 - (textY / 2))))#字的填充位置 # 刷新页面 pygame.display.flip() # 画面更新时间,单位:秒 clock.tick(50) pygame.quit()
游戏的实现效果是这样的:用方块来代替小鸟。