pygame-雷霆战机
1、主程序 plane_main.py
import pygame from plane_sprites import * class PlaneGame(object): def __init__(self): print("游戏初始化") # 创建游戏窗口 self.screen = pygame.display.set_mode(SCREEN_RECT.size) # 创建游戏时钟 self.clock = pygame.time.Clock() # 调用私有方法创建精灵和精灵组 self.__create_sprites() # 设置定时器事件,创建敌机 pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000) # 设置定时器事件,设置英雄自动开火,间隔1秒 pygame.time.set_timer(HERO_FIRE_EVENT, 1500) def start_game(self): print("游戏开始") while True: # 设置刷新帧率 self.clock.tick(FRAME_PER_SECOND) # 事件监听 self.__event_handler() # 碰撞检测 self.__check_collide() # 更新/绘制精灵组 self.__update_sprites() # 更新显示 pygame.display.update() def __event_handler(self): for event in pygame.event.get(): if event.type == pygame.QUIT: PlaneGame.__game_over() elif event.type == CREATE_ENEMY_EVENT: # 创建敌机精灵(定时器事件) enemy_sp = Enemy() self.enemy_group.add(enemy_sp) elif event.type == HERO_FIRE_EVENT: self.hero.fire() # 使用键盘提供的方法监听键盘事件,案件按下,值为1,返回的是元组 keys_pressed = pygame.key.get_pressed() if keys_pressed[pygame.K_RIGHT]: # 向右移动,坐标值增加 if self.hero.rect.right >= SCREEN_RECT.width: self.hero.speed = 0 else: self.hero.speed = 2 elif keys_pressed[pygame.K_LEFT]: if self.hero.rect.left <= 0: self.hero.speed = 0 else: self.hero.speed = -2 else: self.hero.speed = 0 def __check_collide(self): # 子弹摧毁敌机 pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True) # 英雄与精灵组任意精灵碰撞,精灵被摧毁,英雄不会被摧毁 clollide_enemys = pygame.sprite.spritecollide(self.hero, self.enemy_group, True) # 判断英雄碰撞的敌机数量,大于1,英雄需要被清除 if len(clollide_enemys) > 0: self.hero.kill() PlaneGame.__game_over() @staticmethod def __game_over(): pygame.quit() exit() def __create_sprites(self): print("创建精灵组") # 创建背景和背景组 bg1 = Background() bg2 = Background(is_alter=True) self.bg_group = pygame.sprite.Group(bg1, bg2) # 创建敌机精灵组 self.enemy_group = pygame.sprite.Group() # 创建英雄和英雄组,hero其他方法要使用,所以定义为属性 self.hero = Hero() self.hero_group = pygame.sprite.Group(self.hero) def __update_sprites(self): # 更新背景组 self.bg_group.update() self.bg_group.draw(self.screen) # 更新敌机组 self.enemy_group.update() self.enemy_group.draw(self.screen) # 更新英雄组 self.hero_group.update() self.hero_group.draw(self.screen) # 更新子弹精灵组 self.hero.bullets.update() self.hero.bullets.draw(self.screen) if __name__ == "__main__": # 创建游戏对象 game = PlaneGame() game.start_game()
2、精灵工具
import random import pygame # 定义以西窗口其实坐标位0,0 窗口宽度和高度 SCREEN_RECT = pygame.Rect(0, 0, 450, 700) # 刷新帧率,每秒60帧 FRAME_PER_SECOND = 60 # 创建敌机的定时器常量 CREATE_ENEMY_EVENT = pygame.USEREVENT # 创建英雄开火事件 HERO_FIRE_EVENT = pygame.USEREVENT + 1 class GameSprite(pygame.sprite.Sprite): def __init__(self, image_para, speed_para=1): # 父类不是object时都需要调用父类初始化方法 super().__init__() self.image = pygame.image.load(image_para) self.rect = self.image.get_rect() self.speed = speed_para def update(self): # 精灵父类update,设置飞行为垂直方向飞行 self.rect.y += self.speed class Background(GameSprite): def __init__(self, is_alter=False): super().__init__("./images/bg.jpg") # 如果时替换的背景 if is_alter: # bg2 初始位置要设置在窗口上方 self.rect.y = -self.rect.height def update(self): # 调用父类的update方法,向下移动 super().update() # 如果背景图片向下移出窗口,y坐标=700 if self.rect.y > SCREEN_RECT.height: self.rect.y = -SCREEN_RECT.height class Enemy(GameSprite): def __init__(self): # 调用父类方法,创建敌机,加载敌机图片 super().__init__("./images/enemy1.png") # 指定敌机初始位置是在窗口正上方 # self.rect.y = -SCREEN_RECT.height 等价于下面的语句 self.rect.bottom = 0 # 指定敌机的初始随机速度,敌机速度要大于 否则跟背景速度一样,会显示静止 self.speed = random.randint(2, 3) # 指定敌机的初始随机位置 self.rect.x = random.randint(0, SCREEN_RECT.width-self.rect.width) def update(self): # 调用父类方法,实现垂直向下飞行 super().update() # 判断是否废除屏幕,如果是,从精灵组移除 if self.rect.y >= SCREEN_RECT.height: # kill方法会将精灵从所有组中删除 self.kill() def __del__(self): print("敌机%s被销毁" % self.rect) class Hero(GameSprite): def __init__(self): # 调用父类方法,设置图片和速度 super().__init__("./images/hero.png", speed_para=0) # 设置英雄的初始位置 self.rect.centerx = SCREEN_RECT.centerx self.rect.bottom = SCREEN_RECT.bottom - 20 # 创建子弹精灵组 self.bullets = pygame.sprite.Group() def update(self): # 英雄只能左右移动,不能上下移动 self.rect.x += self.speed # 限定英雄不能飞出屏幕,等价于eventhandle中的代码 # if self.rect.right >= SCREEN_RECT.right: # self.rect.right = SCREEN_RECT.right # elif self.rect.x < 0: # self.rect.x = 0 def fire(self): # 创建子弹精灵,一次发射2发子弹 for i in (0,1): bullet = Bullet() # 设置子弹精灵的位置,在飞机正上方60单位,间隔60 bullet.rect.bottom = self.rect.y - i*60 bullet.rect.centerx = self.rect.centerx # 将精灵添加到精灵组 self.bullets.add(bullet) print("开火") class Bullet(GameSprite): def __init__(self): # 调用父类方法,设置子弹图片,设置初始速度 super().__init__("./images/bullet1.png", speed_para=-2) def update(self): # 调用父类方法,让子弹沿着垂直方向飞行 super().update() # 子弹飞出窗口,则销毁 bpottom 为图像的底部 if self.rect.bottom < 0: self.kill() def __del__(self): print("子弹被销毁")
3、资源图片
3.1 背景图片bg.jpg
3.2 英雄飞机 hero.png
3.3 敌机 enemy1.png
3.4 子弹bullet1.png
3.5 游戏画面
3.6 启动游戏