子弹系统与碰撞检测:霓虹射线的飞行逻辑
> 子弹是射击游戏的"语言"——它定义了玩家和世界交互的方式。
## 当前状态:占位符
在 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 中的应用。
> 子弹系统的核心原则:**射击要爽,反馈要快**。玩家按下空格键,子弹必须在同一帧出现,不能有"延迟感"。
- 点赞
- 收藏
- 关注作者
评论(0)