程序员防内卷小游戏2之代码实现

该博客介绍了如何利用Pygame库开发一款简单的飞行射击游戏。游戏包括创建游戏窗口、设置时钟、精灵和精灵组、定时器事件等功能。玩家控制英雄角色,通过键盘移动并发射子弹打击随机出现的敌人。敌人碰撞到英雄会导致游戏结束。游戏还包括背景图片交替滚动、碰撞检测、声音效果以及游戏结束的处理。代码详细展示了游戏精灵类的创建,如背景、敌人、英雄和子弹的移动及销毁机制。
摘要由CSDN通过智能技术生成

老规律,我们用pygame库来进行开发

初始化代码分为:
1.创建主游戏窗口
2.创建游戏的时钟
3.创建精灵和精灵族
4.设置定时器事件,来创建敌人和子弹的事件

具体代码如下:
先定义一个游戏类,类中初始化执行以上四个方法代码。初始化完执行游戏开始方法。

以下为初始化方法

    # 保护我方程序员
    def __init__(self):
        print("游戏初始化")

        # 1.创建游戏窗口
        self.screen = pygame.display.set_mode(SCREEN_RECT.size)

        # 2.创建游戏的时钟
        self.clock = pygame.time.Clock()

        # 3.调用私有方法,精灵和精灵族的创建
        self.__CreateSprites()

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

        pygame.time.set_timer(HERO_FIRE_EVENT, 1000)

    def __CreateSprites(self):  # 自定义的函数用--表示

        # 创建背景精灵和精灵组
        # bg1 = BackGround("static/image/background0.png")  # 第一个背景
        # bg2 = BackGround("static/image/background0.png")  # 第二个背景
        # bg2.rect.y = -bg2.rect.height
        bg1 = BackGround()  # 第一个背景
        bg2 = BackGround(True)  # 第二个背景
        self.backGroup = pygame.sprite.Group(bg1, bg2)  # 实现背景图片交替滚动效果

        # 创建敌人精灵组
        self.enemyGroup = pygame.sprite.Group()

        # 创建英雄程序员精灵和精灵组
        self.hero = Hero()
        self.heroGroup = pygame.sprite.Group(self.hero)

开始游戏方法

    def __StartGame__(self):

        global globalCnt
        globalCnt = 0
        while True:
            # 1.刷新新帧率
            self.clock.tick(FRAME_PER_SEC)
            # 2.事件监听
            self.__EventHandler__()
            # 3.碰撞检测
            self.__CheckCollide()
            # 4.更新绘制精灵组
            self.__UpdateSpi__()
            # 5.更新显示
            pygame.display.update()

这里包含了,刷新游戏帧率,一般每秒60次就可以了
然后就是事件的监听,碰撞检测,更新绘制精灵组,更新显示

事件监听

事件监听主要是按钮操作,所需要的一些动作执行;
我们规定,方向键左右执行,英雄主角就执行往x轴左右移动一个距离

    def __EventHandler__(self):

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                PlaneGame.__GameOver__()
            elif event.type == CREATE_ENEMY_EVENT:
                # 1.创建敌人精灵
                enemy = Enemy()
                self.enemyGroup.add(enemy)
            elif event.type == HERO_FIRE_EVENT:
                self.hero.fire()

        keyPressed = pygame.key.get_pressed()

        if keyPressed[pygame.K_RIGHT]:
            self.hero.speed = 1
        elif keyPressed[pygame.K_LEFT]:
            self.hero.speed = -1

碰撞检测
碰撞检测一般分两种,一种是组碰撞,一种是精灵碰撞,

    def __CheckCollide(self):

        # 1.检测碰撞, 子弹和敌人碰撞,都销毁
        global globalCnt
        killEnemyList = pygame.sprite.groupcollide(self.hero.bulletGroup, self.enemyGroup, True, True)
        if (len(killEnemyList)) > 0:
            print("击中了:" + str(globalCnt))
            tempSound("static/sound/enemy1_down.mp3")
            globalCnt += 1

        # 2.敌人撞毁英雄
        enemiesList = pygame.sprite.spritecollide(self.hero, self.enemyGroup, True)

        # 判断列表是否有内容
        if len(enemiesList) > 0:
            # 如果检测到碰撞,让英雄撞毁
            pygame.mixer.music.stop()
            self.hero.kill()

            # 给出结束游戏提示
            self.screen.fill(RED)
            gameOverText = font_big.render("Game Over", True, (0, 0, 0))
            # gameOverText = font_big.render("游戏结束", True, (0, 0, 0))
            self.screen.blit(gameOverText, (150, 250))

            refuseTimes = font_small.render("You refuse unreasonable requests %d times" % globalCnt, True, (0, 0, 0))
            # refuseTimes = font_small.render("恭喜你打败敌人 %d 次" % globalCnt, True, (0, 0, 0))
            self.screen.blit(refuseTimes, (100, 400))

            pygame.display.update()
            tempSound("static/sound/game_over.wav")
            time.sleep(2)
            pygame.quit()
            exit()

我这边做的事,当子弹和敌人发生碰撞,则敌人销毁,如果是敌人和英雄碰撞,则整个游戏就结束了,结束的时候,我会加上背景音乐以及提示,以及记录整个游戏过程中击败了击此敌人。

更新精灵以及精灵组

    def __UpdateSpi__(self):
        self.backGroup.update()
        self.backGroup.draw(self.screen)

        self.enemyGroup.update()
        self.enemyGroup.draw(self.screen)

        self.heroGroup.update()
        self.heroGroup.draw(self.screen)

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

我们创建的精灵组每一步都要在窗口进行更新,套路都是update\draw

最后就是游戏结束,游戏结束要将所有依赖库移除以及程序退出,

    @staticmethod
    def __GameOver__():
        print("游戏结束")
        pygame.quit()
        exit()

在这游戏结束没有用到其他的方法,则会提示它是静态的,需要加上staticmethod的注入

来看下他是怎么执行的,当然是从main方法开始执行

def tempSound(sound_path):
    downSound = pygame.mixer.Sound(sound_path)
    downSound.play(0)
    downSound.set_volume(1.0)

    # downSound.stop()


if __name__ == '__main__':
    global globalCnt

    # 播放背景音乐
    pygame.mixer.init()
    pygame.mixer.music.load("static/sound/game_music.mp3")
    pygame.mixer.music.play(-1)
    pygame.mixer.music.set_volume(0.1)

    game = PlaneGame()
    game.__StartGame__()

我这加了全局背景音乐以及局部背景音乐,
全局背景音乐用pygame.mixer.music方法,局部背景音乐用pygame.mixer方法

这两种在不同场合使用,都可以设置播放频率,声音大小等,具体可以参考其说明文档

接下来看下比较重要的就是精灵和精灵组代码

我们的背景大小以及初始位置,都设置成固定参数,默认大写为常量,小写为变量

# 创建图像初始位置 x, y, width, height
SCREEN_RECT = pygame.Rect(0, 0, 530, 700)
# 刷新的帧率
FRAME_PER_SEC = 60
# 创建低级的定时器常量
CREATE_ENEMY_EVENT = pygame.USEREVENT
# 英雄发射子弹得事件
HERO_FIRE_EVENT = pygame.USEREVENT + 1

pygame.init()
# 设置窗体的名称
pygame.display.set_caption("保护我方程序猿    原创:爱编程的小仙女")
# 设置窗体的logo,如果不设置默认是一只小龙
gameIcon = pygame.image.load("static/image/logo.ico")
pygame.display.set_icon(gameIcon)

# 设置最小字体以及字体格式
font_small = pygame.font.SysFont("simkai.ttf", 20)
# 设置最大字体以及字体格式,注意xxx.ttf是windows/font目录下有的,如果没有可能会报错
font_big = pygame.font.SysFont("simkai.ttf", 60)
# 设置背景颜色为红色
RED = "#FF0000"

定义一个游戏精灵函数
这个函数初始化为加载图片,更新为某精灵在垂直方向上移动


class GameSprite(pygame.sprite.Sprite):

    def __init__(self, image_name, speed=1):
        # 调用父类的初始化方法
        super(GameSprite, self).__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 __init__(self, is_alt=False):
        # 1.调用父类方法实现精灵的创建
        bgRand = random.randint(0, 1)
        super(BackGround, self).__init__("static/image/background" + str(bgRand) + ".png")

        # 2.判断是否时交替对象,如果是,设置初始位置
        if is_alt:
            self.rect.y = -self.rect.height

    # 游戏背景精灵
    def update(self):
        # 1.调用父类的方法实现
        super(BackGround, self).update()
        # 2.判断是否意出屏幕,如果意出屏幕,将图片设置到屏幕的上方
        if self.rect.y >= SCREEN_RECT.height:
            self.rect.y = -self.rect.height

背景图片我是用两张图片交替进行的,不是一张图片交替,随机交替可以受用random进行对图片的选取,只要名字对的上就可以。
如果游戏背景图片y轴超过了整个背景y轴,那么就将背景图片y轴放置在负方向。

敌人精灵

class Enemy(GameSprite):

    # 敌人精灵
    def __init__(self):
        # 1.调用父类方法,创建低级精灵,同时指定低级图片
        index = random.randint(0, 5)  # 随机显示地方战机
        super(Enemy, self).__init__("static/image/enemy" + str(index) + ".png")

        # super(Enemy, self).__init__("static/image/enemy0.png")

        # 2.指定敌人的初始随机速度 2-6
        self.speed = random.randint(2, 6)

        # 指定敌人的初始随机位置
        self.rect.bottom = 0  # y轴出现的位置

        maxX = SCREEN_RECT.width - self.rect.width
        self.rect.x = random.randint(0, maxX)  # 敌人在X轴随机出现的位置

    def update(self):
        # 1.调用父类方法,保持垂直方向的飞行
        super(Enemy, self).update()

        # 2.判断是否飞出屏幕,如果是,需要从精灵组删除敌人
        if self.rect.y >= SCREEN_RECT.height:
            self.kill()

    def __del__(self):
        pass

敌人精灵,我们要设置他的背景图片,以及随机出现的位置,随机的运行速度,以及飞出背景图片y轴进行精灵的销毁

英雄的精灵

class Hero(GameSprite):
    # 英雄精灵
    def __init__(self):
        # 1.调用父类方法设置image和speed
        super(Hero, self).__init__("static/image/programmer.png", 0)

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

        # 创建子弹得精灵组
        self.bulletGroup = 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):
        # 1.创建子弹精灵

        for i in (0, 1):  # 一次性发射两枚子弹
            bullet = Bullet()

            # 2.创建精灵得位置
            bullet.rect.bottom = self.rect.y - i * 75
            bullet.rect.centerx = self.rect.centerx
            # 3.将精灵添加到精灵组
            self.bulletGroup.add(bullet)

英雄也要设置初始位置、英雄不能移除整个窗体,还要能发射子弹,每次发射几枚子弹

子弹精灵

class Bullet(GameSprite):
    # 子弹精灵

    def __init__(self):
        # 调用父类方法,设置子弹图片,设置初始速度
        bulletRand = random.randint(1, 4)
        super(Bullet, self).__init__("static/image/language" + str(bulletRand) + ".png", -2)

    def update(self):
        # 调用父类方法,让子弹沿垂直方向飞行
        super(Bullet, self).update()

        # 判断子弹飞出屏幕
        if self.rect.bottom < 0:
            self.kill()

    def __del__(self):
        pass

子弹精灵就是设置随机速度,以及运行的方向,在子弹飞出窗体后,进行自动销毁。

自动销毁用的是自带的self.kill()方法

好了整个运行代码我们都写完了,运行下就能得到你想要的效果。
在这展示的是比较初级的游戏,如果你想做更加强大的游戏,好好看看其他的课程以及开发文档,对你很有帮助哦,动手操作一遍吗。

由于无法发送视频,上一篇中已经有外部连接,对着看以下,你可以在这基础上进行优化。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值