02 pygame实现飞机大战

在开始介绍之前,首先要确定飞机大战所需的图片以及所需的工具包和工具类,我所使用的图片是下载自别人分享的百度网盘,在代码的最后我会把图片资源和代码链接放上去,还有我们使用pygame提供的模块和random的模块,来进行设计。
代码中我们设计一个sprite.py的python工具类,以plane_main.py为python的主函数类,这样开发将会很简洁,也更加容易开发,有一点很重要的,我们使用精灵组来显示敌机、英雄、子弹和背景图片,也就是说,显示全部都调用精灵组的图片,这样我们就不用一个一个去显示,非常方便。
spirit.py 主要是定义需要的精灵,用于更新显示和碰撞检测。在sprite中导入pygame模块和random模块,在定义我们所需要的全局变量和自定义类,再在自定义类里面编写我们所需要的函数,如下图所示

这里写图片描述

1. 确定好我们所需要的类后,我们可以一步一步来定义我们所需的类,我们先定义一个GameSprites类作为游戏精灵类,用于游戏的运行

class GameSprites(pygame.sprite.Sprite):def __init__(self, image_name, speed = 1):# 调用父类的初始化方法super().__init__()# 定义对象属性self.image = pygame.image.load(image_name)self.rect = self.image.get_rect()self.speed = speeddef update(self):# 图片向下移动self.rect.y += self.speed

2. 接着我们定义Background游戏背景类,使用两张相同的图片进行循环,一张在y轴正坐标,一张在y轴负坐标。当在正坐标的图片出屏幕时,即self.rect.y >= SCREEN_RECT.height时,让它减去自己的高度,在负坐标那里继续增大,从而实现图片的更替显示。

class Background(GameSprites):"""游戏背景精灵"""def __init__(self, is_alt=False):# 调用父类方法,实现精灵和精灵组的创建(image/rect/speed)super().__init__("./images/img_bg_level_1.jpg")# 判断是否是交替图像if is_alt:self.rect.y = -self.rect.heightdef update(self):# 调用父类的方法实现super().update()# 判断是否移出屏幕if self.rect.y >= SCREEN_RECT.height:self.rect.y = -self.rect.height

3. 接着,我们写一个敌机类,用于显示敌机,使用随机函数random先指定敌机的位置,再设定不同的3种速度,这样敌机就可以在图片上随机出现,以不同速度运动了,在敌机飞出屏幕后销毁敌机精灵,防止内存消耗,如下代码所示

class Enemy(GameSprites):"""敌机精灵"""def __init__(self):# 调用父类的初始化super().__init__("./images/a2-1.png")# 指定敌机的初始随机速度self.speed = random.randint(1, 3)# 指定敌机的初始随机位置self.rect.bottom = 0max_x = SCREEN_RECT.width - self.rect.widthself.rect.x = random.randint(0, max_x)def update(self):# 调用父类方法super().update()# 判断敌机是否飞出屏幕,是则从精灵组中删除if self.rect.y >= SCREEN_RECT.height:# print("敌机飞出了屏幕")self.kill()def __del__(self):# print("敌机挂了")pass

4. 定义完敌机类,我们在定义英雄飞机类,这部分代码稍微复杂些,因为要定义开火这个函数,包括英雄和子弹两个精灵组,需要调用子弹精灵组,和敌机精灵组一样,需要定义初始位置,不同的是,英雄可以使用按键进行左右移动,并且可以发射子弹,如下代码所示

class Hero(GameSprites):def __init__(self):# 调用父类方法super().__init__("./images/me1.png", 0)# 设置英雄初始位置self.rect.centerx = SCREEN_RECT.centerxself.rect.bottom = SCREEN_RECT.bottom - 120# 创建子弹精灵组self.bullets = pygame.sprite.Group()def update(self):# 英雄在水平移动self.rect.x += self.speed# 控制英雄不能离开屏幕if self.rect.x < 0:self.rec .x = 0elif self.rect.x > SCREEN_RECT.right:self.rect.x = SCREEN_RECT.rightdef fire(self):print("发射子弹事件")for i in (0, 1, 2):# 创建子弹精灵bullet = Bullet()# 设置子弹精灵组的位置bullet.rect.bottom = self.rect.y - i*20bullet.rect.centerx = self.rect.centerx# 将精灵添加到精灵组self.bullets.add(bullet)

5. 现在编写子弹精灵组的类,子弹主要就一个任务,那就是向上运动,其它的都不用做,相对其它的精灵组要简单。

class Bullet(GameSprites):"""子弹精灵"""def __init__(self):# 调用父类方法super().__init__("./images/p-f02.png", -2)def update(self):# 调用父类方法super().update()if self.rect.bottom < 0:self.kill()def __del__(self):# print("子弹被销毁")pass

到这里,我们所需的精灵组基本已经定义完了,可以开始在主函数中调用,主函数,相对而言就比较简单了,基本上只负责调用和刷新帧率,plane_main.py如下图所示,
plane_main.py

主要由七个函数组成,分别是初始化函数、创建精灵函数、开始游戏函数、事件触发中断函数、确认碰撞函数、更新精灵函数和游戏结束函数。
1. 初始化函数如下所示,基本上是固定的,

    def __init__(self):print("游戏初始化")# 1.创建游戏窗口self.screen = pygame.display.set_mode(SCREEN_RECT.size)# 2.创建游戏时钟self.clock = pygame.time.Clock()# 3.调用私有方法,精灵和精灵组创建self.creat_sprites()# 4. 设置定时器事件,创建敌机pygame.time.set_timer(CREAT_ENEMY_EVENT, 1000)# 5. 设置定时器事件,创建子弹pygame.time.set_timer(HERO_FIRE_EVENT, 500)

2. 创建精灵组,用于更新显示到屏幕

    def creat_sprites(self):# 创建背景精灵bg1 = Background()bg2 = Background(True)# bg2.rect.y = -bg2.rect.heightself.back_ground = pygame.sprite.Group(bg1, bg2)# 创建敌机精灵组self.enemy_ground = pygame.sprite.Group()# 创建英雄和英雄精灵组self.hero = Hero()self.hero_ground =pygame.sprite.Group(self.hero)

3. 开始游戏,这个也是固定的,

    def start_game(self):print("游戏开始")while True:# 1设置刷新帧率self.clock.tick(FRAME_PER_SEC)# 2设置监听self.__event_handler()# 3.设置碰撞检测self.__check_collid()# 4.更新精灵组self.__update_sprites()# 5.更新显示pygame.display.update()

4. 触发中断检测事件,监测是否按下退出键、敌机是否出现、是否按下左右移动的按键和发射子弹事件,如果检测到有事件发生,记录事件并进行判断为什么事件,再执行相应的代码。这里要注意,使用键盘函数来读取键值

    def __event_handler(self):for event in pygame.event.get():if event.type == pygame.QUIT:PlaneGame.__game_over()elif event.type == CREAT_ENEMY_EVENT:# print("敌机出现")# 创建敌机精灵,enemy = Enemy()# 将敌机精灵添加到精灵组self.enemy_ground.add(enemy)elif event.type ==HERO_FIRE_EVENT:self.hero.fire()# elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:# print("向右移动")# 使用键盘提供的方法key_pressed = pygame.key.get_pressed()# 判断元组中的键值if key_pressed[pygame.K_RIGHT]:self.hero.speed = 2elif key_pressed[pygame.K_LEFT]:self.hero.speed = -2else:self.hero.speed = 0

5. 检测碰撞函数,这里主要是子弹撞毁敌机,和敌机撞毁英雄,我们只要使用pygame自带的精灵组碰撞检测函数就行了groupcollide和spritecollide,会自动帮我们销毁敌机,但是英雄牺牲就需要判断一下,才能执行,要不然敌机会销毁而英雄不会牺牲。

    def __check_collid(self):# 销毁敌机(两个精灵组碰撞检测)pygame.sprite.groupcollide(self.hero.bullets, self.enemy_ground, True, True)# 敌机撞毁英雄enemies = pygame.sprite.spritecollide(self.hero, self.enemy_ground, True)if len(enemies) > 0:# 让英雄牺牲self.hero.kill()# 结束游戏PlaneGame.__game_over()

6. 更新精灵组函数,这个也是固定的两个函数,相应的精灵组使用update和draw函数就行了

    def __update_sprites(self):self.back_ground.update()self.back_ground.draw(self.screen)self.enemy_ground.update()self.enemy_ground.draw(self.screen)self.hero_ground.update()self.hero_ground.draw(self.screen)self.hero.bullets.update()self.hero.bullets.draw(self.screen)

7. 最后别忘了定义游戏结束的静态函数

    @staticmethoddef __game_over():print("游戏结束")pygame.quit()exit()

最后我们定义主函数

if __name__ == '__main__':# 创建游戏对象game = PlaneGame()# 游戏启动game.start_game()

这样就大功告成了,一个简单的飞机大战就完成了

百度网盘:
链接:https://pan.baidu.com/s/1cujNP3Ioj79wh7CM9W7Pxg 密码:az7p


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部