子弹系统与碰撞检测:霓虹射线的飞行逻辑

举报
yd_296221794 发表于 2026/09/10 09:13:19 2026/09/10
【摘要】 > 子弹是射击游戏的"语言"——它定义了玩家和世界交互的方式。## 当前状态:占位符在 NEON RUNNER 2077 的当前版本里,子弹系统还没有真正实现。`PreloadScene` 里已经生成了 `'bullet'` 纹理(青色圆角矩形,4×16 像素),但 `GameScene` 里没有射击逻辑。## 子弹纹理:为什么是 4×16```ts// PreloadScene.tscon...

> 子弹是射击游戏的"语言"——它定义了玩家和世界交互的方式。


## 当前状态:占位符


在 NEON RUNNER 2077 的当前版本里,子弹系统还没有真正实现。`PreloadScene` 里已经生成了 `'bullet'` 纹理(青色圆角矩形,4×16 像素),但 `GameScene` 里没有射击逻辑。


## 子弹纹理:为什么是 4×16


```ts

// PreloadScene.ts

const bulletGraphics = this.make.graphics({ x: 0, y: 0 }, false)!;

bulletGraphics.fillStyle(0x00f0ff, 1);

bulletGraphics.fillRoundedRect(-2, -8, 4, 16, 2);

bulletGraphics.generateTexture('bullet', 4, 16);

```


4×16 像素的青色圆角矩形。为什么是这个尺寸?


- **宽度 4px**:足够细,不会遮挡玩家的视线

- **高度 16px**:足够长,在 1280×720 的画布上能"飞"一段距离

- **圆角 2px**:让子弹看起来"柔和",不是尖锐的针


## 射击机制:按空格键发射


```ts

// 伪代码:射击机制

this.input.keyboard.on('keydown-SPACE', () => {

  if (this.energy >= 0.1) {

    this.fireBullet();

    this.energy -= 0.1;

    this.hud.setEnergy(this.energy);

  }

});

```


射击消耗能量(0.1)。能量不足时不能射击——这是**资源管理**的设计,防止玩家"无脑连射"。


## 子弹飞行:速度与方向


```ts

// 伪代码:发射子弹

fireBullet(): void {

  const bullet = this.physics.add.sprite(this.player.x, this.player.y - 20, 'bullet');

  bullet.setVelocityY(-500); // 向上飞行,500px/s

  this.bullets.push(bullet);

}

```


子弹从玩家上方 20px 的位置发射(`this.player.y - 20`),向上飞行(`setVelocityY(-500)`)。500px/s 在 60fps 下是 8.3px/frame——从玩家位置到屏幕顶部大约需要 84 帧(1.4 秒)。


## 子弹池:对象复用


在 Phaser 里,频繁创建和销毁对象会导致 GC(垃圾回收)压力。**对象池**(Object Pool)是解决这个问题的标准方案:


```ts

// 伪代码:子弹对象池

this.bullets = this.physics.add.group({

  defaultKey: 'bullet',

  maxSize: 30, // 最多 30 发子弹

  createCallback: (bullet) => {

    bullet.setActive(false);

    bullet.setVisible(false);

  }

});


fireBullet(): void {

  if (this.energy >= 0.1) {

    const bullet = this.bullets.get(this.player.x, this.player.y - 20);

    if (bullet) {

      bullet.setActive(true);

      bullet.setVisible(true);

      bullet.setVelocityY(-500);

      this.energy -= 0.1;

      this.hud.setEnergy(this.energy);

    }

  }

}

```


`bullets.get()` 从池子里取一个可用的子弹对象,如果池子满了(`maxSize: 30`),返回 `null`。


## 碰撞检测:子弹 vs 敌人


```ts

// 伪代码:碰撞检测

this.physics.add.overlap(this.bullets, this.enemies, (bullet, enemy) => {

  bullet.setActive(false);

  bullet.setVisible(false);

  bullet.destroy();

  enemy.destroy();

  this.score += 100;

  this.hud.setScore(this.score);

});

```


`physics.add.overlap()` 是 Phaser 的碰撞检测 API——它不检查"物理碰撞",只检查"矩形重叠"。当子弹和敌人的矩形重叠时,回调触发:


1. 子弹隐藏并销毁

2. 敌人销毁

3. 分数 +100


## 碰撞检测:玩家 vs 敌人


```ts

// 伪代码:玩家被敌人撞到

this.physics.add.overlap(this.player, this.enemies, (player, enemy) => {

  this.health -= 0.2;

  this.hud.setHealth(this.health);

  enemy.destroy();

  if (this.health <= 0) {

    this.gameOver();

  }

});

```


玩家被敌人撞到,血量 -0.2。血量归零时触发 `gameOver()`。


## 游戏结束:过渡到 GameOverScene


```ts

// 伪代码:游戏结束

gameOver(): void {

  this.cameras.main.fadeOut(1000, 255, 0, 60);

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

    this.scene.start('GameOverScene', { score: this.score });

  });

}

```


游戏结束时,相机用红色(255, 0, 60)淡出——红色暗示"危险"、"死亡"。然后切到 `GameOverScene`,传递最终分数。


## 下一章预告


子弹系统讲完了,但 NEON RUNNER 2077 的视觉风格里还有一个关键元素——**补间动画**。那些呼吸、闪烁、扫描的效果是怎么做出来的?下一章我会拆解 `tweens` 在霓虹 UI 中的应用。


> 子弹系统的核心原则:**射击要爽,反馈要快**。玩家按下空格键,子弹必须在同一帧出现,不能有"延迟感"。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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