一、开发环境
开发环境 :Windows10 Python3.6.4
第三方库 :Pygame1.9.6
IDE :PyCharm/Sublime Text
二、功能模块
素材模块
游戏图片素材:
BGM及音效素材:
字体素材:
源码模块
子弹模块:
普通子弹部分源码:
def __init__(self, position): super().__init__() self.image = pygame.image.load("images/bullet1.png").convert_alpha() self.rect = self.image.get_rect() self.rect.left, self.rect.top = position self.speed = 12 self.active = False self.mask = pygame.mask.from_surface(self.image) def move(self): self.rect.top -= self.speed if self.rect.top < 0: self.active = False
超级子弹部分源码:
def __init__(self, position): super().__init__() self.image = pygame.image.load("images/bullet2.png").convert_alpha() self.rect = self.image.get_rect() self.rect.left, self.rect.top = position self.speed = 18 self.active = False self.mask = pygame.mask.from_surface(self.image) def move(self): self.rect.top -= self.speed if self.rect.top < 0: self.active = False
敌机子弹部分源码:
def __init__(self, speed, position): super().__init__() self.image = pygame.image.load("images/bullet1.png").convert_alpha() self.rect = self.image.get_rect() self.rect.left, self.rect.top = position self.speed = speed self.active = False self.mask = pygame.mask.from_surface(self.image)
敌机模块:
小型敌机部分源码:
class SmallEnemy(Enemy): def __init__(self, bg_size): super().__init__("images/enemy1.png", 2, bg_size) # 小型敌机毁灭图片切换 self.destroy_images = [] self.destroy_images.extend([pygame.image.load("images/enemy1_down1.png").convert_alpha(), pygame.image.load("images/enemy1_down2.png").convert_alpha(), pygame.image.load("images/enemy1_down3.png").convert_alpha(), pygame.image.load("images/enemy1_down4.png").convert_alpha()]) # 设置敌机原始位置 self.rect.left, self.rect.top = randint(0, self.width - self.rect.width), randint(-5 * self.height, 0) # 表明敌机目前的状态(为True表明敌机生存,反之为碰撞时毁灭,之后播放毁灭画面,重新调用reset方法,将敌机设置到初始位置) self.active = True # 返回英雄除了空白区域的部分 self.mask = pygame.mask.from_surface(self.image)
中型敌机部分源码:
class MidEnemy(Enemy): # 中型敌机打击次数 energy = 8 def __init__(self, bg_size): super().__init__("images/enemy2.png", 1, bg_size) # 中型敌机毁灭图片切换 self.destroy_images = [] self.destroy_images.extend([pygame.image.load("images/enemy2_down1.png").convert_alpha(), pygame.image.load("images/enemy2_down2.png").convert_alpha(), pygame.image.load("images/enemy2_down3.png").convert_alpha(), pygame.image.load("images/enemy2_down4.png").convert_alpha()]) # 子弹打击时效果图片 self.image_hit = pygame.image.load("images/enemy2_hit.png").convert_alpha() # 设置敌机原始位置 # self.width, self.height = bg_size[0], bg_size[1] self.rect.left, self.rect.top = randint(0, self.width - self.rect.width), randint(-10 * self.height, -self.height) self.active = True # 返回英雄除了空白区域的部分 self.mask = pygame.mask.from_surface(self.image) # 击打次数属性 self.energy = MidEnemy.energy # 是否击中属性 self.hit = False
我方战机模块部分源码:
class MyPlane(pygame.sprite.Sprite): def __init__(self, bg_size): super().__init__() # 获取英雄图片(两幅图片实现动态效果) self.image1 = pygame.image.load("images/me1.png").convert_alpha() self.image2 = pygame.image.load("images/me2.png").convert_alpha() # 英雄毁灭图片切换 self.destroy_images = [] self.destroy_images.extend([pygame.image.load("images/me_destroy_1.png").convert_alpha(), pygame.image.load("images/me_destroy_2.png").convert_alpha(), pygame.image.load("images/me_destroy_3.png").convert_alpha(), pygame.image.load("images/me_destroy_4.png").convert_alpha()]) # 获取英雄大小,宽度和高度 self.rect = self.image1.get_rect() # 设置英雄位置 self.width, self.height = bg_size[0], bg_size[1] self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, self.height - self.rect.height - 60 # 设置英雄速度 self.speed = 10 # 设置英雄生存状态 self.active = True # 设置飞机无敌 self.invincible = False # 返回英雄除了空白区域的部分 self.mask = pygame.mask.from_surface(self.image1)
技能模块部分源码:
class BulletSupply(pygame.sprite.Sprite): def __init__(self, bgsize): super().__init__() self.image = pygame.image.load("images/bullet_supply.png").convert_alpha() self.rect = self.image.get_rect() self.width, self.height = bgsize[0], bgsize[1] self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100 self.speed = 5 self.active = False self.mask = pygame.mask.from_surface(self.image) def move(self): if self.rect.top < self.height: self.rect.top += self.speed else: self.active = False def reset(self): self.active = True self.rect.left, self.rect.bottom = randint(0, self.width - self.rect.width), -100
主模块
游戏初始化部分源码:
def __init__(self): # 1.变量定义 self.__variate__define() # 2.pygame和音乐初始化 pygame.init() pygame.mixer.init() # 3.创建游戏窗口 self.screen = pygame.display.set_mode(self.bg_size) pygame.display.set_caption("飞机大战") # 4.获取背景图片 self.background = pygame.image.load("images/background.png").convert() # 5.创建游戏时钟 self.clock = pygame.time.Clock() # 6.载入音乐模块 pygame.mixer.music.load("sound/game_music.ogg") pygame.mixer.music.set_volume(0.2) # 设置音量 self.bullet_sound = pygame.mixer.Sound("sound/bullet.wav") self.bullet_sound.set_volume(0.2) self.bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav") self.bomb_sound.set_volume(0.2)
控制英雄飞机:
def __keypress_hanlder(self): """检测用户的键盘操作,控制英雄飞机""" key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: self.hero.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: self.hero.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: self.hero.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: self.hero.moveRight()
创建敌机源码:
def add_small_enemy(self, group1, group2, num): """创建小型敌机对象,num为对象个数,将其添加到精灵组中""" for i in range(num): e1 = enemy_plane.SmallEnemy(self.bg_size) group1.add(e1) group2.add(e1) def add_mid_enemy(self, group1, group2, num): """创建中型敌机对象""" for i in range(num): e1 = enemy_plane.MidEnemy(self.bg_size) group1.add(e1) group2.add(e1) def add_big_enemy(self, group1, group2, num): """创建大型敌机对象""" for i in range(num): e1 = enemy_plane.BigEnemy(self.bg_size) group1.add(e1) group2.add(e1)
子弹生成部分源码:
def __create_bullet(self): # 生成普通子弹 self.bullet1 = [] self.bullet1_index = 0 self.BULLET_NUM = 4 for i in range(self.BULLET_NUM): self.bullet1.append(bullet.Bullet1(self.hero.rect.midtop))
定义游戏难度部分源码:
def __create_start_image(self): # 定义难度属性 self.easy = True self.common = False self.difficult = False # 飞机大战主题 self.start = False self.theme_font = pygame.font.Font("font/font.ttf", 50) self.theme_text = self.theme_font.render("Plane War", True, self.WHILE) self.theme_text_rect = self.theme_text.get_rect() self.theme_text_rect.left, self.theme_text_rect.top = (120, 40) # 游戏开始字体 self.start_font = pygame.font.Font("font/font.ttf", 40) self.start_text = self.start_font.render("Start Game", True, self.WHILE) self.start_text_rect = self.start_text.get_rect() self.start_text_rect.left, self.start_text_rect.top = (150, 200) # 简单字体 self.easy_font = pygame.font.Font("font/font.ttf", 40) self.easy_text = self.easy_font.render("easy", True, self.BLACK) self.easy_text_rect = self.easy_text.get_rect() self.easy_text_rect.left, self.easy_text_rect.top = (200, 400) # 一般字体 self.common_font = pygame.font.Font("font/font.ttf", 40) self.common_text = self.common_font.render("common", True, self.WHILE) self.common_text_rect = self.common_text.get_rect() self.common_text_rect.left, self.common_text_rect.top = (180, 450) # 困难字体 self.difficult_font = pygame.font.Font("font/font.ttf", 40) self.difficult_text = self.difficult_font.render("difficult", True, self.WHILE) self.difficult_text_rect = self.difficult_text.get_rect() self.difficult_text_rect.left, self.difficult_text_rect.top = (180, 510)
三、游戏效果
游戏开始效果:
游戏战斗效果:
游戏结束效果:
游戏UI界面优化:可以使用游戏引擎pygame-menu进行优化
课后作业:游戏动态地图实现