前言
这次带大家仿写个之前有段时间比较火的愤怒的小鸟小游戏呗。
废话不多说,让我们愉快地开始吧~
开发工具
**Python版本:**3.6.4
相关模块:
pygame模块;
以及一些python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
原理简介
这里简单介绍一下游戏的实现原理呗。首先是游戏的开始界面,大概是长这样的,比较简约:
主要包括两个部分,即游戏的标题和游戏的开始以及退出按钮,这两部分的代码实现如下:
'''按钮类'''
class Button(pygame.sprite.Sprite):
def __init__(self, screen, x, y, width, height, action=None, color_not_active=(189, 195, 199), color_active=(189, 195, 199)):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.action = action
self.screen = screen
self.color_active = color_active
self.color_not_active = color_not_active
'''添加文字'''
def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
self.font = pygame.font.Font(font, size)
self.text = self.font.render(text, True, color)
self.text_pos = self.text.get_rect()
self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
'''是否被鼠标选中'''
def selected(self):
pos = pygame.mouse.get_pos()
if (self.x < pos[0] < self.x + self.width) and (self.y < pos[1] < self.y + self.height):
return True
return False
'''画到屏幕上'''
def draw(self):
if self.selected():
pygame.draw.rect(self.screen, self.color_active, (self.x, self.y, self.width, self.height))
else:
pygame.draw.rect(self.screen, self.color_not_active, (self.x, self.y, self.width, self.height))
if hasattr(self, 'text'):
self.screen.blit(self.text, self.text_pos)
'''文字标签类'''
class Label(pygame.sprite.Sprite):
def __init__(self, screen, x, y, width, height):
pygame.sprite.Sprite.__init__(self)
self.x = x
self.y = y
self.width = width
self.height = height
self.screen = screen
'''添加文字'''
def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
self.font = pygame.font.Font(font, size)
self.text = self.font.render(text, True, color)
self.text_pos = self.text.get_rect()
self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
'''画到屏幕上'''
def draw(self):
if hasattr(self, 'text'):
self.screen.blit(self.text, self.text_pos)
复制代码
实现起来其实都比较简单,按钮类就是多了一个被鼠标选中之后(也就是鼠标的位置落在按钮的区域范围内时)改变颜色以直观地告诉玩家该按钮已经被选中了的功能。
如果玩家点击退出键(QUIT),则退出游戏:
def quitgame():
pygame.quit()
sys.exit()
若点击开始游戏按钮,则开始游戏:
def startgame():
game_levels = GameLevels(cfg, screen)
game_levels.start()
复制代码
游戏界面大概长这样:
玩家获胜的方法就是操作有限数量的小鸟将所有入侵的猪干掉,换句话说就是利用弹弓发射小鸟,让小鸟击中场上的所有猪。若小鸟全部发射完之后场上仍然有猪没有被击中,则玩家失败。判断游戏胜负关系的代码实现起来其实蛮简单的,大概是这样的:
'''游戏状态'''
def status(self, pigs, birds):
status_codes = {
'gaming': 0,
'failure': 1,
'victory': 2,
}
if len(pigs) == 0: return status_codes['victory']
elif len(birds) == 0: return status_codes['failure']
else: return status_codes['gaming']
复制代码
接着,为了实现游戏,我们先定义一下所有我们需要的游戏精灵类。首先,是我们的主角,愤怒的小鸟:
'''小鸟'''
class Bird(pygame.sprite.Sprite):
def __init__(self, screen, imagepaths, loc_info, velocity=None, color=(255, 255, 255), **kwargs):
pygame.sprite.Sprite.__init__(self)
assert len(loc_info) == 3
assert len(imagepaths) == 1
# 设置必要的属性常量
self.color = color
self.screen = screen
self.loc_info = list(loc_info)
self.imagepaths = imagepaths
self.velocity = VelocityVector() if velocity is None else velocity
self.type = 'bird'
self.fly_path = []
self.is_dead = False
self.elasticity = 0.8
self.is_loaded = False
self.is_selected = False
self.inverse_friction = 0.99
self.gravity = VelocityVector(0.2, math.pi)
# 屏幕大小
self.screen_size = screen.get_rect().size
self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)