-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblock.lua
More file actions
292 lines (221 loc) · 6.79 KB
/
block.lua
File metadata and controls
292 lines (221 loc) · 6.79 KB
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
--
-- Block mechanics
--
Block = class:new()
-- These properties are shared for all block instances
Block.spawnpoint = math.floor(windowHeight / 2)
Block.gapMinSize = blockGapMinSize
Block.gapMaxSize = blockGapMaxSize
Block.gapSize = blockGapMaxSize
Block.randomSpawnGapMin = blockRandomSpawnGapMin
Block.wallsDirection = true -- `true` for up, `false` for down
--
-- Init
--
function Block:init (x, y, w, h, color, moving, speedX, speedY, bounds)
self.x = x or blockX
self.y = y or blockY
self.w = w or blockWidth
self.h = h or blockHeight
self.color = color or colorBlock
self.moving = moving or blockMoving
self.speedX = speedX or blockSpeedX
self.speedY = speedY or blockSpeedY
self.bounds = bounds or blockBounds
self.hitbox = {
x1 = self.x,
y1 = self.y,
x2 = self.x + self.w,
y2 = self.y + self.h
}
end
--
-- Debug
--
function Block:debugPrint ()
msg = {
"x: "..self.x.."\n",
"y: "..self.y.."\n",
"w: "..self.w.."\n",
"h: "..self.h.."\n",
"moving: "..tostring(self.moving).."\n",
"speed: "..self.speedX..", "..self.speedY.."\n",
}
print("-- Block info: ---\n"..table.concat(msg))
end
--
-- Clamp to boundaries
--
local clamp = function (n, min, max) return n < min and min or (n > max and max or n) end
--
-- Set block x coordinate and check bounds
--
function Block: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 block y coordinate and check bounds
--
function Block: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 block
--
function Block:move (dx, dy, speedX, speedY)
local dx = dx or 0
local dy = dy or 0
local speedX = speedX or self.speedX
local speedY = speedY or self.speedY
dx = dx * speedX or 0
dy = dy * speedY or 0
self:setX(self.x - dx)
self:setY(self.y - dy)
end
--
-- Update hitbox
--
function Block:updateHitbox ()
self.hitbox = {
x1 = self.x,
y1 = self.y,
x2 = self.x + self.w,
y2 = self.y + self.h
}
end
--
-- Offscreen check
--
function Block:isOffscreen (bounds)
-- Define boundaries
local x1,y1 = self.x, self.y
local x2,y2 = self.x + self.w, self.y + self.h
local bx1, bx2 = bounds.x1, bounds.x2
local by1, by2 = bounds.y1, bounds.y2
-- Check each side of the window
local left = x2 < bx1 -- right edge of block is past the left edge
local right = x1 > bx2 -- left edge of block is past the right edge
local top = y2 < by1 -- top edge of block is past the bottom edge
local bottom = y1 > by2 -- bottom edge of block is past the top edge
-- Return offscreen status
return left or right or top or bottom
end
--
-- Spawn a random block
--
-- NOTE Updates are performed when calling updateWalls()
--
function Block:spawnBlock (color, spawnX, spawnY)
local c = color or self.color
local x = spawnX or camera.bounds.x2
local w = blockWidth
local h = blockHeight
local y = spawnY or Block.spawnpoint - math.floor(h / 2)
-- Return new block instances
return Block:new(x, y, w, h, c)
end
--
-- Return new walls and update spawning parameters
--
function Block:spawnWalls (spawnX, spawnY, color)
local x,y = spawnX, spawnY
local c = color or self.color
local above = above or false
local w = blockWidth
-- Spawn the block above the spawnpoint
local y1 = y
local h1 = math.max(Block.spawnpoint - math.ceil(Block.gapSize / 2), blockMargin)
-- Spawn the block below the spawnpoint
local y2 = math.min(Block.spawnpoint + math.floor(Block.gapSize / 2), camera.bounds.y2 - blockMargin)
local h2 = camera.bounds.y2 - y2
-- Update spawn parameters
Block.updateWalls(camera.bounds)
-- Return new block instances
return {
Block:new(x, y1, w, h1, c),
Block:new(x, y2, w, h2, c)
}
end
--
-- Update walls spawnpoint
--
-- TODO Make the top and bottom walls change independently of each other?
--
function Block.updateWalls (bounds)
-- Fetch current parameters
local y,ymin,ymax = Block.spawnpoint, bounds.y1 + blockMargin, bounds.y2 - blockMargin
--local g,gmin,gmax = Block.gapSize, Block.gapMinSize, Block.gapMaxSize
-- Randomize the y value change
local dyList = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5}
-- Get a random value from the table above
local dy = dyList[rng(1, #dyList)]
-- Subtract (move up) if direction is true, add (move down) if false
if Block.wallsDirection then dy = y - dy else dy = y + dy end
-- Clamp the changes to the boundaries
dy = clamp(math.floor(dy), ymin, ymax)
-- Reverse direction if top or bottom is reached
local wallsTop = y == ymin and Block.wallsDirection
local wallsBottom = y == ymax and not Block.wallsDirection
if wallsTop or wallsBottom then
Block.wallsDirection = not Block.wallsDirection
-- Randomize the gap size change
--local dg = rng(66, 150) / 100
--g = clamp(math.floor(g * dg), gmin, gmax)
end
-- Set the changed values
Block.spawnpoint = dy
--Block.gapSize = dg
end
--
-- Load callback
--
function Block:load ()
end
--
-- Update callback
--
function Block:update (dt)
self:updateHitbox()
end
--
-- Draw callback
--
function Block:draw ()
love.graphics.setColor(self.color)
-- If not debugging, fill the whole block
local fill = ""
if debugBlock and not debugNone or debugAll then fill = "line" else fill = "fill" end
-- Draw the block
love.graphics.rectangle( fill,
self.x,
self.y,
self.w,
self.h )
-- Draw debug overlays
if debugBlock and not debugNone or debugAll then
-- Block outline
--love.graphics.setColor(debugColorHitbox)
--love.graphics.rectangle( "line",
-- self.x,
-- self.y,
-- self.w,
-- self.h )
-- Spawnpoint
love.graphics.setColor(debugColorMarker)
love.graphics.rectangle( "fill",
camera.bounds.x2,
Block.spawnpoint,
2,
2 )
end
end