飞机大战

飞机大战

最近想试试pyinstaller,那么就要搞个小程序,然后想了下,之前学python的还有个飞机大战的例子没弄,那就用它来试试打包了
借鉴博主链接,里面有需要的图片 飞机大战

基本功能

(1)多方向移动 例如左上 右下等

看博客的时候发现部分的同一时刻只弄一个方向,看评论的时候会发现有些人会问,其实的话多个if就行

(2)攻击

思路就是获取事件类型,键盘按压的key的判断,本例空格攻击

(3) 分数显示

每挂掉一个就Enemy.dead+1,主程序循环的时候不断获取该值,不断刷新渲染,然后字体的话需要去C盘下面的fonts文件获取 .ttf,在代码中改成相对应的文件路径

fontobj = pygame.font.Font('./times.ttf', 25)	

效果图

左上角杀敌数量

全部代码两个文件

文件1

mod.py

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 Gamesprit(pygame.sprite.Sprite):
    def __init__(self, img, speed=1):
        super(Gamesprit, self).__init__()
        self.image = pygame.image.load(img)
        self.rect = self.image.get_rect()
        self.speed = speed

    def update(self, *args):
        self.rect.y += self.speed


class Back(Gamesprit):
    def __init__(self, is_alt=False):
        super().__init__('./back.png')
        if is_alt:  # 此参数是构造一个隐藏的背景
            self.rect.y = -self.rect.height

    def update(self, *args):
        super().update()  # 背景移动
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -self.rect.height  # 一个背景跑完,立马上移形成循环播放


class Enemy(Gamesprit):
    dead = 0

    def __init__(self):
        super().__init__('./enemy.png')
        self.speed = random.randint(0, 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):
        super().update()
        if self.rect.y >= SCREEN_RECT.height:  # 敌机出界
            self.kill()  # 销毁


class Bullet(Gamesprit):
    def __init__(self):
        super().__init__('./bullet.png')
        self.speed = -2

    def update(self, *args):
        super().update()
        if self.rect.bottom < 0:  # 子弹出界
            self.kill()


class Hero(Gamesprit):
    def __init__(self):
        super().__init__('hero.png', 2)
        # 飞船初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom

        self.bullets = pygame.sprite.Group()  # 容器装子弹对象

    def update(self, up=False, down=False, left=False, right=False):
        if up:  # 多个if是为了能同时进多方向移动 例如左上
            self.rect.y -= self.speed
            if self.rect.y < 0:  # 下面的每个子if都是为了防止出界
                self.rect.y = 0
        elif down:
            self.rect.y += self.speed
            if self.rect.bottom > SCREEN_RECT.bottom:
                self.rect.bottom = SCREEN_RECT.bottom
        elif left:
            self.rect.x -= self.speed
            if self.rect.left < 0:
                self.rect.left = 0
        elif right:
            self.rect.x += self.speed
            if self.rect.right > SCREEN_RECT.right:
                self.rect.right = SCREEN_RECT.right

    def fire(self):
        # 生成子弹 开火
        bullet = Bullet()
        bullet.rect.bottom = self.rect.y
        bullet.rect.centerx = self.rect.centerx
        self.bullets.add(bullet)
文件2

new_plane.py

import pygame

from mod import SCREEN_RECT, Back, Hero, FRAME_PER_SEC, CREATE_ENEMY_EVENT, Enemy, HERO_FIRE_EVENT

SCORE = pygame.USEREVENT+2
pygame.init()


class Text_score(object):
    """
    分数机制
    """
    fontobj = pygame.font.Font('./times.ttf', 25)

    @staticmethod
    def get_dead_text():
        dead = Enemy.dead
        text = Text_score.fontobj.render('you have kill:'+str(dead), True, (255, 255, 255))
        textrect = text.get_rect()
        return text, textrect


class Play_game(object):
    def __init__(self):

        pygame.display.set_caption('飞机大战')  # 标题
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)
        self.clock = pygame.time.Clock()  # 时钟对象 控制循环频率
        pygame.display.update()
        self._create()
        pygame.time.set_timer(CREATE_ENEMY_EVENT, 1000)  # 重复创建事件 这个每隔1000ms创建敌机
        pygame.time.set_timer(SCORE,1)

    def _create(self):
        back1 = Back()  # 初始后让你第一眼看到的背景
        back2 = Back(True)  # 初始后背景图的上方 被隐藏了看不到
        self.back_group = pygame.sprite.Group(back1, back2)
        self.enemies = pygame.sprite.Group()
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)

    def _event_handle(self):
        for evt in pygame.event.get():  # 事件检测
            if evt.type == pygame.QUIT:  # 退出
                Play_game._exit_game()
            elif evt.type == CREATE_ENEMY_EVENT:  # 与上面的set_timer对 然后创建一个敌机对象
                enemy = Enemy()
                self.enemies.add(enemy)
            elif evt.type == pygame.KEYDOWN:  # 检测键盘按压
                if evt.key == pygame.K_SPACE:  # 按键为空格
                    self.hero.fire()  # fire
                elif evt.key == pygame.K_ESCAPE:  # esc 退出游戏
                    Play_game._exit_game()
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_RIGHT]:
            self.hero.update(right=True)
        if keys_pressed[pygame.K_LEFT]:
            self.hero.update(left=True)
        if keys_pressed[pygame.K_UP]:
            self.hero.update(up=True)
        if keys_pressed[pygame.K_DOWN]:
            self.hero.update(down=True)

    def collision(self):
        res = pygame.sprite.groupcollide(self.hero.bullets, self.enemies, True, True)  # 检测碰撞 碰撞的话两个都消灭
        if res:
            Enemy.dead += 1
        collide_enemies = pygame.sprite.spritecollide(self.hero, self.enemies, True)  # 单个精灵与一组精灵的碰撞 返回被碰到的精灵的list
        if len(collide_enemies):  # 返回的list不为空的话 证明碰撞 游戏结束
            self.hero.kill()
            Play_game._exit_game()

    def _update(self):  # 一起更新 每个group的update它会自动调用其中每个精灵的update
        self.back_group.update()
        self.back_group.draw(self.screen)

        # self.hero_group.update()
        self.hero_group.draw(self.screen)

        self.enemies.update()
        self.enemies.draw(self.screen)

        self.hero.bullets.update()
        self.hero.bullets.draw(self.screen)

    def start_game(self):
        while True:
            self.clock.tick(FRAME_PER_SEC)
            self._event_handle()
            self.collision()
            self._update()
            text, rect = Text_score.get_dead_text()  # 分数获取
            self.screen.blit(text, rect)  # 分数渲染
            pygame.display.update()

    @staticmethod
    def _exit_game():
        pygame.quit()
        exit()


if __name__=="__main__":
    play=Play_game()
    play.start_game()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值