赛博红兔的科技博客

CyberHongTu shares news, insights, and musings on fascinating technology subjects.


和我一起做3A游戏《信仰之跃:百层试炼》

大家好,我是赛博红兔。欢迎回到《和我一起做3A游戏》系列!在介绍今天的游戏之前,我建议完全没有Pygame基础的朋友们先去看看本系列的前三集基础教学,链接我会放在下方评论区。我小时候非常沉迷于文曲星上的一款游戏叫作《是男人就下100层》。它最早叫《NS-Shaft》,由日本开发者草薙昭彦设计,通过使用方向键左右控制角色,目标是尽可能地下到更多层,同时要避免被台阶托上去挤死、掉下去摔死或被钉板尖刀戳死。我们就来制作一款自己的跳塔游戏,还给它取一个中二的名字叫作《信仰之跃:百层试炼》! 游戏一共有100层,反正我自己从来没有玩通关过,自己设计的游戏自己打不通,让我产生了一种是不是设计得太难了的自我怀疑。欢迎大家都来玩玩,真能打通关的,把通关截图或者视频发到评论区或者发给我邮箱,来打消我的怀疑。

我已经把这个游戏用到的资源、代码还有EXE的应用程序打包放在百度网盘了,链接会放在下面,代码也可以去我的GitHub或者博客下载。你可以按照上面的安装说明部署项目,都写得比较详细了。如果,只想玩这个游戏的朋友,可以直接运行我打包好的EXE应用文件,在电脑上直接跑不需要安装python。记住,跑这个游戏的电脑需要有一张声卡来运行背景音乐,而且一定要把应用程序和assets也就是游戏资源包放在一起,不然会出错。

好了,想继续学习这游戏是怎么做的朋友请接着往下看。首先,我在第一集已经介绍了我所有的游戏资源,包括图片、声效、BGM,都是从这两个开源网站下载的,大家也可以共享一下自己了解的游戏资源库。接下来我们看到的是游戏源代码,这里,我主要会重点介绍之前没有见过的pygame功能和游戏特色部分的代码。具体大伙可以按照我的源代码去学习和拓展。在我们的项目包里第一个asset文件夹里都是游戏的资源文件,包括一些图片和音效。下面是一个主文件和一个配置文件,这游戏常量有不少,比如游戏窗口显示,图片、音乐存放路径,事件代码等等,我们都用英文大写来命名它们并且都放在了这个叫settings的配置文件里,方便主文件的调用。我把主要参数归类了一下,具体大家可以参考源代码。游戏的核心结构划分为三个主要类:Hero角色类、Terrain每一层阶梯类、Game游戏类。首先我们引入random模块中的choices和randint函数。choices用于从序列中随机选择多个元素,randint生成指定范围内的随机整数。导入了pygame库,sys模块里的exit函数是用来方便退出游戏用的。当然必须要导入所有的游戏配置参数文件。

1. 功能函数

def flip(images):
    """水平翻转一组图像。"""
    return [pg.transform.flip(image, True, False) for image in images]

def load_image_sheets(img_path, width, height, needScale=False, customScale=False, size=None):
    """加载精灵图并分割成子图像,用于动画帧管理。"""
    # ...具体实现省略
    return images

def render_font(text, font, color, center):
    """渲染字体并返回渲染后的图像和位置。"""
    # ...具体实现省略
    return rendered_text, rendered_text_rect

render_font 函数:生成游戏中的文本(如标题、分数显示),使用指定的字体、颜色和位置。

flip 函数:实现角色左右方向的动画翻转,利用 Pygame 的 transform.flip 方法。

load_image_sheets 函数:将精灵图拆分为多个子图像,用于管理角色的动画帧,支持图像缩放。

2. 角色类(Hero)

class Hero(pg.sprite.Sprite):
    def __init__(self, heroType):
        # 初始化角色属性
        self.health = MAX_HEALTH
        self.direction = "left"
        self.run = False
        self.fall = False
        # 加载动画图像
        self.hero_idle_right_img = load_image_sheets(...)
        self.hero_idle_left_img = flip(self.hero_idle_right_img)
        # ...加载其他状态图像(跑步、掉落、受击)

    def hero_appear(self):
        """播放角色出现动画。"""
        # ...具体实现省略

    def hero_run(self):
        """处理角色移动逻辑。"""
        # ...具体实现省略

    def hero_die(self):
        """处理角色死亡逻辑。"""
        # ...具体实现省略

    def animation(self):
        """管理角色不同状态的动画。"""
        # ...具体实现省略

    def update(self):
        """每帧更新角色状态和动画。"""
        # 调用上述方法更新角色状态
  1. 初始化角色:加载角色的不同状态动画,包括静止、跑步、掉落和受击。通过 flip 函数处理朝向动画。
  2. 动画管理:根据角色状态选择不同的动画帧,并在状态切换时重置动画计数。
  3. 逻辑实现
    • hero_run:通过键盘输入控制角色左右移动。
    • hero_die:检测角色是否触碰到致命障碍,设置死亡状态。

3. 阶梯类(Terrain)

class Terrain(pg.sprite.Sprite):
    def __init__(self, terrainType, pos):
        """初始化阶梯属性和类型。"""
        self.type = terrainType
        self.has_dealt_damage = False
        # 加载图像
        if self.type == "conveyor_tile_right":
            self.image = load_image_sheets(...)
        else:
            self.image = pg.image.load(...)

    def terrain_move(self):
        """更新阶梯位置。"""
        self.rect.y -= TERRAIN_SPEED

    def destroy(self):
        """销毁移出屏幕的阶梯对象。"""
        if self.rect.y <= -TERRAIN_HEIGHT:
            self.kill()

    def update(self):
        """每帧更新阶梯状态。"""
        self.terrain_move()
        self.destroy()
  1. 阶梯类型:定义不同的阶梯效果(普通、治疗、陷阱、传送带等),通过参数 terrainType 区分。
  2. 位置更新:阶梯向上移动,给玩家制造“向下跳”的错觉。
  3. 销毁逻辑:移出屏幕的阶梯自动销毁,释放内存资源。

4. 主游戏类(Game)

class Game:
    def setup(self):
        """初始化游戏状态和窗口。"""
        self.game_active = False
        self.clock = pg.time.Clock()

    def load_resources(self):
        """加载资源(字体、图像、音效)。"""
        self.background = pg.image.load(BACKGROUND).convert()
        self.hero_initImgs = [load_image_sheets(...) for hero_name in HERO_LIST]

    def handle_events(self):
        """处理玩家输入和事件。"""
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                exit()

    def draw_background(self):
        """绘制背景和动态效果(墙体、锯齿)。"""
        # ...具体实现省略

    def main_loop(self):
        """游戏主循环。"""
        while True:
            self.handle_events()
            if self.game_active:
                self.draw_background()
                terrains.update()
                hero.update()
                # 检测碰撞并更新状态
            pg.display.update()
  1. 资源加载:初始化游戏界面和加载所有必要资源(背景、角色图像、音效等)。
  2. 事件处理:监听键盘输入,处理角色选择和移动。
  3. 主循环
    • 持续更新角色和阶梯的状态。
    • 绘制游戏画面,包括背景、角色和阶梯。
    • 实现碰撞检测和游戏逻辑。

大功告成!现在我们就一起玩一下新鲜出炉的《信仰之跃》。好了,接下来,就由大家亲自体验这款游戏的魅力吧。你们在边学边玩的时候,遇到了什么问题或者BUG请给我留言。之后,我们说好了还会带给大家更多精彩的“3A”游戏!那就这样,咱们下期再见!拜拜!



Leave a comment