pygame-雷霆战机

 

1、主程序  plane_main.py

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()

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

        # 设置定时器事件,设置英雄自动开火,间隔1秒
        pygame.time.set_timer(HERO_FIRE_EVENT, 1500)

    def start_game(self):
        print("游戏开始")
        while True:
            # 设置刷新帧率
            self.clock.tick(FRAME_PER_SECOND)
            # 事件监听
            self.__event_handler()
            # 碰撞检测
            self.__check_collide()
            # 更新/绘制精灵组
            self.__update_sprites()
            # 更新显示
            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_sp = Enemy()
                self.enemy_group.add(enemy_sp)
            elif event.type == HERO_FIRE_EVENT:
                self.hero.fire()

        # 使用键盘提供的方法监听键盘事件,案件按下,值为1,返回的是元组
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_RIGHT]:
            # 向右移动,坐标值增加
            if self.hero.rect.right >= SCREEN_RECT.width:
                self.hero.speed = 0
            else:
                self.hero.speed = 2
        elif keys_pressed[pygame.K_LEFT]:
            if self.hero.rect.left <= 0:
                self.hero.speed = 0
            else:
                self.hero.speed = -2
        else:
            self.hero.speed = 0

    def __check_collide(self):
        # 子弹摧毁敌机
        pygame.sprite.groupcollide(self.hero.bullets, self.enemy_group, True, True)
        # 英雄与精灵组任意精灵碰撞,精灵被摧毁,英雄不会被摧毁
        clollide_enemys = pygame.sprite.spritecollide(self.hero, self.enemy_group, True)
        # 判断英雄碰撞的敌机数量,大于1,英雄需要被清除
        if len(clollide_enemys) > 0:
            self.hero.kill()
            PlaneGame.__game_over()


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

    def __create_sprites(self):
        print("创建精灵组")
        # 创建背景和背景组
        bg1 = Background()
        bg2 = Background(is_alter=True)
        self.bg_group = pygame.sprite.Group(bg1, bg2)

        # 创建敌机精灵组
        self.enemy_group = pygame.sprite.Group()

        # 创建英雄和英雄组,hero其他方法要使用,所以定义为属性
        self.hero = Hero()
        self.hero_group = pygame.sprite.Group(self.hero)

    def __update_sprites(self):
        # 更新背景组
        self.bg_group.update()
        self.bg_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)


if __name__ == "__main__":
    # 创建游戏对象
    game = PlaneGame()
    game.start_game()

 

2、精灵工具

import random
import pygame

# 定义以西窗口其实坐标位0,0 窗口宽度和高度
SCREEN_RECT = pygame.Rect(0, 0, 450, 700)
# 刷新帧率,每秒60帧
FRAME_PER_SECOND = 60
# 创建敌机的定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT

# 创建英雄开火事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1


class GameSprite(pygame.sprite.Sprite):
    def __init__(self, image_para, speed_para=1):
        # 父类不是object时都需要调用父类初始化方法
        super().__init__()
        self.image = pygame.image.load(image_para)
        self.rect = self.image.get_rect()
        self.speed = speed_para

    def update(self):
        # 精灵父类update,设置飞行为垂直方向飞行
        self.rect.y += self.speed


class Background(GameSprite):

    def __init__(self, is_alter=False):
        super().__init__("./images/bg.jpg")
        # 如果时替换的背景
        if is_alter:
            # bg2 初始位置要设置在窗口上方
            self.rect.y = -self.rect.height

    def update(self):
        # 调用父类的update方法,向下移动
        super().update()
        # 如果背景图片向下移出窗口,y坐标=700
        if self.rect.y > SCREEN_RECT.height:
            self.rect.y = -SCREEN_RECT.height


class Enemy(GameSprite):
    def __init__(self):
        # 调用父类方法,创建敌机,加载敌机图片
        super().__init__("./images/enemy1.png")

        # 指定敌机初始位置是在窗口正上方
        # self.rect.y = -SCREEN_RECT.height 等价于下面的语句
        self.rect.bottom = 0
        # 指定敌机的初始随机速度,敌机速度要大于 否则跟背景速度一样,会显示静止
        self.speed = random.randint(2, 3)

        # 指定敌机的初始随机位置
        self.rect.x = random.randint(0, SCREEN_RECT.width-self.rect.width)

    def update(self):
        # 调用父类方法,实现垂直向下飞行
        super().update()

        # 判断是否废除屏幕,如果是,从精灵组移除
        if self.rect.y >= SCREEN_RECT.height:
            # kill方法会将精灵从所有组中删除
            self.kill()

    def __del__(self):
        print("敌机%s被销毁" % self.rect)


class Hero(GameSprite):
    def __init__(self):
        # 调用父类方法,设置图片和速度
        super().__init__("./images/hero.png", speed_para=0)

        # 设置英雄的初始位置
        self.rect.centerx = SCREEN_RECT.centerx
        self.rect.bottom = SCREEN_RECT.bottom - 20

        # 创建子弹精灵组
        self.bullets = pygame.sprite.Group()

    def update(self):
        # 英雄只能左右移动,不能上下移动
        self.rect.x += self.speed

        # 限定英雄不能飞出屏幕,等价于eventhandle中的代码
        # if self.rect.right >= SCREEN_RECT.right:
        #     self.rect.right = SCREEN_RECT.right
        # elif self.rect.x < 0:
        #     self.rect.x = 0


    def fire(self):
        # 创建子弹精灵,一次发射2发子弹
        for i in (0,1):
            bullet = Bullet()
            # 设置子弹精灵的位置,在飞机正上方60单位,间隔60
            bullet.rect.bottom = self.rect.y - i*60
            bullet.rect.centerx = self.rect.centerx
            # 将精灵添加到精灵组
            self.bullets.add(bullet)
        print("开火")


class Bullet(GameSprite):

    def __init__(self):
        # 调用父类方法,设置子弹图片,设置初始速度
        super().__init__("./images/bullet1.png", speed_para=-2)

    def update(self):
        # 调用父类方法,让子弹沿着垂直方向飞行
        super().update()
        # 子弹飞出窗口,则销毁 bpottom 为图像的底部
        if self.rect.bottom < 0:
            self.kill()

    def __del__(self):
        print("子弹被销毁")

3、资源图片

3.1  背景图片bg.jpg

3.2  英雄飞机 hero.png

3.3  敌机 enemy1.png

3.4  子弹bullet1.png

3.5 游戏画面

 

 

 

3.6 启动游戏

 

posted @ 2024-01-23 09:30  无声袖箭  阅读(158)  评论(0)    收藏  举报