-
Notifications
You must be signed in to change notification settings - Fork 0
/
enemy.ts
108 lines (89 loc) · 3.68 KB
/
enemy.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// A subset of a pirate, but could be just an item
type EnemyTarget = { sprite: Sprite, health: number, hit: (who: Enemy, amount: number) => void }
class Enemy {
static hitSound: music.SoundEffect = music.createSoundEffect(WaveShape.Noise, 1839, 287, 255, 70, 150, SoundExpressionEffect.Warble, InterpolationCurve.Logarithmic)
public sprite: Sprite
public health: number = 1
public riches = 1
protected _speed: number = 10
protected _currentTarget: EnemyTarget
protected _nextAttackTime: number = 0
protected _lastAttackTick: number = 0
protected _facing: 'left' | 'right' = 'left'
protected _isAttacking: boolean = false
protected _lastDirectionTick: number = 0
protected _minDistanceFromTarget: number = 30
constructor({ x, y, target, sprite, riches, speed, minDistanceFromTarget }:
{
x: number,
y: number,
target: EnemyTarget,
sprite: Sprite,
riches?: number,
speed?: number,
minDistanceFromTarget?: number
}) {
this.sprite = sprite
this.sprite.x = x
this.sprite.y = y
this.riches = riches != null ? riches : 1
this._speed = speed != null ? speed : 10
this._minDistanceFromTarget = minDistanceFromTarget != null ? minDistanceFromTarget : 30
// On initial spawn they are quick to attack!
this._nextAttackTime = Math.randomRange(Militia.attackDelayMin / 2, Militia.attackDelayMax / 2)
this._lastAttackTick = control.millis()
this._currentTarget = target
}
public destroy() {
if (this.sprite) {
this.sprite.destroy()
}
}
public setCurrentTarget(pirate: EnemyTarget) {
if (pirate.health > 0 && this.health > 0) {
this._currentTarget = pirate
this.sprite.follow(this._currentTarget.sprite, this._speed)
}
}
protected walk(direction?: 'left' | 'right') {
this._facing = direction ? direction : this._facing
this.sprite.follow(this._currentTarget.sprite, this._speed)
}
protected hit({ attacker, damage }: { attacker: Pirate, damage: number }): boolean {
this.health -= damage
music.play(Enemy.hitSound, music.PlaybackMode.InBackground)
if (this.health <= 0) {
this.sprite.follow(this._currentTarget.sprite, 0)
}
return true
}
protected attack() {
// Stop moving
this.sprite.follow(this._currentTarget.sprite, 0)
this._isAttacking = true
}
protected die() {}
public render() {
// No Undead walking!
if (this.health <= 0 || this._isAttacking) return
// Check your distance from the target randomly
if ((control.millis() - this._lastDirectionTick) > Militia.directionChangeInterval) {
this._lastDirectionTick = control.millis()
if (Utils.getDistance(
{ x: this.sprite.x, y: this.sprite.y },
{ x: this._currentTarget.sprite.x, y: this._currentTarget.sprite.y }
) <= this._minDistanceFromTarget) {
this.sprite.follow(this._currentTarget.sprite, 0)
} else {
this.sprite.follow(this._currentTarget.sprite, this._speed)
}
}
// Face your target
if (this._currentTarget.sprite.x < this.sprite.x && this._facing === 'right' && !this._isAttacking) {
this.walk('left')
} else if (this._currentTarget.sprite.x > this.sprite.x && this._facing === 'left' && !this._isAttacking) {
this.walk('right')
}
this.sprite.z = this.sprite.y
}
}