-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelicopter.lua
303 lines (236 loc) · 6.85 KB
/
helicopter.lua
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
--
-- Helicopter prototype
--
Helicopter = class:new()
--
-- init
--
function Helicopter:init (x, y, speedX, liftSpeed, liftDelay, fallSpeed, fallDelay, bounds, hitbox, hitboxTolerance, scale)
-- Coordinates
self.x = x or 0
self.y = y or 0
-- Scaling
self.scale = scale or helicopterScale
-- Velocity and acceleration
self.speedX = speedX or helicopterSpeedX
self.liftSpeed = liftSpeed or helicopterLiftSpeed
self.liftDelay = liftDelay or helicopterLiftDelay
self.liftElapsedTime = 0
self.fallSpeed = fallSpeed or helicopterFallSpeed
self.fallDelay = fallDelay or helicopterFallDelay
self.fallElapsedTime = 0
-- Boundaries
self.bounds = bounds or helicopterBounds
-- Image paths
self.imgPath = helicopterImgPath
self.fireImagePath = helicopterFireImgPath
-- Load images
self.image = love.graphics.newImage(self.imgPath) -- current image
self.normalImage = love.graphics.newImage(self.imgPath)
self.fireImage = love.graphics.newImage(self.fireImagePath)
-- Animation-related things
self.frames = {}
self.frames.total = spriteFrames
self.frames.list = {}
self.frames.w = spriteWidth
self.frames.h = spriteHeight
self.frames.current = 1
self.delay = spriteAnimationDelay
self.elapsedTime = 0
-- Build the frames list
for f=1,self.frames.total do
self.frames.list[f] = QuadData:new( self.image,
(f-1) * self.frames.w,
0,
self.frames.w,
self.frames.h,
self.frames.w * self.frames.total,
self.frames.h )
end
-- Hitbox
self.hitbox = hitbox or helicopterHitbox
self.hitboxTolerance = hitboxTolerance or helicopterHitboxTolerance
-- Statuses
self.falling = false
self.lifting = false
self.crashed = false
end
--
-- Clamp to window boundaries
--
local clamp = function (n, min, max) return n < min and min or (n > max and max or n) end
--
-- Debug
--
function Helicopter:debugPrint ()
msg = {
"x: "..self.x.."\n",
"y: "..self.y.."\n",
}
print("-- Helicopter info: ---\n"..table.concat(msg))
end
--
-- Animation
--
function Helicopter:animate (dt)
-- Add to elapsed time
self.elapsedTime = self.elapsedTime + dt
-- Increment frame if delay has been passed
if self.delay <= self.elapsedTime then
self.elapsedTime = self.elapsedTime - self.delay
self.frames.current = self.frames.current % (self.frames.total) + 1
end
end
--
-- Set helicopter x coordinate and check bounds
--
function Helicopter:setX (x)
if self.bounds then
self.x = clamp(x, self.bounds.x1, self.bounds.x2)
else
self.x = x
end
self:updateHitbox()
end
--
-- Set helicopter y coordinate and check bounds
--
function Helicopter:setY (y)
if self.bounds then
self.y = clamp(y, self.bounds.y1, self.bounds.y2)
else
self.y = y
end
self:updateHitbox()
end
--
-- Move the helicopter
--
function Helicopter:move (dx, dy, speedX, liftSpeed, fallSpeed)
local dx = dx or 0
local dy = dy or 0
local speedX = speedX or self.speedX
local liftSpeed = liftSpeed or self.liftSpeed
local fallSpeed = fallSpeed or self.fallSpeed
dx = dx * speedX or 0
dy = dy or 0
if dy > 0 then
dy = dy * liftSpeed
elseif dy < 0 then
dy = dy * fallSpeed
end
self:setX(self.x + dx)
self:setY(self.y - dy)
end
--
-- Crash the helicopter
--
function Helicopter:crash ()
self.crashed = true
self.image = self.fireImage
end
--
-- Update hitbox
--
function Helicopter:updateHitbox ()
local x,y = self.x, self.y
local w,h = self.frames.w, self.frames.h
local t = self.hitboxTolerance
local s = self.scale
self.hitbox = {
x1 = x + (t.x1 * s),
y1 = y + (t.y1 * s),
x2 = x + ((w - t.x2) * s),
y2 = y + ((h - t.y2) * s)
}
end
--
-- Collision detection
--
function Helicopter:detectCollisions (obj)
-- If crashed, skip collision detection
if self.crashed then return end
-- Setup locals
local collision = false
local hurtbox = self.hitbox
-- Detect collision with provided hitbox
if obj then
local hitbox = obj.hitbox
local left = hurtbox.x2 >= hitbox.x1
local right = hurtbox.x1 <= hitbox.x2
local top = hurtbox.y2 >= hitbox.y1
local bottom = hurtbox.y1 <= hitbox.y2
if left and top and bottom and right then collision = true end
-- Detect collision with boundaries if no obj is provided
else
local hitbox = self.bounds
local y = self.y
local top = hurtbox.y2 <= hitbox.y1
local bottom = hurtbox.y1 >= hitbox.y2
if top or bottom then collision = true end
end
return collision
end
--
-- Set bounds
--
function Helicopter:setBounds (bounds)
self.bounds = bounds
end
--
-- Move bounds
--
function Helicopter:moveBounds (dx,dy)
local dx = dx or 0
local dy = dy or 0
local x1,x2 = self.bounds.x1, self.bounds.x2
local y1,y2 = self.bounds.y1, self.bounds.y2
local bounds = {
x1 = x1 + dx,
x2 = x2 + dx,
y1 = y1 + dy,
y2 = y2 + dy
}
self:setBounds(bounds)
end
--
-- Load callback
--
function Helicopter:load ()
end
--
-- Update callback
--
function Helicopter:update (dt)
self:animate(dt)
end
--
-- Draw callback
--
function Helicopter:draw ()
-- Draw the helicopter
love.graphics.draw( self.image,
self.frames.list[self.frames.current].quad,
self.x,
self.y,
0,
self.scale,
self.scale )
-- Draw debug overlays
if debugHelicopter and not debugNone or debugAll then
-- Draw sprite outline
love.graphics.setColor(debugColorOutline)
love.graphics.rectangle( "line",
self.x,
self.y,
self.frames.w * self.scale,
self.frames.h * self.scale )
-- Draw hitbox
love.graphics.setColor(debugColorHitbox)
love.graphics.rectangle( "line",
self.hitbox.x1,
self.hitbox.y1,
self.hitbox.x2 - self.hitbox.x1,
self.hitbox.y2 - self.hitbox.y1 )
end
end