赞
踩
简介:一共分为2个py文件,分别是主类、和精灵类
飞机大战图片地址:链接: https://pan.baidu.com/s/18T6n9JFIDxBqYX9CnHi7ZQ 密码: tqbr
注释:项目启动后如果报libpng warning: iCCP: known incorrect sRGB profile无须处理,不会影响项目和代码,视觉洁癖可以直接百度搜索这个错误提示,网上有解决办法
ps:因为图片是png格式,而libpng-1.6以上版本增强了ICC profiles检查,所以才会警告
plane_main.py(启动主类)
- import pygame
-
- import plane_sprites
-
-
- class PlanGame(object):
- """飞机大战-主体类"""
-
- def __init__(self):
- """
- 初始化
- """
- pygame.init()
- # 创建窗口
- self.screen = pygame.display.set_mode(plane_sprites.SCREEN_RECT.size)
- # 创建游戏时钟对象
- self.clock = pygame.time.Clock()
- # 创建精灵组
- self.__create_sprites()
- # 定时器 - 创建敌机 1s (USEREVENT是一个常量,可以通过+1来改变此常量)
- pygame.time.set_timer(pygame.USEREVENT, 1000)
- # 定时器 - 主机子弹 0.5s
- pygame.time.set_timer(pygame.USEREVENT + 1, 500)
-
- def start_game(self):
- """
- 启动游戏
- :return:
- """
- while True:
- # 执行循环中游戏时钟的频率
- self.clock.tick(plane_sprites.FRAME_PER_SEC)
- # 事件监听
- self.__event__handler()
- # 碰撞检测
- self.__check_collide()
- # 更新/绘制精灵族
- self.__update_sprites()
- # 更新显示
- pygame.display.update()
-
- def __create_sprites(self):
- """
- 创建/绘制精灵族
- :return:
- """
- # 创建背景精灵和精灵组
- bg_one = plane_sprites.BackGround(False)
- bg_two = plane_sprites.BackGround(True)
- self.back_group = pygame.sprite.Group(bg_one, bg_two)
- # 创建敌机精灵组
- self.enemy_group = pygame.sprite.Group()
- # 创建主机精灵组
- self.me = plane_sprites.Me()
- self.me_group = pygame.sprite.Group(self.me)
- # 创建敌机子弹摧毁精灵组
- self.destroy_group = pygame.sprite.Group()
-
- def __event__handler(self):
- """
- 事件监听
- :return:
- """
- for e in pygame.event.get():
- # 点击关闭游戏窗口
- if e.type == pygame.QUIT:
- # 退出pygame
- pygame.quit()
- # 终止程序
- exit()
- elif e.type == pygame.USEREVENT:
- # 添加敌机精灵到精灵组中
- self.enemy = plane_sprites.Enemy()
- self.enemy_group.add(self.enemy)
- elif e.type == pygame.USEREVENT + 1:
- self.me.me_bullet()
-
- # 获取所有按键的元组
- keys_pressed = pygame.key.get_pressed()
- # 主机左右移动
- if keys_pressed[pygame.K_RIGHT]:
- self.me_group.update(True, False)
- elif keys_pressed[pygame.K_LEFT]:
- self.me_group.update(True, True)
-
- def __check_collide(self):
- """
- 碰撞检测
- :return:
- """
- # 主机被毁
- if self.me.state == 4:
- # 游戏结束
- self.__game_over()
-
- # 检测子弹与敌机碰撞(敌机先不销毁,注意!顺序必须是敌机在前,否则下面for循环拿不到explode_index)
- d_group = pygame.sprite.groupcollide(self.enemy_group, self.me.bullet_group, False, True)
- # 将碰撞敌机精灵添加到敌机子弹摧毁精灵组
- self.destroy_group.add(d_group)
- for enemy in self.destroy_group:
- # 爆炸状态为0 代表未摧毁,此处改为1待摧毁
- if enemy.enemy_explode_index == 0:
- enemy.enemy_explode_index = 1
- # 摧毁完毕后删除精灵
- elif enemy.enemy_explode_index == 5:
- self.destroy_group.remove_internal(enemy)
- self.enemy_group.remove_internal(enemy)
-
- # 检测主机与敌机碰撞
- d_me = pygame.sprite.spritecollide(self.me, self.enemy_group, True)
- if len(d_me) > 0:
- # 主机爆炸
- self.me.state = 3
-
- def __update_sprites(self):
- """
- 更新/绘制精灵组
- :return:
- """
- # 背景精灵组更新
- self.back_group.update()
- self.back_group.draw(self.screen)
- # 敌机精灵组更新
- self.enemy_group.update()
- self.enemy_group.draw(self.screen)
- # 主机精灵组更新
- self.me_group.update()
- self.me_group.draw(self.screen)
- # 子弹精灵组更新
- self.me.bullet_group.update()
- self.me.bullet_group.draw(self.screen)
-
- @staticmethod
- def __game_over():
- """
- 游戏结束
- :return:
- """
- pygame.quit()
- exit()
-
-
- if __name__ == '__main__':
- # 创建游戏对象
- game = PlanGame()
- # 启动游戏
- game.start_game()
plane_sprites.py(精灵类)
- import random
-
- import pygame.sprite
-
- # 窗口大小 480像素 * 700像素
- SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
- # 刷新的帧频
- FRAME_PER_SEC = 60
-
-
- class GameSprite(pygame.sprite.Sprite):
- """飞机大战-精灵类"""
-
- def __init__(self, image_url, speed=1):
- """
- 初始化
- :param image_url: 图片路径
- :param speed: 移动频率(默认1)
- """
- # 使用super调用父类初始化(继续类不是Object,则需要调用)
- super().__init__()
- # 绘制图片
- self.image = pygame.image.load(image_url)
- # 获取坐标、宽高
- 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):
- """
- 背景图片初始化
- """
- super().__init__("./images/background.png")
- # 定义图片y值
- if is_alt:
- self.rect.y = self.rect.height
-
- def update(self):
- """
- 更新图片位置
- """
- super().update()
- # 背景图片大于屏幕高度则赋值当前窗口高度的负数值
- if self.rect.y >= SCREEN_RECT.height:
- self.rect.y = -self.rect.height
-
-
- class Enemy(GameSprite):
- """飞机大战-敌机类"""
-
- def __init__(self):
- """
- 敌机初始化
- """
- super().__init__("./images/enemy1.png")
- # 指定敌机的随机速度
- self.speed = random.randint(1, 3)
- # 指定敌机的随机位置(窗口宽度-敌机宽度)
- self.rect.bottom = 0
- self.rect.x = random.randint(0, SCREEN_RECT.width - self.rect.width)
- # 敌机爆炸状态 0:未摧毁 1:待摧毁 1-4:摧毁中 5:已摧毁
- self.enemy_explode_index = 0
-
- def update(self):
- """
- 更新敌机位置
- """
- super().update()
- # 敌机大于当前窗口高度时从精灵组里删除敌机
- if self.rect.y > SCREEN_RECT.height:
- self.kill()
- # 已销毁敌机
- if self.enemy_explode_index == 5:
- return
- # 敌机爆炸
- if self.enemy_explode_index != 0:
- new_rect = self.rect
- super().__init__("./images/enemy1_down%d.png" % self.enemy_explode_index)
- self.enemy_explode_index += 1
- self.rect = new_rect
-
-
- class Me(GameSprite):
- """飞机大战-主机类"""
-
- def __init__(self):
- """
- 主机初始化
- """
- super().__init__("./images/me1.png", 0)
- # 指定主机的x轴中心位置
- self.rect.centerx = SCREEN_RECT.centerx
- # 指定主机的位置y轴位置(窗口宽度-敌机宽度-50)
- self.rect.y = SCREEN_RECT.height - self.rect.height - 50
- # 创建子弹精灵组
- self.bullet_group = pygame.sprite.Group()
- # 主机爆炸状态 1:喷气 2:不喷气 3:摧毁 4:已摧毁
- self.state = 1
- # 主机爆炸进度 1-4
- self.progress = 1
-
- def update(self, is_move=False, is_left=False):
- """
- 更新主机位置
- :param is_move: 是否移动
- :param is_left: 是否左移动
- :return:
- """
- # 获取上个精灵的位置
- new_rect = self.rect
- # 喷气和不喷气相互切换
- if self.state == 1:
- super().__init__("./images/me2.png")
- self.state = 2
- elif self.state == 2:
- super().__init__("./images/me1.png")
- self.state = 1
- # 主机被摧毁
- else:
- super().__init__("./images/me_destroy_%d.png" % self.progress)
- self.rect = new_rect
- # 主机已被摧毁
- if self.progress != 4:
- self.progress += 1
- else:
- self.state = 4
- return
- # 将上个精灵的位置赋值到新的精灵上
- self.rect = new_rect
- if not is_move:
- return
- # 左右移动
- if is_left and self.rect.x > 0:
- self.rect.x -= 2
- elif not is_left and self.rect.right < SCREEN_RECT.width:
- self.rect.x += 2
-
- def me_bullet(self):
- """
- 主机添加子弹
- :return:
- """
- for i in range(0, 3):
- # 添加子弹精灵到精灵组中
- bullet = Bullet()
- # 子弹x+y轴位置
- bullet.rect.y = self.rect.y - i * 20
- bullet.rect.x = self.rect.centerx
- # 将子弹精灵添加到精灵组中
- self.bullet_group.add(bullet)
-
-
- class Bullet(GameSprite):
- """飞机大战-子弹类"""
-
- def __init__(self):
- """
- 子弹初始化
- """
- super().__init__("./images/bullet2.png", -2)
-
- def update(self):
- """
- 发射子弹
- :return:
- """
- super().update()
- # 子弹y轴高度小于等于0时从精灵组里删除
- if self.rect.y <= 0:
- self.kill()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。