feat(towers): 实现防御塔基类与4种塔及塔管理器
This commit is contained in:
91
game/towers/InternTower.ts
Normal file
91
game/towers/InternTower.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type Phaser from 'phaser'
|
||||
import { TowerBase } from './TowerBase'
|
||||
import { GameManager } from '../GameManager'
|
||||
import type { EnemyBase } from '../enemies/EnemyBase'
|
||||
|
||||
export class InternTower extends TowerBase {
|
||||
private selfDestroyTimer: number = 0
|
||||
private readonly SELF_DESTROY_INTERVAL = 1000
|
||||
private destroyed: boolean = false
|
||||
public onSelfDestroy?: (tower: InternTower) => void
|
||||
|
||||
constructor(scene: Phaser.Scene, gridX: number, gridY: number) {
|
||||
super(scene, gridX, gridY, 50, 1, 15, 1.5)
|
||||
this.drawSprite()
|
||||
}
|
||||
|
||||
drawSprite(): void {
|
||||
if (!this.sprite) return
|
||||
this.sprite.clear()
|
||||
// 绿色小人(圆头+十字身体)
|
||||
this.sprite.fillStyle(0x22c55e, 1)
|
||||
this.sprite.fillCircle(0, -12, 8)
|
||||
// 身体
|
||||
this.sprite.fillRect(-3, -4, 6, 14)
|
||||
// 手臂
|
||||
this.sprite.fillRect(-12, -2, 24, 4)
|
||||
this.sprite.setPosition(this.px, this.py)
|
||||
this.sprite.setDepth(10)
|
||||
}
|
||||
|
||||
override update(delta: number, enemies: EnemyBase[]): void {
|
||||
if (this.destroyed) return
|
||||
|
||||
super.update(delta, enemies)
|
||||
|
||||
// 被动:每秒1%概率离场
|
||||
this.selfDestroyTimer += delta
|
||||
if (this.selfDestroyTimer >= this.SELF_DESTROY_INTERVAL) {
|
||||
this.selfDestroyTimer -= this.SELF_DESTROY_INTERVAL
|
||||
if (Math.random() < 0.01) {
|
||||
// 退还 25 HC
|
||||
GameManager.getInstance().addHC(25)
|
||||
this.showMessage('实习生跑路!+25HC')
|
||||
this.destroyed = true
|
||||
this.onSelfDestroy?.(this)
|
||||
this.destroy()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attack(target: EnemyBase): void {
|
||||
// 整顿职场:5% 概率秒杀 HP < 500 的怪物
|
||||
if (Math.random() < 0.05 && target.hp < 500) {
|
||||
target.takeDamage(9999)
|
||||
this.showMessage('整顿职场!秒杀!')
|
||||
} else {
|
||||
target.takeDamage(this.attackDamage)
|
||||
}
|
||||
// 近战效果(闪光)
|
||||
this.showMeleeEffect(target)
|
||||
}
|
||||
|
||||
private showMeleeEffect(target: EnemyBase): void {
|
||||
const g = this.scene.add.graphics()
|
||||
g.fillStyle(0x22c55e, 0.7)
|
||||
g.fillCircle(target.sprite.x, target.sprite.y, 10)
|
||||
g.setDepth(15)
|
||||
this.scene.time.delayedCall(150, () => g.destroy())
|
||||
}
|
||||
|
||||
private showMessage(msg: string): void {
|
||||
const txt = this.scene.add
|
||||
.text(this.px, this.py - 30, msg, {
|
||||
fontFamily: 'VT323, monospace',
|
||||
fontSize: '14px',
|
||||
color: '#22C55E',
|
||||
backgroundColor: '#14532D',
|
||||
padding: { x: 4, y: 2 },
|
||||
})
|
||||
.setOrigin(0.5, 1)
|
||||
.setDepth(20)
|
||||
this.scene.tweens.add({
|
||||
targets: txt,
|
||||
y: this.py - 55,
|
||||
alpha: 0,
|
||||
duration: 1200,
|
||||
onComplete: () => txt.destroy(),
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user