GameScene:战斗场景与 Arena 背景绘制

举报
yd_296221794 发表于 2026/10/04 10:56:50 2026/10/04
【摘要】 > 122 行代码,把一个空白画布变成了"霓虹竞技场"。## 场景概览`GameScene` 是 NEON RUNNER 2077 的核心场景——玩家在这里战斗、得分、升级。但目前的实现里,战斗循环还没有真正开始(`placeholderText` 写着 "COMBAT ARENA // STANDBY"),所以这个场景的视觉部分比逻辑部分更完整。```ts// src/scenes/Gam...

> 122 行代码,把一个空白画布变成了"霓虹竞技场"。


## 场景概览


`GameScene` 是 NEON RUNNER 2077 的核心场景——玩家在这里战斗、得分、升级。但目前的实现里,战斗循环还没有真正开始(`placeholderText` 写着 "COMBAT ARENA // STANDBY"),所以这个场景的视觉部分比逻辑部分更完整。


```ts

// src/scenes/GameScene.ts

export class GameScene extends Phaser.Scene {

  private hud!: HUD;

  private player!: Phaser.GameObjects.Sprite;

  private score = 0;

  private wave = 1;

  private health = 1;

  private energy = 0;

```


## Arena 背景:网格 + 边框


`drawArenaBackground()` 是 `GameScene` 里最"有画面感"的方法:


```ts

private drawArenaBackground(width: number, height: number): void {

  const g = this.add.graphics().setDepth(0);

  g.fillStyle(COLORS.DEEP_BLACK, 1);

  g.fillRect(0, 0, width, height);


  g.lineStyle(1, COLORS.NEON_PURPLE, 0.18);

  const step = 80;

  for (let x = 0; x <= width; x += step) {

    g.beginPath();

    g.moveTo(x, 0);

    g.lineTo(x, height);

    g.strokePath();

  }

  for (let y = 0; y <= height; y += step) {

    g.beginPath();

    g.moveTo(0, y);

    g.lineTo(width, y);

    g.strokePath();

  }


  g.lineStyle(2, COLORS.NEON_CYAN, 0.5);

  g.strokeRect(40, 90, width - 80, height - 130);

}

```


这个背景分三层:


1. **深黑填充**:`DEEP_BLACK`(`#0A0A0F`)铺满整个画布

2. **紫色网格**:80px 间距的横竖线,透明度 0.18——非常淡,几乎看不见,但存在

3. **青色边框**:距离边缘 40px(左右)和 90px(上)/ 130px(下)的矩形框


## 为什么网格透明度是 0.18


0.18 是一个经过视觉验证的值。如果透明度太高(比如 0.5),网格会"抢戏"——玩家的注意力会被网格分散。如果透明度太低(比如 0.05),网格会"消失"——玩家感觉不到"竞技场"的氛围。


0.18 刚好让网格"存在但不显眼"——它像是一个"背景纹理",不是"前景元素"。


## 玩家精灵:霓虹三角形


```ts

this.player = this.add.sprite(width / 2, height / 2, 'player')

  .setDepth(10)

  .setAlpha(0.9);

```


玩家精灵在画布中心,`setDepth(10)` 确保它在背景之上。`setAlpha(0.9)` 让玩家看起来"半透明"——这是霓虹风格的典型处理:物体不是"实心"的,而是"发光"的。


## 玩家呼吸动画


```ts

this.tweens.add({

  targets: this.player,

  alpha: { from: 0.7, to: 1 },

  duration: 800,

  yoyo: true,

  repeat: -1,

  ease: 'Sine.easeInOut',

});

```


玩家的透明度在 0.7 和 1.0 之间呼吸,周期 800ms(400ms 上升 + 400ms 下降)。这个动画让玩家看起来像"在呼吸"——不是静止的模型,而是"活"的系统。


## 占位文字:战斗前的"待机"状态


```ts

this.placeholderText = this.add.text(width / 2, height * 0.3, 'COMBAT ARENA // STANDBY', {

  fontFamily: FONTS.DISPLAY, fontSize: '36px', color: '#FCEE0A', align: 'center',

}).setOrigin(0.5).setAlpha(0.6);


this.placeholderSub = this.add.text(width / 2, height * 0.3 + 50, '> M2 // CORE GAMEPLAY PENDING IMPLEMENTATION', {

  fontFamily: FONTS.MONO, fontSize: '16px', color: '#00F0FF', align: 'center',

}).setOrigin(0.5).setAlpha(0.7);

```


这两行文字是"占位符"——它们告诉玩家"战斗还没开始"。`M2` 是开发代号,暗示这是第二个里程碑(Milestone 2)。


## 占位文字的呼吸动画


```ts

this.tweens.add({

  targets: [this.placeholderText, this.placeholderSub],

  alpha: { from: 0.3, to: 0.6 },

  duration: 1200,

  yoyo: true,

  repeat: -1,

  ease: 'Sine.easeInOut',

});

```


占位文字的透明度在 0.3 和 0.6 之间呼吸,周期 1200ms。这个动画和玩家的呼吸动画(800ms)不同步——如果两个动画周期相同,它们会"共振",看起来像在"闪烁"。不同的周期让动画看起来更自然。


## 自动得分与能量恢复


```ts

this.time.addEvent({

  delay: 1500,

  loop: true,

  callback: () => {

    this.score += 10;

    this.energy = Math.min(1, this.energy + 0.04);

    this.hud.setScore(this.score);

    this.hud.setEnergy(this.energy);

  },

});

```


每 1500ms 增加 10 分和 0.04 能量。这是"待机状态"的模拟——即使战斗还没开始,玩家也能看到分数在涨、能量在恢复。这个设计让玩家觉得"游戏在运行",而不是"卡住了"。


## 退出战斗:ESC 键


```ts

this.input.keyboard?.once('keydown-ESC', () => {

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

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

    this.scene.start('MenuScene');

  });

});

```


按 ESC 键,相机淡出(400ms,深蓝),然后切回 `MenuScene`。`once('keydown-ESC', ...)` 确保只触发一次——如果玩家按住 ESC 不放,不会连续触发多次。


## 下一章预告


GameScene 讲完了,但 NEON RUNNER 2077 的"战斗循环"还没有真正实现。下一章我会拆解玩家控制与移动系统——那个霓虹三角形是怎么在 1280×720 的画布上飞的。


> 战斗场景的核心原则:**背景要淡,前景要亮**。玩家在战斗中不会去欣赏背景,但背景的"存在感"决定了整个场景的氛围。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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