项目下载链接:
https://download.csdn.net/download/qq_39236499/12793963
游戏操作:
1.wsad或者方向键操作飞机
2.空格键放全屏炸弹
代码:
此代码分5个模块
main.py
import pygame import sys # 退出需要 import traceback # 为了更好地退出 from pygame.locals import * # 就直接用QUIT而不需要pygame.QUIT from random import * # 生成随机数需要 """自建模块""" import myplane # 飞机模块 import bullet # 子弹模块 import enemy # 敌机模块 import supply # 补给模块 """一些初始化""" pygame.init() # 初始化 pygame.mixer.init() # 混音器初始化 """一些设置""" ######################################################################################################################## # 颜色设置 BLACK = (0, 0, 0) # 黑色 WHITE = (255, 255, 255) # 白色 GREEN = (0, 255, 0) # 绿色 RED = (255, 0, 0) # 红色 # 窗口尺寸设置 bg_size = width, height = 480, 700 # 背景尺寸 # 音乐设置 pygame.mixer.music.load("sound/game_music.ogg") # 游戏背景声音 pygame.mixer.music.set_volume(0.2) bullet_sound = pygame.mixer.Sound("sound/bullet.wav") bullet_sound.set_volume(0.2) bomb_sound = pygame.mixer.Sound("sound/use_bomb.wav") bomb_sound.set_volume(0.2) supply_sound = pygame.mixer.Sound("sound/supply.wav") supply_sound.set_volume(0.2) get_bomb_sound = pygame.mixer.Sound("sound/get_bomb.wav") get_bomb_sound.set_volume(0.2) get_bullet_sound = pygame.mixer.Sound("sound/get_bullet.wav") get_bullet_sound.set_volume(0.2) upgrade_sound = pygame.mixer.Sound("sound/upgrade.wav") upgrade_sound.set_volume(0.2) enemy3_fly_sound = pygame.mixer.Sound("sound/enemy3_flying.wav") enemy3_fly_sound.set_volume(0.2) enemy1_down_sound = pygame.mixer.Sound("sound/enemy1_down.wav") enemy1_down_sound.set_volume(0.2) enemy2_down_sound = pygame.mixer.Sound("sound/enemy2_down.wav") enemy2_down_sound.set_volume(0.2) enemy3_down_sound = pygame.mixer.Sound("sound/enemy3_down.wav") enemy3_down_sound.set_volume(0.5) me_down_sound = pygame.mixer.Sound("sound/me_down.wav") me_down_sound.set_volume(0.2) ######################################################################################################################## """一些函数""" ######################################################################################################################## def add_small_enemies(group1, group2, num): for i in range(num): e1 = enemy.SmallEnemy(bg_size) group1.add(e1) group2.add(e1) def add_mid_enemies(group1, group2, num): for i in range(num): e2 = enemy.MidEnemy(bg_size) group1.add(e2) group2.add(e2) def add_big_enemies(group1, group2, num): for i in range(num): e3 = enemy.BigEnemy(bg_size) group1.add(e3) group2.add(e3) def inc_speed(target, inc): for each in target: each.speed += inc ######################################################################################################################## screen = pygame.display.set_mode(bg_size) # 创建窗口 pygame.display.set_caption("飞机大战") # 窗口名字 background = pygame.image.load("images/background.png").convert() # 加载背景图片 def main(): # 主函数 pygame.mixer.music.play(-1) # -1循环播放背景音乐 clock = pygame.time.Clock() # 生成我方飞机 me = myplane.MyPlane(bg_size) enemies = pygame.sprite.Group() # 生成敌方小型飞机 small_enemies = pygame.sprite.Group() add_small_enemies(small_enemies, enemies, 15) # 15个 # 生成敌方中型飞机 mid_enemies = pygame.sprite.Group() add_mid_enemies(mid_enemies, enemies, 4) # 4个 # 生成敌方大型飞机 big_enemies = pygame.sprite.Group() add_big_enemies(big_enemies, enemies, 2) # 2个 # 生成普通子弹 bullet1 = [] bullet1_index = 0 BULLET1_NUM = 4 # 子弹数量 for i in range(BULLET1_NUM): bullet1.append(bullet.Bullet1(me.rect.midtop)) # 子弹放置飞机的顶部中央 # 生成超级子弹 bullet2 = [] bullet2_index = 0 BULLET2_NUM = 8 # 超级子弹数量,一列4个 for i in range(BULLET2_NUM//2): bullet2.append(bullet.Bullet2((me.rect.centerx-33, me.rect.centery))) # 第一列 bullet2.append(bullet.Bullet2((me.rect.centerx+30, me.rect.centery))) # 第二列 # 中弹图片索引 e1_destroy_index = 0 e2_destroy_index = 0 e3_destroy_index = 0 me_destroy_index = 0 # 统计得分 score = 0 # 初始化0分 score_font = pygame.font.Font("font/font.ttf", 36) # 字体,字号 # 标志是否暂停游戏 paused = False pause_nor_image = pygame.image.load("images/pause_nor.png")\ .convert_alpha() # 暂停图片1 pause_pressed_image = pygame.image.load("images/pause_pressed.png")\ .convert_alpha() # 暂停图片1 resume_nor_image = pygame.image.load("images/resume_nor.png")\ .convert_alpha() # 非暂停图片1 resume_pressed_image = pygame.image.load("images/resume_pressed.png")\ .convert_alpha() # 非暂停图片2 paused_rect = pause_nor_image.get_rect() # 图片矩形 paused_rect.left, paused_rect.top = width - paused_rect.width - 10, 10 # 图片矩形位置 paused_image = pause_nor_image # 初始化图片最初状态,为暂停图片1 # 设置难度级别 level = 1 # 初始化等级 # 全屏炸弹 bomb_image = pygame.image.load("images/bomb.png").convert_alpha() # 炸弹的图片 bomb_rect = bomb_image.get_rect() # 炸弹的图片的矩形 bomb_font = pygame.font.Font("font/font.ttf", 48) # 显示炸弹个数的字体,字号 bomb_num = 3 # 初始化3个全屏炸弹 # 每30秒发放一个补给包 bullet_supply = supply.Bullet_Supply(bg_size) # 超级子弹补给 bomb_supply = supply.Bomb_Supply(bg_size) # 全屏炸弹补给 SUPPLY_TIME = USEREVENT # 自定义事件1 pygame.time.set_timer(SUPPLY_TIME, 30 * 1000) # 定时器30秒,30×1000毫秒 # 超级子弹定时器 DOUBLE_BULLET_TIME = USEREVENT + 1 # 自定义事件2 # 标志是否使用超级子弹 is_double_bullet = False # 解除我方无敌状态定时器 INVINCIBLE_TIME = USEREVENT + 2 # 自定义事件3 # 生命数量 life_image = pygame.image.load("images/life.png")\ .convert_alpha() # 生命的图片,小飞机表示生命 life_rect = life_image.get_rect() # 图片矩形 life_num = 3 # 初始化3条命 # 用于阻止重复打开记录文件 recorded = False # 游戏结束画面 gameover_font = pygame.font.Font("font/font.ttf", 48) # 字体,字号 again_image = pygame.image.load("images/again.png").convert_alpha() # 再来一次的图片 again_rect = again_image.get_rect() # 图片矩形 gameover_image = pygame.image.load("images/gameover.png").convert_alpha() # 游戏结束的图片 gameover_rect = gameover_image.get_rect() # 图片矩形 # 用于切换图片 switch_image = True # 用于延迟 delay = 100 running = True # 这个就没改过 while running: for event in pygame.event.get(): # 遍历事件 if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: # 按下鼠标 if event.button == 1 and paused_rect.collidepoint(event.pos): # 1是左键,鼠标在按钮上且点击了左键 paused = not paused # 暂停不暂停相互切换 if paused: # 如果暂停 pygame.time.set_timer(SUPPLY_TIME, 0) # 暂停供给 pygame.mixer.music.pause() # 暂停音乐 pygame.mixer.pause() # 暂停混音器 else: # 如果不暂停 pygame.time.set_timer(SUPPLY_TIME, 30*1000) # 30秒一个供给 pygame.mixer.music.unpause() # 不暂停音乐 pygame.mixer.unpause() # 不暂停混音器 elif event.type == MOUSEMOTION: # 鼠标有移动 if paused_rect.collidepoint(event.pos): # 鼠标位置在图片上 if paused: paused_image = resume_pressed_image else: paused_image = pause_pressed_image else: # 鼠标没在图片上,显示浅色的方案 if paused: paused_image = resume_nor_image else: paused_image = pause_nor_image elif event.type == KEYDOWN: # 如果有按键 if event.key == K_SPACE: # 按下的是空格键 if bomb_num: # 如果还有全屏炸弹 bomb_num -= 1 # 剩余全屏炸弹数量-1 bomb_sound.play() # 炸弹播放音效 for each in enemies: # 遍历敌人 if each.rect.bottom > 0: # 如果有敌人在屏幕内 each.active = False # 毁灭它们 elif event.type == SUPPLY_TIME: # 如果有供给 supply_sound.play() # 供给音效播放 if choice([True, False]): # 随机供给 bomb_supply.reset() else: bullet_supply.reset() elif event.type == DOUBLE_BULLET_TIME: # 如果是超级子弹 is_double_bullet = False # 改为False pygame.time.set_timer(DOUBLE_BULLET_TIME, 0) # 取消计时器 elif event.type == INVINCIBLE_TIME: # 如果是无敌状态 me.invincible = False # 改False pygame.time.set_timer(INVINCIBLE_TIME, 0) # 取消计时器 # 升级提升游戏难度 ######################################################################################################################## # 根据用户的得分增加难度 if level == 1 and score > 50000: level = 2 upgrade_sound.play() # 增加3架小型敌机,2架中型敌机,1架大型敌机 add_small_enemies(small_enemies, enemies, 3) add_mid_enemies(mid_enemies, enemies, 2) add_big_enemies(big_enemies, enemies, 1) # 提升小型敌机的速度 inc_speed(small_enemies, 1) elif level == 2 and score > 300000: level = 3 upgrade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型,中型敌机的速度 inc_speed(small_enemies, 1) inc_speed(big_enemies, 1) elif level == 3 and score > 600000: level = 4 upgrade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型,中型敌机的速度 inc_speed(small_enemies, 1) inc_speed(big_enemies, 1) elif level == 4 and score > 1000000: level = 5 upgrade_sound.play() # 增加5架小型敌机,3架中型敌机,2架大型敌机 add_small_enemies(small_enemies, enemies, 5) add_mid_enemies(mid_enemies, enemies, 3) add_big_enemies(big_enemies, enemies, 2) # 提升小型,中型敌机的速度 inc_speed(small_enemies, 1) inc_speed(big_enemies, 1) ######################################################################################################################## screen.blit(background, (0, 0)) # 绘制背景 if life_num and not paused: # 如果还有名且非暂停 # 检测用户的键盘操作 key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: # 向上 me.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: # 向下 me.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: # 向左 me.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: # 向右 me.moveRight() # 绘制全屏炸弹补给并检测是否获得 if bomb_supply.active: # 炸弹供给为活跃状态时 bomb_supply.move() # 向下移动炸弹供给 screen.blit(bomb_supply.image, bomb_supply.rect) # 绘制炸弹图像 if pygame.sprite.collide_mask(bomb_supply, me): # 如果飞机接收到供给 get_bomb_sound.play() # 播放接收到的音效 if bomb_num < 3: # 如果现存全屏炸弹数量 < 3 bomb_num += 1 # 全屏炸弹+1 bomb_supply.active = False # 供给状态改为非活跃状态 # 绘制超级子弹补给并检测是否获得 if bullet_supply.active: # 超级子弹供给为活跃状态时 bullet_supply.move() # 向下移动超级子弹供给 screen.blit(bullet_supply.image, bullet_supply.rect) # 绘制超级子弹图像 if pygame.sprite.collide_mask(bullet_supply, me): # 如果飞机接收到供给 get_bullet_sound.play() # 播放音效 # 发射超级子弹 is_double_bullet = True # 超级子弹现在为活跃状态 pygame.time.set_timer(DOUBLE_BULLET_TIME, 18 * 1000) # 18秒状态的定时器 bullet_supply.active = False # 供给状态改为非活跃 # 子弹 ######################################################################################################################## # 发射子弹 if not(delay % 10): # 被10整除 bullet_sound.play() if is_double_bullet: bullets = bullet2 bullets[bullet2_index].reset((me.rect.centerx-33, me.rect.centery)) bullets[bullet2_index+1].reset((me.rect.centerx+30, me.rect.centery)) bullet2_index = (bullet2_index + 2) % BULLET2_NUM else: bullets = bullet1 bullets[bullet1_index].reset(me.rect.midtop) # 复位子弹 bullet1_index = (bullet1_index + 1) % BULLET1_NUM # 索引+1 # 检测子弹是否击中敌机 for b in bullets: # 遍历子弹 if b.active: # 如果活跃为True b.move() # 移动子弹 screen.blit(b.image, b.rect) # 绘制子弹 enemy_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask) # 检测碰撞 if enemy_hit: # 如果碰撞 b.active = False # 子弹活跃False for e in enemy_hit: # 遍历碰撞 if e in mid_enemies or e in big_enemies: # 如果碰撞大型敌机或者中型敌机 e.hit = True # 击中为True e.energy -= 1 # 血量-1 if e.energy == 0: # 当血量为0 e.active = False # 敌机活跃改为False else: # 如果是小型飞机 e.active = False # 敌机活跃改为False ######################################################################################################################## # 绘制大型敌机 ######################################################################################################################## for each in big_enemies: # 遍历大型敌机 if each.active: # 如果敌机活跃为True each.move() # 移动敌机 if each.hit: # 如果敌机被击中 # 绘制被打到的特效 screen.blit(each.image_hit, each.rect) # 绘制击中的效果图像 each.hit = False # 击中改为False else: # 如果没有被击中,正常情况下 if switch_image: screen.blit(each.image1, each.rect) # 绘制第一张敌机图像 else: screen.blit(each.image2, each.rect) # 绘制第二张敌机图像 # 绘制血槽,黑线 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.BigEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) # 大型敌机即将出现在画面中,播放音效 if each.rect.bottom == -50: # 大型敌机距离上边界50 enemy3_fly_sound.play(-1) # 循环播放大型敌机的音效 else: # 如果大型敌机为非活跃状态 # 毁灭 if not (delay % 3): # 被3整除 if e3_destroy_index == 0: # 大型敌机被毁灭图片播放完 enemy3_down_sound.play() # 播放大型敌机被击落的音效 screen.blit(each.destroy_images[e3_destroy_index], each.rect) e3_destroy_index = (e3_destroy_index + 1) % 6 # 图片索引+1 if e3_destroy_index == 0: # 播放完 enemy3_fly_sound.stop() # 大型敌机被击落的音效暂停 score += 10000 each.reset() # 敌机重置复位 ######################################################################################################################## # 绘制中型敌机 ######################################################################################################################## for each in mid_enemies: # 遍历中型敌机 if each.active: # 如果中型敌机活跃为True each.move() # 移动中型敌机 if each.hit: # 如果被击中 screen.blit(each.image_hit, each.rect) # 绘制被击中效果图像 each.hit = False # 被击中改为False,就是不在绘制被击中的效果图像 else: # 没有被击中 screen.blit(each.image, each.rect) # 绘制正常的中型敌机图像 # 绘制血槽 pygame.draw.line(screen, BLACK, (each.rect.left, each.rect.top - 5), (each.rect.right, each.rect.top - 5), 2) # 当生命大于20%显示绿色,否则显示红色 energy_remain = each.energy / enemy.MidEnemy.energy if energy_remain > 0.2: energy_color = GREEN else: energy_color = RED pygame.draw.line(screen, energy_color, (each.rect.left, each.rect.top - 5), (each.rect.left + each.rect.width * energy_remain, each.rect.top - 5), 2) else: # 如果非活跃状态 # 毁灭 if not (delay % 3): # 被3整除 if e2_destroy_index == 0: # 播放完 enemy2_down_sound.play() # 被击落的音效播放 screen.blit(each.destroy_images[e2_destroy_index], each.rect) # 绘制被击落的效果图像 e2_destroy_index = (e2_destroy_index + 1) % 4 # 索引+1 if e2_destroy_index == 0: # 播放完 score += 6000 each.reset() # 复位 ######################################################################################################################## # 绘制小型敌机 ######################################################################################################################## for each in small_enemies: # 遍历小型敌机 if each.active: # 为活跃状态 each.move() # 移动敌机 screen.blit(each.image, each.rect) # 绘制敌机 else: # 如果为非活跃状态 # 毁灭 if not (delay % 3): if e1_destroy_index == 0: # 播放完 enemy1_down_sound.play() # 播放被击落的音效 screen.blit(each.destroy_images[e1_destroy_index], each.rect) # 绘制效果图 e1_destroy_index = (e1_destroy_index + 1) % 4 # 索引+1 if e1_destroy_index == 0: # 播放完 score += 1000 each.reset() # 复位 ######################################################################################################################## ######################################################################################################################## # 检测我飞机是否被撞 enemies_down = pygame.sprite.spritecollide(me, enemies, False, pygame.sprite.collide_mask) if enemies_down and not me.invincible: # 如果被撞 # 这里可以改无敌 me.active = False # 飞机活跃状态改为False for e in enemies_down: # 遍历被撞的敌机 e.active = False # 敌机状态也改为False # 绘制我方飞机 if me.active: # 没被撞,活跃正常时 if switch_image: screen.blit(me.image1, me.rect) # 第一张图像 else: screen.blit(me.image2, me.rect) # 第二张图像 else: # 非活跃 # 毁灭 if not (delay % 3): if me_destroy_index == 0: # 播放完 me_down_sound.play() # 播放坠落音效 screen.blit(me.destroy_images[me_destroy_index], me.rect) # 绘制被撞图像 me_destroy_index = (me_destroy_index + 1) % 4 # 索引+1 if me_destroy_index == 0: # 播放完 life_num -= 1 me.reset() pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000) # 绘制全屏炸弹数量 bomb_text = bomb_font.render("× %d" % bomb_num, True, WHITE) text_rect = bomb_text.get_rect() screen.blit(bomb_image, (10, height - 10 - bomb_rect.height)) # 先画炸弹图片 screen.blit(bomb_text, (20 + bomb_rect.width, height - 5 - text_rect.height)) # 再画文本 # 绘制剩余生命数量 if life_num: for i in range(life_num): screen.blit(life_image, (width-10-(i+1)*life_rect.width, height-10-life_rect.height)) # 绘制得分 score_text = score_font.render("Score : %s" % str(score), True, WHITE) screen.blit(score_text, (10, 5)) # 绘制游戏结束画面 elif life_num == 0: # 背景音乐停止 pygame.mixer.music.stop() # 停止全部音效 pygame.mixer.stop() # 停止发放补给 pygame.time.set_timer(SUPPLY_TIME, 0) if not recorded: recorded = True # 读取历史最高得分 with open("record.txt", "r") as f: record_score = int(f.read()) # 如果玩家得分高于历史最高得分,存档 if score > record_score: with open("record.txt", "w") as f: f.write(str(score)) # 绘制游戏结束界面 # 绘制结束画面 record_score_text = score_font.render("Best : %d" % record_score, True, (255, 255, 255)) screen.blit(record_score_text, (50, 50)) gameover_text1 = gameover_font.render("Your Score", True, (255, 255, 255)) gameover_text1_rect = gameover_text1.get_rect() gameover_text1_rect.left, gameover_text1_rect.top = \ (width - gameover_text1_rect.width) // 2, height // 3 screen.blit(gameover_text1, gameover_text1_rect) gameover_text2 = gameover_font.render(str(score), True, (255, 255, 255)) gameover_text2_rect = gameover_text2.get_rect() gameover_text2_rect.left, gameover_text2_rect.top = \ (width - gameover_text2_rect.width) // 2, \ gameover_text1_rect.bottom + 10 screen.blit(gameover_text2, gameover_text2_rect) again_rect.left, again_rect.top = \ (width - again_rect.width) // 2, gameover_text2_rect.bottom + 50 screen.blit(again_image, again_rect) gameover_rect.left, gameover_rect.top = \ (width - again_rect.width) // 2, again_rect.bottom + 10 screen.blit(gameover_image, gameover_rect) # 检测用户的鼠标操作 # 如果用户按下鼠标左键 if pygame.mouse.get_pressed()[0]: # 获取鼠标坐标 pos = pygame.mouse.get_pos() # 如果用户点击“重新开始” if again_rect.left < pos[0] < again_rect.right and again_rect.top < pos[1] < again_rect.bottom: # 调用main函数,重新开始游戏 main() # 如果用户点击“结束游戏” elif gameover_rect.left < pos[0] < gameover_rect.right and \ gameover_rect.top < pos[1] < gameover_rect.bottom: # 退出游戏 pygame.quit() sys.exit() # 绘制暂停按钮 screen.blit(paused_image, paused_rect) ######################################################################################################################## # 切换图片,5帧切换一次 if not(delay % 5): # 被5整除 switch_image = not switch_image # 切换图片 delay -= 1 # 递减 if not delay: delay = 100 pygame.display.flip() clock.tick(60) # 一秒钟60次 # 运行 ######################################################################################################################## if __name__ == "__main__": try: main() except SystemExit: # 这是按下 × 的异常,直接忽略 pass except: traceback.print_exc() pygame.quit() input() ########################################################################################################################
myplane.py
import pygame class MyPlane(pygame.sprite.Sprite): # 继承动画精灵类 def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵 self.image1 = pygame.image.load("images/me1.png").convert_alpha() # 飞机图片1 self.image2 = pygame.image.load("images/me2.png").convert_alpha() # 飞机图片2 self.destroy_images = [] self.destroy_images.extend([ pygame.image.load("images/me_destroy_1.png").convert_alpha(), # 飞机被撞图片1 pygame.image.load("images/me_destroy_2.png").convert_alpha(), # 飞机被撞图片2 pygame.image.load("images/me_destroy_3.png").convert_alpha(), # 飞机被撞图片3 pygame.image.load("images/me_destroy_4.png").convert_alpha() # 飞机被撞图片4 ]) 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 # 飞机速度为10 self.active = True self.invincible = False # 无敌 self.mask = pygame.mask.from_surface(self.image1) # 标记飞机非透明部分 def moveUp(self): # 向上移动的方法 if self.rect.top > 0: # 飞机矩形坐标上边界 > 0 self.rect.top -= self.speed # 坐标数值变小,即向上移动 else: # 到屏幕顶端 self.rect.top = 0 # 保证飞机不出屏幕 def moveDown(self): # 向下移动的方法 if self.rect.bottom < self.height - 60: self.rect.top += self.speed else: self.rect.bottom = self.height - 60 def moveLeft(self): if self.rect.left > 0: self.rect.left -= self.speed else: self.rect.left = 0 def moveRight(self): if self.rect.right < self.width: self.rect.left += self.speed else: self.rect.right = self.width def reset(self): self.rect.left, self.rect.top = \ (self.width - self.rect.width) // 2, \ self.height - self.rect.height - 60 self.active = True self.invincible = True
enemy.py
import pygame from random import * class SmallEnemy(pygame.sprite.Sprite): # 小型敌机类,继承动画精灵类 def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵 self.image = pygame.image.load("images/enemy1.png").convert_alpha() # 小型敌机图片 self.destroy_images = [] self.destroy_images.extend([ pygame.image.load("images/enemy1_down1.png").convert_alpha(), # 小型敌机被击落图片1 pygame.image.load("images/enemy1_down2.png").convert_alpha(), # 小型敌机被击落图片2 pygame.image.load("images/enemy1_down3.png").convert_alpha(), # 小型敌机被击落图片3 pygame.image.load("images/enemy1_down4.png").convert_alpha() # 小型敌机被击落图片4 ]) self.rect = self.image.get_rect() # 小型敌机矩形位置 self.width, self.height = bg_size[0], bg_size[1] # 屏幕宽,高 self.speed = 2 # 小型敌机速度为2 self.active = True # 初始化在动 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-5 * self.height, 0) # 随机生成小型敌机位置,在屏幕上边界外面 self.mask = pygame.mask.from_surface(self.image) # 标记小型敌机图片非透明部分 def move(self): # 小型敌机移动的方法,只能向下移动 if self.rect.top < self.height: self.rect.top += self.speed else: # 出了屏幕下边界 self.reset() # 重置 def reset(self): # 重置的方法 self.active = True # 重置在动 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-5 * self.height, 0) # 重新随机在屏幕上边界外面生成 class MidEnemy(pygame.sprite.Sprite): # 中型敌机类,继承动画精灵类 energy = 8 # 中型敌机的血量8 def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵类 self.image = pygame.image.load("images/enemy2.png").convert_alpha() # 中型敌机图片 self.image_hit = pygame.image.load("images/enemy2_hit.png")\ .convert_alpha() # 中型敌机被击中时的图片 self.destroy_images = [] self.destroy_images.extend([ pygame.image.load("images/enemy2_down1.png").convert_alpha(), # 中型敌机被击落的图片1 pygame.image.load("images/enemy2_down2.png").convert_alpha(), # 中型敌机被击落的图片2 pygame.image.load("images/enemy2_down3.png").convert_alpha(), # 中型敌机被击落的图片3 pygame.image.load("images/enemy2_down4.png").convert_alpha() # 中型敌机被击落的图片4 ]) self.rect = self.image.get_rect() # 中型敌机矩形位置 self.width, self.height = bg_size[0], bg_size[1] # 窗口的宽,高 self.speed = 1 # 中型敌机移动速度 self.active = True # 初始化在动 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-10 * self.height, -self.height) # 随机生成中型敌机位置,在屏幕上边界外面 self.mask = pygame.mask.from_surface(self.image) # 标记中型敌机图片非透明部分 self.energy = MidEnemy.energy # 中型敌机的血量为8 self.hit = False # 初始化没击中 """中型敌机移动的方法,只能向下,处理屏幕就重置复位""" def move(self): # 移动的方法,只能向下 if self.rect.top < self.height: self.rect.top += self.speed else: # 出了屏幕底端 self.reset() # 重置 """"重置的方法""" def reset(self): # 重置的方法 self.active = True # 重置在动 self.energy = MidEnemy.energy # 重置血量8 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-10 * self.height, -self.height) # 重新随机在屏幕上边界外面生成 class BigEnemy(pygame.sprite.Sprite): # 大型敌机类,继承动画精灵类 energy = 20 # 大型敌机血量20 def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵 self.image1 = pygame.image.load("images/enemy3_n1.png")\ .convert_alpha() # 大型敌机图片1 self.image2 = pygame.image.load("images/enemy3_n2.png")\ .convert_alpha() # 大型敌机图片2 self.image_hit = pygame.image.load("images/enemy3_hit.png")\ .convert_alpha() # 大型敌机被击中时图片 self.destroy_images = [] self.destroy_images.extend([ pygame.image.load("images/enemy3_down1.png").convert_alpha(), # 大型敌机被击落图片1 pygame.image.load("images/enemy3_down2.png").convert_alpha(), # 大型敌机被击落图片2 pygame.image.load("images/enemy3_down3.png").convert_alpha(), # 大型敌机被击落图片3 pygame.image.load("images/enemy3_down4.png").convert_alpha(), # 大型敌机被击落图片4 pygame.image.load("images/enemy3_down5.png").convert_alpha(), # 大型敌机被击落图片5 pygame.image.load("images/enemy3_down6.png").convert_alpha() # 大型敌机被击落图片6 ]) self.rect = self.image1.get_rect() # 大型敌机矩形位置 self.width, self.height = bg_size[0], bg_size[1] # 屏幕宽,高 self.speed = 1 # 大型敌机速度为1 self.active = True # 初始化在动 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-15 * self.height, -5 * self.height) # 随机生成大型敌机位置,在屏幕上边界外面 self.mask = pygame.mask.from_surface(self.image1) # 标记大型敌机图片非透明部分 self.energy = BigEnemy.energy # 大型敌机血量20 self.hit = False # 初始化没击中 def move(self): # 移动的方法,只能向下移动 if self.rect.top < self.height: self.rect.top += self.speed else: # 出了屏幕下边界 self.reset() # 重置 def reset(self): # 重置的方法 self.active = True # 重置在动 self.energy = BigEnemy.energy # 重置血量 self.rect.left, self.rect.top = \ randint(0, self.width - self.rect.width), \ randint(-15 * self.height, -5 * self.height) # 重置位置,在屏幕上边界外面
bullet.py
import pygame class Bullet1(pygame.sprite.Sprite): # 子弹类,继承动画精灵类 def __init__(self, position): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵 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 reset(self, position): # 重置的方法 self.rect.left, self.rect.top = position # 重置位置 self.active = True # 重置在动 class Bullet2(pygame.sprite.Sprite): # 子弹类,继承动画精灵类 def __init__(self, position): pygame.sprite.Sprite.__init__(self) # 初始化动画精灵 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 = 14 # 子弹速度 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 reset(self, position): # 重置的方法 self.rect.left, self.rect.top = position # 重置位置 self.active = True
supply.py
import pygame from random import * class Bullet_Supply(pygame.sprite.Sprite): def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/bullet_supply.png").convert_alpha() self.rect = self.image.get_rect() self.width, self.height = bg_size[0], bg_size[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 class Bomb_Supply(pygame.sprite.Sprite): def __init__(self, bg_size): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/bomb_supply.png").convert_alpha() self.rect = self.image.get_rect() self.width, self.height = bg_size[0], bg_size[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
素材:
图像,音频,字体素材太多,就不贴出来,自行下载,下载链接: