飞机大战项目

飞机大战

使用pygame进行游戏开发

安装pygame

  • “win”+R:输入cmd,打开黑窗口
  • 输入:pip install pygame
  • 验证安装:python -m pygame.examples.aliens

所遇问题
打开pycharm,输入import pygame可能会遇到的问题:

ModuleNotFoundError: No module named 'pygame'

解决方法(这里只说我自己遇到的问题啦):
看pycharm中输入import pygame所在文件是否与pygame安装环境匹配。
我最初把pygame安装到了base环境中,而写入的文件时pt环境,那如何进入pt环境:cmd中输入:activate pt 后再安装一次pygame,解决了上述问题。

在这里插入图片描述

飞机大战写成两个文件

两个文件
plane_sprites.py文件:封装游戏精灵文件
plane_main.py文件:游戏主程序(封装游戏主类,创建游戏对象,启动游戏)

代码展示

  1. plane_sprites.py文件
 import pygame
import random
# 封装的游戏精灵文件
# 1.背景图片的尺寸
SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
# 2.创建敌机的事件id、用户事件id
CREATE_ENEMY_EVENT = pygame.USEREVENT
HERO_FIRE_EVENT = pygame.USEREVENT + 1
# 游戏精灵
class Gamesprites(pygame.sprite.Sprite):
    # 初始化方法
    def __init__(self, image_name, speed = 1):
        # 必须调用父类的init方法
        super().__init__()
        # 1.精灵的图片
        self.image = pygame.image .load(image_name)
        # 2.精灵的尺寸
        self.rect = self.image.get_rect()
        # 3.记录速度
        self.speed = speed
    def update(self, *args):
        self.rect.y += self.speed
# 二.背景精灵
# 背景精灵,基础GameSprites
# 背景精灵有两张图片,first:(00; second:(0-自身高度)
# 循环动画
class BackgroundSprites(Gamesprites):
    def update(self, *args):
        super().update()
        # 循环动画,使图片连续播放:判断图片位置,若>=自身高度(700,重新从-700开始
        if self.rect.y >= self.rect.height:
            self.rect.y = -self.rect.height

class Enemy(Gamesprites):
    def __init__(self):
        # 1.指定敌机的图片
        super().__init__("../images/enemy1.png")
        # 2.设置随机的初始速度
        self.speed = random.randint(1, 3)
        # 3.设置随机的初始位置
        self.rect.bottom = 0
        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0, max_x)
    def update(self, *args):
        # 1.调用父类,让敌机可以垂直移动
        super().update()
        # 2.如果敌机飞出屏幕,从精灵组删除
        if self.rect.y >= SCREEN_RECT.height:
            # print("敌机飞出屏幕...")
            self.kill()
    # 重写del方法,打印敌机销毁
    def __del__(self):
        print(f"本机挂了,{self.rect}")

class Hero(Gamesprites):
    def __init__(self):
        # 战机图片
        super().__init__("../images/me1.png")
        # 初始位置:水平居中,垂直方向距离底部120
        self.rect.centerx = SCREEN_RECT.centerx
        # self.rect.y = SCREEN_RECT.height - self.rect.height - 120
        self.rect.bottom = SCREEN_RECT.bottom - 120
        # 飞机的上下键移动方向:1(水平),2(垂直)
        self.direction = 1
        # 子弹精灵组
        self.bullet_group = pygame.sprite.Group()
    def update(self, *args):
        if self.direction == 1:
            self.rect.x += self.speed
        # 定义飞机左右范围:坐标原点在左上角,self.rect.left是y坐标轴,而右边是无限大,选取SCREEN.RECT.right
            if self.rect.left < 0:
                self.rect.left = 0
            elif self.rect.right > SCREEN_RECT.right:
                self.rect.right = SCREEN_RECT.right
        else:
            super().update()
            if self.rect.y < 0:
                  self.rect.y = 0
            elif self.rect.bottom > SCREEN_RECT.bottom:
                  self.rect.bottom = SCREEN_RECT.bottom
    def fire(self):
        print("发射子弹...")
        for i in (1, 2, 3, 4):
            # 创建子弹精灵
            bullet = Bullet()
            # 子弹的位置:水平在飞机中间,垂直在飞机头部+20
            bullet.rect.centerx = self.rect.centerx
            bullet.rect.bottom = self.rect.top - 15*i
            self.bullet_group.add(bullet)


# 子弹类
class Bullet(Gamesprites):
    def __init__(self):
        super().__init__("../images/bullet2.png", -2)
    def update(self, *args):
        super().update()
        if self.rect.y <= 0:
            self.kill()
  1. plane_main.py文件
import pygame
from plane_sprites import*
# 游戏主程序
# 1.封装游戏主类
# 2.创建  游戏对象
# 3.启动游戏
class PlaneGame(object):
    # 1.初始化方法
    def __init__(self):
        print("游戏初始化")
        pygame.init()
        # (1)创建游戏窗口
        # self.screen = pygame.display.set_mode((480, 700))
        # size返回矩形区域的宽高,以元组形式返回
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        # (2)设置游戏时钟
        self.clock = pygame.time.Clock()
        # (3)调用创建精灵和精灵组的方法
        self.__creat_sprites()

        # 需求:通过定时器,每隔1s添加一架敌机
        # pygame.time.set_timer(事件id, 间隔时间单位ms)
        pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)
        pygame.time.set_timer(HERO_FIRE_EVENT, 400)
        # 1.1  私有方法:创建精灵,创建精灵组
    def __creat_sprites(self):
        # (1)背景组
        # 背景精灵
        bg1 = BackgroundSprites("../images/background.png")
        bg2 = BackgroundSprites("../images/background.png")
        # 第二张图片的位置是负的自身高度
        bg2.rect.y = -bg2.rect.height
        self.back_group = pygame.sprite.Group(bg1, bg2)
        # (2)敌机组
        self.enemy_group = pygame.sprite.Group()
        # (3)英雄组
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)

    # 2. 开始游戏
    def start_game(self):
        print("开始游戏")
        while True:
            # (0).设置刷新帧率60
            self.clock.tick(60)
            # (1)事件监听
            self.__event_handler()
            # (2)碰撞检测
            self.__check_collide()
            # (3)更新精灵
            self.__update_sprites()
            # (4)更新屏幕
            pygame.display.update()
    # 2.1  事件监听
    def __event_handler(self):
        even_list = pygame.event.get()
        for event in even_list:
            if event.type == pygame.QUIT:
                self.__game_over()
            elif event.type == CREATE_ENEMY_EVENT:
                print("敌机出场...")
                # 给敌机组添加敌机
                self.enemy_group.add(Enemy())
            # 移动英雄的位置
            # 方式一:event.type用户必须抬起按键才算一次,操作灵活性不高
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
                print("按下右键")
                self.hero.speed = 3
                self.hero.direction = 1
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
                print("按下左键")
                self.hero.speed = -3
                self.hero.direction = 1
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
                print("按下上键")
                self.hero.speed = -3
                self.hero.direction = 2
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
                print("按下下键")
                self.hero.speed = 3
                self.hero.direction = 2
            elif event.type == HERO_FIRE_EVENT:
                self.hero.fire()
            else:
                self.hero.speed = 0
            # 方式二:用户按住方向键不放,就能实现持续向某个方向移动,操作灵活性高
            # keys_pressed = pygame.key.get_pressed()  # 写在for循环外
            # elif keys_pressed[pygame.K_RIGHT]:
            #     self.hero.speed = 2
            # elif keys_pressed[pygame.K_LEFT]:
            #     self.hero.speed = -2
            # else:
            #     self.hero.speed = 0

    # 2.2 碰撞检测(子弹销毁敌机,敌机销毁英雄)
    def __check_collide(self):
        # 子弹摧毁敌机
        pygame.sprite.groupcollide(self.hero.bullet_group, self.enemy_group, True, True)
        # 敌机撞毁英雄
        enemies = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        # 判断列表时候有内容
        if len(enemies) > 0:
            # 让英雄牺牲
            self.hero.kill()
            # 结束游戏
            self.__game_over()
    # 2.3  精灵组更新和绘制
    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)
        # 优化方法:将各个组放入列表中。然后循环调用updata、draw
        for group in [self.back_group, self.enemy_group, self.hero_group, self.hero.bullet_group]:
            # 更新
            group.update()
            # 绘制
            group.draw(self.screen)


    # 2.4 游戏结束
    def __game_over(self):
        print("点击了右上角的按钮,退出游戏")
        # 退出游戏
        pygame.quit()
        # 停止程序的运行
        exit()
# 以下没有缩进,不是PlaneGame类的代码
if __name__ == "__main__":
    game = PlaneGame()
    game.start_game()

欢迎各位大佬提出问题!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值