Python飞机大战

一、项目准备

在开发游戏前,我们需要安装一个pygame模块

  • pygame 就是一个 Python 模块,专为电子游戏设计

安装pygame

sudo pip3 install pygame

验证安装

python3 -m pygame.examples.aliens

二、文件职责

首先我们需要两个文件编写代码 plane_main 和 plane_sprites

  • plane_main
    1. 封装 主游戏类
    2. 创建 游戏对象
    3. 启动游戏
  • plane_sprites
    1.封装游戏中 所有 需要使用的 精灵子类
    2.提供游戏的 相关工具

三、搭建游戏框架

第一部分----游戏初始化

  • 设置游戏窗口
  • 创建游戏时钟
  • 创建精灵、精灵组

第二部分----游戏循环

  • 设置刷新帧率
  • 事件监听
  • 碰撞检测
  • 更新精灵组
  • 更新屏幕显示

四、代码整理1----在plane_main游戏主程序中

  • 导入模块
#导入Python本身提供的pygame模块
import pygame
#导入精灵文件Plan_sprites模块
from PlanSprite import *
  • 创建一个类
#运用面向对象思想创建主游戏类
class PlaneGame(object):
  • 游戏初始化
#初始化方法
def __init__(self):
    #创建游戏窗口
    self.screen = pygame.display.set_mode(SCREEN_RECT.size) 
    #创建游戏时钟
    self.clock = pygame.time.Clock()
    #创建精灵组
    self.__create_sprites()
    #得分显示,(默认为0)
    self.wanjia = 0
    #定时器 毫秒  第一个参数是事件的名字  第二个参数是多长时间执行一次时间
    pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)
  • 创建精灵组
def __create_sprites(self):
    #背景精灵组
    bg1 = Background()
    bg2 = Background(True)
    self.back_group = pygame.sprite.Group(bg1,bg2)
    #敌机的精灵组
    self.enemy_group = pygame.sprite.Group()
    #英雄的精灵组
    self.hero = Hero()
    self.hero_group = pygame.sprite.Group(self.hero)
  • 游戏循环部分
def start_game(self):
    print("游戏开始...")
    while  True:
        #设置帧率
        self.clock.tick(FRAME_PER_SEC)
        #事件监听
        self.__event_handler()
        #碰撞检测
        self.__check_collide()
        #更新精灵和精灵组
        self.__update_sprites()
        #分数
        self.__print_score()
        #更新显示
        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 = Enemy()
            self.enemy_group.add(enemy)
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: #子弹定时器事件
            self.hero.fire()
  • 碰撞检测
def __check_collide(self):
    # 1. 子弹摧毁敌机
    if pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True):
        self.wanjia +=2

    # 2. 敌机撞毁英雄
    enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True) 

    # 判断列表时候有内容
    if len(enemies) > 0: 

        # 让英雄牺牲
        self.hero.kill()
        print("英雄牺牲")

        # 结束游戏
        PlaneGame.__game_over()
        print("游戏结束")
  • 更新精灵组
def __update_sprites(self):
    #更新背景精灵组
    self.back_group.update()
    self.back_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)
  • 打印分数
def __print_score(self):
    pygame.font.init()
    #位置
    pos = (20,0)
    #颜色
    color = (255,255,255)
    #显示内容
    text = "score:" + str(self.wanjia)
    #字体
    cur_font = pygame.font.SysFont("楷体",30)
    text_fort = cur_font.render(text,1,color)
    self.screen.blit(text_fort,pos)
  • 结束游戏
#退出游戏
@staticmethod       
def __game_over():
    #卸载所有 pygame 模块
    pygame.quit
    #python本身提供的退出脚本的功能
    exit()
  • 调用主函数
if __name__ == '__main__':
    #创建游戏对象
    game = PlaneGame()
    #开始游戏
    game.start_game()       

五、代码整理2----在plane_sprites游戏精灵中

#导入随机包
import random
#导入pygame模块
import pygame
#设置游戏屏幕大小
SCREEN_RECT = pygame.Rect(0,0,480,700)
#刷新帧率
FRAME_PER_SEC = 60
#敌机事件的常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
  • 创建游戏精灵的基础类
 class GameSprite(pygame.sprite.Sprite):
    #给基础类的速度设置一个默认值为1
    def __init__(self,image_name,speed=1):
        #继承父类的初始化
        super().__init__()
        #pygame.image.load(pygame提供的方法) 加载图片
        self.image = pygame.image.load(image_name)
        #设置尺寸
        self.rect = self.image.get_rect()
        #记录速度
        self.speed = speed

    #每次更新屏幕时在游戏循环内调用
    def update(self):
        #默认在垂直方向移动
        self.rect.y += self.speed   
  • 创建背景精灵类
class Background(GameSprite):

    #is_alt判断是否为另外一张图像(False表示第一张图像 True表示另外一张图像)
    def __init__(self,is_alt=False):
        #传入背景图片
        image_name = "./images/timg.jpeg"
        super().__init__(image_name)
        #如果是另一张图像,讲图片设置到屏幕顶部
        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):
        #传入敌机图片
        image_name = "./images/enemy-1.gif"
        super().__init__(image_name)
        #设置敌机的随机初始速度
        self.speed = random.randint(1,3)
        #敌机x轴最大值 需要用屏幕的宽度-敌机自身的宽度

        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0,max_x)#随机位置
        self.rect.bottom = 0 #敌机底部位置

    def update(self):
        super().update()
        #判断是否飞出屏幕,如果是,需要将敌机从精灵组删除
        if self.rect.y >= SCREEN_RECT.height: 
            self.kill()
            print("敌机飞出屏幕...")
    #删除敌机后打印(可忽略)
    def __del__(self): 
        print("敌机挂了 %s" % self.rect) 
  • 创建英雄精灵类
class Hero(GameSprite):
    def __init__(self):
        #传入玩家飞机图片
        image_name = "./images/plane.png"
        super().__init__(image_name,0)
        #设置初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 80
        #创建子弹精灵组
        self.bullets = pygame.sprite.Group()

        self.speed1 = 0


    def update(self):
        #key.get_pressed(pygame提供的方法)设置按键
        keys_pressed = pygame.key.get_pressed()
        
        if keys_pressed[pygame.K_RIGHT]:
            self.rect.x += 10
        elif keys_pressed[pygame.K_LEFT]:
            self.rect.x -= 10
        elif keys_pressed[pygame.K_UP]:
            self.rect.y -= 10
        elif keys_pressed[pygame.K_DOWN]:
            self.rect.y += 10
        if keys_pressed[pygame.K_c]:
            self.fire()
        

        # 判断屏幕边界
        if self.rect.left < 0: 
            self.rect.left = 0 
        elif self.rect.right > SCREEN_RECT.right: 
            self.rect.right = SCREEN_RECT.right
        elif self.rect.top < 0:
            self.rect.top = 0
        elif self.rect.bottom > SCREEN_RECT.bottom:
            self.rect.bottom = SCREEN_RECT.bottom

    #发射子弹
    def fire(self):
        bullet = Bullet()
        bullet1 = Bullet()
        bullet2 = Bullet()
        #子弹发射位置
        bullet.rect.bottom = self.rect.y -30
        bullet.rect.centerx = self.rect.centerx
        bullet1.rect.bottom = self.rect.y -20
        bullet1.rect.centerx = self.rect.centerx + 15
        bullet2.rect.bottom = self.rect.y -20
        bullet2.rect.centerx = self.rect.centerx - 15
        #将子弹添加到精灵组
        self.bullets.add(bullet,bullet1,bullet2)
  • 创建子弹精灵
class Bullet(GameSprite):
    def __init__(self):
        #传入子弹图片
        image_name = './images/bullet1.png'
        super().__init__(image_name,-10)

    #判断子弹超出屏幕后删除
    def update(self):
        super().update()    
        if self.rect.bottom < 0:
            self.kill() 

你可能感兴趣的:(Python飞机大战)