-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathEnemy.elm
140 lines (100 loc) · 2.82 KB
/
Enemy.elm
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
module Enemy exposing (Enemy, tickEnemies, enemyAI, enemyViews, initEnemy)
import Mover exposing (Mover, tickMover, moverView)
import Trig exposing (targetDirection, turnDirection)
-- Enemy ships fly through the game box and try to
-- kill the rocket ship.
-- They start spawning partway into the game.
import Time exposing (Time)
import Html exposing (Html)
import Svg exposing (g)
-- Enemy is a Mover that also has hp and a weapon cooldown reload.
type alias Enemy =
Mover
{ hp : Int
, firing : Bool
, cooldown : Int
, cooldownMax : Int
}
initEnemy : Enemy
initEnemy =
{ x = 100
, y = 100
, d = 0
, s = 5.0
, ts =
10.0
-- Top speed
, acc = 0.0
, turn = 0.0
, hp = 10
, firing = False
, cooldown = 0
, cooldownMax = 12
}
-- Take a list of enemies and "tick" them (make them move
-- forward, etc). If a enemy is out of bounds, we remove it
-- from the list of enemies.
tickEnemies : Time -> List Enemy -> List Enemy
tickEnemies diff enemies =
-- TODO: Change to filterMap when we have death detection
List.map (tickEnemy diff) enemies
-- Moves/turns the enemy and cools down the weapon every tick.
tickEnemy : Time -> Enemy -> Enemy
tickEnemy diff enemy =
tickMover diff
{ enemy
| cooldown = (weaponCooldown enemy)
}
-100
-100
1100
1100
enemyAI : { b | x : Float, y : Float } -> Enemy -> Enemy
enemyAI { x, y } e =
let
td =
targetDirection (e.x - x) (e.y - y)
dir =
turnDirection td e.d
a =
if dir == 0 then
1
else
-0.25
f =
if dir == 0 then
True
else
False
in
{ e
| turn = dir
, acc = a
, firing = f
}
-- Cooldown a weapon from cooldownMax down to cooled 0.
weaponCooldown : Enemy -> Int
weaponCooldown { cooldown, cooldownMax, firing } =
if cooldown == 0 && firing then
cooldownMax
else
clamp 0 cooldownMax (cooldown - 1)
-- Renders all enemies from a list of enemies.
-- `g` is an svg "group". We're grouping all enemies in the SVG output.
-- Really just a convenience so I can return one SVG node.
enemyViews : List Enemy -> Html msg
enemyViews enemies =
g [] (List.map enemyView enemies)
-- Renders the enemy with the provided SVGs.
-- If the enemy is accelerating, shows the enemy rocket engines
-- burning. 40x40 px within the 1000x1000 game box.
enemyView : Enemy -> Html msg
enemyView enemy =
let
enemyImg =
if enemy.acc > 0 then
"./assets/rocket-3-burn.svg"
else
"./assets/rocket-3.svg"
in
moverView enemy enemyImg ( 40, 40 )