BootScene:开机场景的极简设计

举报
yd_296221794 发表于 2026/09/12 10:52:40 2026/09/12
【摘要】 > 39 行代码,300 毫秒,一个标题。为什么"少"反而更重要?## 场景概览`BootScene` 是 NEON RUNNER 2077 的第一个场景,也是最短的场景——只有 39 行。它的职责极其单一:**展示标题,然后切走**。```ts// src/scenes/BootScene.tsexport class BootScene extends Phaser.Scene {  c...

> 39 行代码,300 毫秒,一个标题。为什么"少"反而更重要?


## 场景概览


`BootScene` 是 NEON RUNNER 2077 的第一个场景,也是最短的场景——只有 39 行。它的职责极其单一:**展示标题,然后切走**。


```ts

// src/scenes/BootScene.ts

export class BootScene extends Phaser.Scene {

  constructor() {

    super('BootScene');

  }


  create(): void {

    const { width, height } = this.scale;

    this.cameras.main.setBackgroundColor(COLORS.DEEP_BLACK);


    this.add

      .text(width / 2, height / 2 - 40, 'NEON RUNNER 2077', {

        fontFamily: FONTS.DISPLAY,

        fontSize: '56px',

        color: '#FCEE0A',

        align: 'center',

      })

      .setOrigin(0.5)

      .setAlpha(0);


    this.add

      .text(width / 2, height / 2 + 30, '// BOOTING CYBERWARE', {

        fontFamily: FONTS.MONO,

        fontSize: '18px',

        color: '#00F0FF',

        align: 'center',

      })

      .setOrigin(0.5)

      .setAlpha(0);


    this.time.delayedCall(300, () => {

      this.scene.start('PreloadScene');

    });

  }

}

```


## 为什么"不加载任何资源"


`BootScene` 的 `preload()` 方法是空的——它不加载任何图片、音频、字体。这是有意为之的。


在 Phaser 里,`preload()` 是在 `create()` 之前调用的。如果 `BootScene` 的 `preload()` 里加载了资源,那么玩家会看到一个空白的加载界面——这和"开机"的体验背道而驰。


`BootScene` 的目标是**零延迟反馈**:玩家打开页面,立刻看到标题。字体已经在 `index.html` 的 `<link>` 里加载了,所以标题一出来就是 Orbitron,不会出现"先显示默认字体再切换"的闪烁。


## setAlpha(0):从不可见开始


注意两行文字都设置了 `.setAlpha(0)`——完全透明。这意味着标题在创建时是不可见的。但代码里没有用 `tweens` 让标题淡入,而是直接 300ms 后切场景。


这个"透明"是给 CSS 的 `boot-overlay` 动画用的。`index.html` 里的 `#boot-overlay` 是一个覆盖层,它包含 `.boot-text` 和 `.boot-sub`,用 CSS 动画做故障闪烁效果。Phaser 的 `BootScene` 标题和 CSS 的 `boot-overlay` 是**两套视觉系统**——Phaser 画的是游戏世界,CSS 画的是"开机界面"。


## 300ms 延迟:不是偷懒,是节奏


`this.time.delayedCall(300, ...)` 这个 300ms 不是随便写的。在游戏开发里,"开机"这个动作需要一个**心理节奏**:


- 0ms:页面加载,CSS 的 `.boot-text` 开始故障闪烁

- 300ms:Phaser 启动,`BootScene` 创建标题

- 600ms:`BootScene` 切到 `PreloadScene`

- 1800ms:`PreloadScene` 的加载条走完

- 2100ms:`PreloadScene` 切到 `MenuScene`


整个"开机"流程大约 2.1 秒。这个时间不是"越快越好"——如果 0.5 秒就进菜单,玩家会觉得"这游戏太简单了"。2.1 秒的"加载感"让玩家觉得"这是一个有分量的游戏"。


## 为什么用 `delayedCall` 而不是 `setTimeout`


Phaser 的 `this.time.delayedCall()` 和原生的 `setTimeout()` 看起来一样,但有一个关键区别:**Phaser 的时间系统是可暂停的**。


如果游戏进入后台(用户切到别的标签页),Phaser 会自动暂停所有 `time.addEvent` 和 `tweens`。`setTimeout` 不受这个限制——它会在后台继续计时,等用户切回来时立刻触发。


在 NEON RUNNER 2077 里,`BootScene` 的 300ms 延迟用 `delayedCall` 写,是为了保证"开机节奏"在游戏暂停/恢复时不会乱。


## 下一章预告


`BootScene` 讲完了,但真正的主角是 `PreloadScene`——它要在一个没有外部资源的场景里,用 `make.graphics` 程序化生成 3 张贴图(玩家/敌人/子弹),还要让加载条看起来像在"加载"。下一章我会拆解这个 121 行的场景。


> 开机场景的核心原则:**零资源,零延迟,零干扰**。玩家打开页面,立刻看到内容,立刻知道"这是什么游戏"。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。