85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
import type Phaser from 'phaser'
|
||
import { TowerBase } from './TowerBase'
|
||
import { AudioEngine } from '../AudioEngine'
|
||
import type { EnemyBase } from '../enemies/EnemyBase'
|
||
|
||
/**
|
||
* 外包程序员 — 30 HC(最便宜但最差)
|
||
* 攻击:扔出 Bug(随机概率丢空),低伤害,攻速慢
|
||
* 特殊技能"甲方爸爸":5% 概率扔出的 Bug 反弹打到自己,瞬间精力归零(摸鱼)
|
||
* 特色:便宜、量多凑数,是前期过渡塔
|
||
*/
|
||
export class OutsourceTower extends TowerBase {
|
||
constructor(scene: Phaser.Scene, gridX: number, gridY: number) {
|
||
// cost=30, range=2, damage=8, speed=0.7
|
||
super(scene, gridX, gridY, 30, 2, 8, 0.7, 'tower-outsource')
|
||
}
|
||
|
||
attack(target: EnemyBase): void {
|
||
AudioEngine.getInstance().playOutsourceAttack()
|
||
// 5% 概率 Bug 反弹(精力归零)
|
||
if (Math.random() < 0.05) {
|
||
this.stamina = 0
|
||
this.showMessage('Bug反弹!精力归零!', '#ef4444')
|
||
return
|
||
}
|
||
// 30% 概率丢空(miss)
|
||
if (Math.random() < 0.3) {
|
||
this.showMessage('Miss!环境问题!', '#9ca3af')
|
||
return
|
||
}
|
||
this.fireBug(target)
|
||
}
|
||
|
||
private fireBug(target: EnemyBase): void {
|
||
const bugEmojis = ['🐛', '🔥', '💥', '❌']
|
||
const sym = bugEmojis[Math.floor(Math.random() * bugEmojis.length)]
|
||
|
||
const bullet = this.scene.add.text(this.px, this.py, sym, {
|
||
fontSize: '14px',
|
||
}).setOrigin(0.5, 0.5).setDepth(13)
|
||
|
||
// 外包子弹走曲线(不走直线,歪歪扭扭)
|
||
const midX = (this.px + target.x) / 2 + (Math.random() - 0.5) * 60
|
||
const midY = (this.py + target.y) / 2 + (Math.random() - 0.5) * 60
|
||
|
||
this.scene.tweens.add({
|
||
targets: bullet,
|
||
x: midX, y: midY,
|
||
duration: 200,
|
||
ease: 'Sine.easeOut',
|
||
onComplete: () => {
|
||
this.scene.tweens.add({
|
||
targets: bullet,
|
||
x: target.x, y: target.y,
|
||
duration: 200,
|
||
ease: 'Sine.easeIn',
|
||
onComplete: () => {
|
||
bullet.destroy()
|
||
if (!target.isDead) {
|
||
target.takeDamage(this.attackDamage)
|
||
const g = this.scene.add.graphics()
|
||
g.fillStyle(0xef4444, 0.4)
|
||
g.fillCircle(target.x, target.y, 10)
|
||
g.setDepth(15)
|
||
this.scene.time.delayedCall(200, () => g.destroy())
|
||
}
|
||
},
|
||
})
|
||
},
|
||
})
|
||
}
|
||
|
||
private showMessage(msg: string, color: string): void {
|
||
const txt = this.scene.add
|
||
.text(this.px, this.py - 28, msg, {
|
||
fontFamily: 'VT323, monospace', fontSize: '13px',
|
||
color, backgroundColor: '#1c1917', padding: { x: 3, y: 1 },
|
||
}).setOrigin(0.5, 1).setDepth(20)
|
||
this.scene.tweens.add({
|
||
targets: txt, y: this.py - 50, alpha: 0,
|
||
duration: 1000, onComplete: () => txt.destroy(),
|
||
})
|
||
}
|
||
}
|