老规律,我们用pygame库来进行开发
初始化代码分为:
1.创建主游戏窗口
2.创建游戏的时钟
3.创建精灵和精灵族
4.设置定时器事件,来创建敌人和子弹的事件
具体代码如下:
先定义一个游戏类,类中初始化执行以上四个方法代码。初始化完执行游戏开始方法。
以下为初始化方法
# 保护我方程序员
def __init__(self):
print("游戏初始化")
# 1.创建游戏窗口
self.screen = pygame.display.set_mode(SCREEN_RECT.size)
# 2.创建游戏的时钟
self.clock = pygame.time.Clock()
# 3.调用私有方法,精灵和精灵族的创建
self.__CreateSprites()
# 4.设置定时器事件-创建敌军,子弹事件
pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
pygame.time.set_timer(HERO_FIRE_EVENT, 1000)
def __CreateSprites(self): # 自定义的函数用--表示
# 创建背景精灵和精灵组
# bg1 = BackGround("static/image/background0.png") # 第一个背景
# bg2 = BackGround("static/image/background0.png") # 第二个背景
# bg2.rect.y = -bg2.rect.height
bg1 = BackGround() # 第一个背景
bg2 = BackGround(True) # 第二个背景
self.backGroup = pygame.sprite.Group(bg1, bg2) # 实现背景图片交替滚动效果
# 创建敌人精灵组
self.enemyGroup = pygame.sprite.Group()
# 创建英雄程序员精灵和精灵组
self.hero = Hero()
self.heroGroup = pygame.sprite.Group(self.hero)
开始游戏方法
def __StartGame__(self):
global globalCnt
globalCnt = 0
while True:
# 1.刷新新帧率
self.clock.tick(FRAME_PER_SEC)
# 2.事件监听
self.__EventHandler__()
# 3.碰撞检测
self.__CheckCollide()
# 4.更新绘制精灵组
self.__UpdateSpi__()
# 5.更新显示
pygame.display.update()
这里包含了,刷新游戏帧率,一般每秒60次就可以了
然后就是事件的监听,碰撞检测,更新绘制精灵组,更新显示
事件监听
事件监听主要是按钮操作,所需要的一些动作执行;
我们规定,方向键左右执行,英雄主角就执行往x轴左右移动一个距离
def __EventHandler__(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
PlaneGame.__GameOver__()
elif event.type == CREATE_ENEMY_EVENT:
# 1.创建敌人精灵
enemy = Enemy()
self.enemyGroup.add(enemy)
elif event.type == HERO_FIRE_EVENT:
self.hero.fire()
keyPressed = pygame.key.get_pressed()
if keyPressed[pygame.K_RIGHT]:
self.hero.speed = 1
elif keyPressed[pygame.K_LEFT]:
self.hero.speed = -1
碰撞检测
碰撞检测一般分两种,一种是组碰撞,一种是精灵碰撞,
def __CheckCollide(self):
# 1.检测碰撞, 子弹和敌人碰撞,都销毁
global globalCnt
killEnemyList = pygame.sprite.groupcollide(self.hero.bulletGroup, self.enemyGroup, True, True)
if (len(killEnemyList)) > 0:
print("击中了:" + str(globalCnt))
tempSound("static/sound/enemy1_down.mp3")
globalCnt += 1
# 2.敌人撞毁英雄
enemiesList = pygame.sprite.spritecollide(self.hero, self.enemyGroup, True)
# 判断列表是否有内容
if len(enemiesList) > 0:
# 如果检测到碰撞,让英雄撞毁
pygame.mixer.music.stop()
self.hero.kill()
# 给出结束游戏提示
self.screen.fill(RED)
gameOverText = font_big.render("Game Over", True, (0, 0, 0))
# gameOverText = font_big.render("游戏结束", True, (0, 0, 0))
self.screen.blit(gameOverText, (150, 250))
refuseTimes = font_small.render("You refuse unreasonable requests %d times" % globalCnt, True, (0, 0, 0))
# refuseTimes = font_small.render("恭喜你打败敌人 %d 次" % globalCnt, True, (0, 0, 0))
self.screen.blit(refuseTimes, (100, 400))
pygame.display.update()
tempSound("static/sound/game_over.wav")
time.sleep(2)
pygame.quit()
exit()
我这边做的事,当子弹和敌人发生碰撞,则敌人销毁,如果是敌人和英雄碰撞,则整个游戏就结束了,结束的时候,我会加上背景音乐以及提示,以及记录整个游戏过程中击败了击此敌人。
更新精灵以及精灵组
def __UpdateSpi__(self):
self.backGroup.update()
self.backGroup.draw(self.screen)
self.enemyGroup.update()
self.enemyGroup.draw(self.screen)
self.heroGroup.update()
self.heroGroup.draw(self.screen)
self.hero.bulletGroup.update()
self.hero.bulletGroup.draw(self.screen)
我们创建的精灵组每一步都要在窗口进行更新,套路都是update\draw
最后就是游戏结束,游戏结束要将所有依赖库移除以及程序退出,
@staticmethod
def __GameOver__():
print("游戏结束")
pygame.quit()
exit()
在这游戏结束没有用到其他的方法,则会提示它是静态的,需要加上staticmethod的注入
来看下他是怎么执行的,当然是从main方法开始执行
def tempSound(sound_path):
downSound = pygame.mixer.Sound(sound_path)
downSound.play(0)
downSound.set_volume(1.0)
# downSound.stop()
if __name__ == '__main__':
global globalCnt
# 播放背景音乐
pygame.mixer.init()
pygame.mixer.music.load("static/sound/game_music.mp3")
pygame.mixer.music.play(-1)
pygame.mixer.music.set_volume(0.1)
game = PlaneGame()
game.__StartGame__()
我这加了全局背景音乐以及局部背景音乐,
全局背景音乐用pygame.mixer.music方法,局部背景音乐用pygame.mixer方法
这两种在不同场合使用,都可以设置播放频率,声音大小等,具体可以参考其说明文档
接下来看下比较重要的就是精灵和精灵组代码
我们的背景大小以及初始位置,都设置成固定参数,默认大写为常量,小写为变量
# 创建图像初始位置 x, y, width, height
SCREEN_RECT = pygame.Rect(0, 0, 530, 700)
# 刷新的帧率
FRAME_PER_SEC = 60
# 创建低级的定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
# 英雄发射子弹得事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1
pygame.init()
# 设置窗体的名称
pygame.display.set_caption("保护我方程序猿 原创:爱编程的小仙女")
# 设置窗体的logo,如果不设置默认是一只小龙
gameIcon = pygame.image.load("static/image/logo.ico")
pygame.display.set_icon(gameIcon)
# 设置最小字体以及字体格式
font_small = pygame.font.SysFont("simkai.ttf", 20)
# 设置最大字体以及字体格式,注意xxx.ttf是windows/font目录下有的,如果没有可能会报错
font_big = pygame.font.SysFont("simkai.ttf", 60)
# 设置背景颜色为红色
RED = "#FF0000"
定义一个游戏精灵函数
这个函数初始化为加载图片,更新为某精灵在垂直方向上移动
class GameSprite(pygame.sprite.Sprite):
def __init__(self, image_name, speed=1):
# 调用父类的初始化方法
super(GameSprite, self).__init__()
# 定义对象的属性
self.image = pygame.image.load(image_name)
self.rect = self.image.get_rect()
self.speed = speed
def update(self):
# 在屏幕的垂直方向上移动
self.rect.y += self.speed
背景图片精灵
class BackGround(GameSprite):
def __init__(self, is_alt=False):
# 1.调用父类方法实现精灵的创建
bgRand = random.randint(0, 1)
super(BackGround, self).__init__("static/image/background" + str(bgRand) + ".png")
# 2.判断是否时交替对象,如果是,设置初始位置
if is_alt:
self.rect.y = -self.rect.height
# 游戏背景精灵
def update(self):
# 1.调用父类的方法实现
super(BackGround, self).update()
# 2.判断是否意出屏幕,如果意出屏幕,将图片设置到屏幕的上方
if self.rect.y >= SCREEN_RECT.height:
self.rect.y = -self.rect.height
背景图片我是用两张图片交替进行的,不是一张图片交替,随机交替可以受用random进行对图片的选取,只要名字对的上就可以。
如果游戏背景图片y轴超过了整个背景y轴,那么就将背景图片y轴放置在负方向。
敌人精灵
class Enemy(GameSprite):
# 敌人精灵
def __init__(self):
# 1.调用父类方法,创建低级精灵,同时指定低级图片
index = random.randint(0, 5) # 随机显示地方战机
super(Enemy, self).__init__("static/image/enemy" + str(index) + ".png")
# super(Enemy, self).__init__("static/image/enemy0.png")
# 2.指定敌人的初始随机速度 2-6
self.speed = random.randint(2, 6)
# 指定敌人的初始随机位置
self.rect.bottom = 0 # y轴出现的位置
maxX = SCREEN_RECT.width - self.rect.width
self.rect.x = random.randint(0, maxX) # 敌人在X轴随机出现的位置
def update(self):
# 1.调用父类方法,保持垂直方向的飞行
super(Enemy, self).update()
# 2.判断是否飞出屏幕,如果是,需要从精灵组删除敌人
if self.rect.y >= SCREEN_RECT.height:
self.kill()
def __del__(self):
pass
敌人精灵,我们要设置他的背景图片,以及随机出现的位置,随机的运行速度,以及飞出背景图片y轴进行精灵的销毁
英雄的精灵
class Hero(GameSprite):
# 英雄精灵
def __init__(self):
# 1.调用父类方法设置image和speed
super(Hero, self).__init__("static/image/programmer.png", 0)
# 设置英雄初始位置
self.rect.centerx = SCREEN_RECT.centerx
self.rect.bottom = SCREEN_RECT.bottom - 120
# 创建子弹得精灵组
self.bulletGroup = pygame.sprite.Group()
def update(self):
# 英雄在水平方向移动
self.rect.x += self.speed
# 控制英雄不能离开屏幕
if self.rect.x < 0:
self.rect.x = 0
elif self.rect.right > SCREEN_RECT.right:
self.rect.right = SCREEN_RECT.right
def fire(self):
# 1.创建子弹精灵
for i in (0, 1): # 一次性发射两枚子弹
bullet = Bullet()
# 2.创建精灵得位置
bullet.rect.bottom = self.rect.y - i * 75
bullet.rect.centerx = self.rect.centerx
# 3.将精灵添加到精灵组
self.bulletGroup.add(bullet)
英雄也要设置初始位置、英雄不能移除整个窗体,还要能发射子弹,每次发射几枚子弹
子弹精灵
class Bullet(GameSprite):
# 子弹精灵
def __init__(self):
# 调用父类方法,设置子弹图片,设置初始速度
bulletRand = random.randint(1, 4)
super(Bullet, self).__init__("static/image/language" + str(bulletRand) + ".png", -2)
def update(self):
# 调用父类方法,让子弹沿垂直方向飞行
super(Bullet, self).update()
# 判断子弹飞出屏幕
if self.rect.bottom < 0:
self.kill()
def __del__(self):
pass
子弹精灵就是设置随机速度,以及运行的方向,在子弹飞出窗体后,进行自动销毁。
自动销毁用的是自带的self.kill()方法
好了整个运行代码我们都写完了,运行下就能得到你想要的效果。
在这展示的是比较初级的游戏,如果你想做更加强大的游戏,好好看看其他的课程以及开发文档,对你很有帮助哦,动手操作一遍吗。
由于无法发送视频,上一篇中已经有外部连接,对着看以下,你可以在这基础上进行优化。