Phaser 3 游戏引擎核心概念:场景、物理、补间

举报
yd_296221794 发表于 2026/10/25 00:40:39 2026/10/25
【摘要】 > 理解 Phaser 的三大支柱,是读懂 NEON RUNNER 2077 源码的前提。## 为什么是 Phaser 3在 2026 年,做 2D 网页游戏的选择其实不少:PixiJS、Three.js、Babylon.js,甚至 Canvas 2D 原生 API。但 Phaser 3 有一个独特的定位——**它把"游戏循环"这件事封装好了**。你不需要写 `requestAnimatio...

> 理解 Phaser 的三大支柱,是读懂 NEON RUNNER 2077 源码的前提。


## 为什么是 Phaser 3


在 2026 年,做 2D 网页游戏的选择其实不少:PixiJS、Three.js、Babylon.js,甚至 Canvas 2D 原生 API。但 Phaser 3 有一个独特的定位——**它把"游戏循环"这件事封装好了**。


你不需要写 `requestAnimationFrame`,不需要自己处理输入、碰撞、资源加载。Phaser 把这些都变成了 `Scene` 里的方法。


## 场景(Scene):游戏的生命单元


Phaser 的场景系统是整个引擎的骨架。NEON RUNNER 2077 里一共注册了 4 个场景:


```ts

// src/config/gameConfig.ts

scene: [BootScene, PreloadScene, MenuScene, GameScene]

```


每个场景都是一个 `extends Phaser.Scene` 的类。Phaser 在内部维护一个场景栈,通过 `this.scene.start('SceneName')` 切换。


每个场景有三个核心生命周期方法:


| 方法 | 调用时机 | 典型用途 |

|---|---|---|

| `constructor()` | 实例化时 | 注册场景键名 |

| `preload()` | 进入场景前 | 加载资源(图片/音频/纹理) |

| `create()` | 资源加载完毕 | 创建游戏对象、启动逻辑 |


`BootScene` 的 `create()` 里只有 300ms 的延迟调用,然后切到 `PreloadScene`。`PreloadScene` 的 `preload()` 里调用 `generateProceduralAssets()`——这个方法不加载任何外部文件,而是用 `make.graphics` 程序化生成纹理。


## 物理系统:Arcade Physics


NEON RUNNER 2077 使用的是 Phaser 的 Arcade Physics,这是最轻量的 2D 物理引擎:


```ts

physics: {

  default: 'arcade',

  arcade: {

    gravity: { x: 0, y: 0 }, // 无重力,纯 2D 平面

    debug: false,

  },

},

```


`gravity: { x: 0, y: 0 }` 意味着这是一个**零重力平面**——玩家和子弹在 X/Y 轴上自由移动,没有抛物线,没有下落。这是射击游戏的典型设定。


`debug: false` 表示不显示碰撞体边界框。如果要调试,改成 `true` 就能看到每个物体的绿色包围盒。


## 补间(Tween):让"动"这件事变得声明式


Phaser 的 `tweens.add()` 是 NEON RUNNER 2077 里用得最频繁的 API。它的核心思想是:**你描述"从哪到哪",而不是"怎么动"**。


`PreloadScene` 里的加载条动画:


```ts

this.tweens.addCounter({

  from: 0,

  to: 100,

  duration: 1800,

  ease: 'Sine.easeInOut',

  onUpdate: (_tween, _key, _target, current) => {

    const value = current / 100;

    this.progressBar.width = this.barWidth * value;

    this.percentText.setText(`${Math.floor(value * 100)}%`);

  },

});

```


注意 `tweens.addCounter` 和 `tweens.add` 的区别:`addCounter` 不操作具体对象,只给你一个 `current` 数值回调,适合驱动进度条这种"数值型"动画。


`MenuScene` 里的标题呼吸效果:


```ts

this.tweens.add({

  targets: this.subtitle,

  alpha: { from: 0.4, to: 0.9 },

  duration: 1200,

  yoyo: true, // 到达终点后自动反向

  repeat: -1, // 无限循环

  ease: 'Sine.easeInOut',

});

```


`yoyo: true` + `repeat: -1` 是 Phaser 里做"呼吸效果"的标准写法——不用写 `onComplete` 回调再反向播放,一行配置搞定。


## 场景切换与相机淡入淡出


NEON RUNNER 2077 里场景切换不是"瞬间"的,而是通过相机淡入淡出过渡:


```ts

this.cameras.main.fadeOut(400, 10, 10, 15);

this.cameras.main.once('camerafadeoutcomplete', () => {

  this.scene.start('GameScene');

});

```


`fadeOut(400, 10, 10, 15)` 的参数是:时长 400ms,RGB 值 (10, 10, 15)——接近黑色的深蓝。这个过渡让场景切换不那么"硬",在赛博朋克语境里像是一次"系统重启"。


## 下一章预告


场景系统讲完了,但 NEON RUNNER 2077 的视觉风格真正建立的地方是**颜色系统**。下一章我会拆解 `colors.ts` 里那 12 个霓虹色值,以及它们是怎么从 TypeScript 常量一路渗透到 CSS 变量、Canvas 绘制、文字颜色的。


> 如果你在写 Phaser 项目,记住一个原则:**场景是容器,补间是语言,物理是规则**。把这三件事分清楚,代码就不会乱。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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