飞机大战【python】

飞机大战

需要模块pygame
环境python3.9 pycharm

代码的使用
  • 下载image中的所有图片,没有用到的可以做后续更改

  • 两个代码和images文件夹放在同一目录下

  • 将最上方.py文件命名为plane_sprites

  • 运行最下方的代码

代码细节
  • 建立精灵组,创建类后继承父类pygame.sprite.Sprite中的方法
  • 封装图像,位置,速度
  • super()._init() 继承父类的初始化
  • 重写父类中的update方法
import random
import pygame

#设置一个屏幕大小的常量
SCREEN_RECT = pygame.Rect(0,0,480,700)
#刷新的帧率
FRAME_PER_SEC = 60
#创建敌机的定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
#英雄发射子弹事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1

class GameSprite(pygame.sprite.Sprite):
    """飞机精灵"""
    def __init__(self,image_name,speed=1):    #封装图像,位置,速度
        super().__init__()
        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):
    def update(self):
        # 1.调用父类的方法实现
        super().update()
        # 2.判断是否移出屏幕,如果移出屏幕,将图像设置到屏幕上方
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -self.rect.height


class Enemy(GameSprite):
    """敌机精灵"""
    def __init__(self):
        #调用父类方法,创建敌机精灵,同时指定敌机图片
        super().__init__("./images/enemy1.png")
        #2.指定低级的初始随即速度

        self.speed = random.randint(1,3)

        #3.指定敌机的初始随机位置(设置y方向的初始位置)
        self.rect.bottom = 0

        max_x = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0,max_x)
    def update(self):
        # 1.调用父类方法保持垂直方向的飞行
        super().update()
        # 2.判断是否飞出屏幕,如果是,需要从精灵组删除敌机
        if self.rect.y >= SCREEN_RECT.height:
            print("飞出屏幕需要删除")
            self.kill()
    def __del__(self):
        print("敌机再%s位置被销毁"%(self.rect))


class Hero(GameSprite):
    """英雄精灵"""
    def __init__(self):
        super(Hero, self).__init__("./images./me1.png")
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 120
        #创建子弹的精灵组
        self.bullets = pygame.sprite.Group()
    def update(self):
        # 英雄在水平方向移动
        self.rect.x += self.speed
        #控制英雄不能移开屏幕
        if self.rect.x < 0:
            self.rect.x = 0
        elif self.rect.right > SCREEN_RECT.right:
            self.rect.right = SCREEN_RECT.right

    def fire(self):
        print("发射子弹")
        for i in (0,1,2):
            # 创建子弹精灵
            bullet = Bullet()

            bullet.rect.bottom = self.rect.y - i * 20
            bullet.rect.centerx = self.rect.centerx

            self.bullets.add(bullet)


class Bullet(GameSprite):
    """子弹精灵"""
    def __init__(self):
        super(Bullet, self).__init__("./images/bullet1.png",-2)

    def update(self):
        super(Bullet, self).update()
        #判断子弹是否飞离屏幕
        if self.rect.bottom < 0:
            self.kill()
  • 加载对象初始化
    • 建立屏幕大小 screen = pygame.display.set_mode((480,700))
    • 加载图片 bg = pygame.image.load("./images/background.png")
    • 用 screen.blit(bg,(0,0)) 方法控制图像加载完后的位置
    • 用pygame.rect(x,y,width,heigth)来初始化图像位置
    • 创建精灵和精灵组
      • 每一个图像都是一个ji
  • 进入游戏循环
    • 设立帧数
      • pygame.time.Clock()方法中的 tick(帧数)
    • 用rect方法来控制图像的移动
    • 然后重新显示图像加载完成后的位置
    • 用pygame.display.update的方法来更新画面
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()

        #4.设置定时器事件 - 创建敌机 ls
        pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)

        #5.创建定时器事件 -英雄发射子弹
        pygame.time.set_timer(HERO_FIRE_EVENT,500)

    def __create_sprites(self):
        """创建精灵"""
        bg1 = Background("./images/background.png")
        bg2 = Background("./images/background.png")
        bg2.rect.y = -bg2.rect.height
        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()
            # 更新显示
            pygame.display.update()

    def __event_handler(self):
        """事件监听"""
        for event in pygame.event.get():	#用ptgame.event.get()方法来捕获事件
            if event.type == pygame.QUIT:	#点击关闭后退出游戏
                self.__game_over()
            elif event.type == CREATE_ENEMY_EVENT:	#捕获事件如果时定时器变量
                # print("敌机出场...")
                #创建敌机精灵
                enemy = Enemy()
                #将敌机添加到敌机精灵组
                self.enemy_group.add(enemy)
            elif event.type == HERO_FIRE_EVENT:
                self.hero.fire()

            # elif event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            #     print("向右移动")

        # 使用键盘提供的方法获取键盘按键 - 按键元组
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_RIGHT]:
            self.hero.speed = 2
        elif keys_pressed[pygame.K_LEFT]:
            self.hero.speed = -2

    def __check_collide(self):
        pygame.sprite.groupcollide(self.hero.bullets,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()

        pass

    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)
    @staticmethod
    def __game_over():
        print("游戏结束")
        pygame.quit()
        exit()



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、付费专栏及课程。

余额充值