-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtext.lua
More file actions
298 lines (244 loc) · 10.5 KB
/
text.lua
File metadata and controls
298 lines (244 loc) · 10.5 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
290
291
292
293
294
295
296
297
298
local CustomFont = require("custom_font")
local Colors = require("colors")
local Settings = require("settings")
local Text = {}
local UTF8_PATTERN = "[%z\1-\127\194-\244][\128-\191]*"
CustomFont:init()
Text.charHeight = CustomFont.charHeight
function Text.drawCenteredText(text, yPosition, widthPercentage, minScale, maxScale)
local scale = Text.calculateScaleForWidth(text, widthPercentage)
if minScale and maxScale then
local height_factor = Settings.WINDOW_HEIGHT / 800
minScale = minScale * height_factor
maxScale = math.min(maxScale, maxScale * height_factor)
scale = math.max(minScale, math.min(maxScale, scale))
end
local textWidth = Text.getTextWidth(text, scale)
local x = (Settings.WINDOW_WIDTH - textWidth) / 2
Text.drawText(text, x, yPosition, scale)
end
local function drawMenuItems(menuItems, selectedItem, startY, widthPercentage)
local uniformScale = Text.calculateUniformScale(menuItems, widthPercentage)
local yPos = startY
for i, item in ipairs(menuItems) do
if i == selectedItem then
love.graphics.setColor(Colors.cyan)
else
love.graphics.setColor(Colors.white)
end
-- Use the uniform scale for all items
local textWidth = Text.getTextWidth(item.text, uniformScale)
local x = (Settings.WINDOW_WIDTH - textWidth) / 2
Text.drawText(item.text, x, yPos, uniformScale)
item.y = yPos -- Store y position for click detection
item.height = Text.getTextHeight(uniformScale) -- Uniform height based on uniform scale
yPos = yPos + 50
end
end
local function drawHighScoreFlash(hiScore, nuHiScore, hiScoreFlashVisible)
if nuHiScore and hiScoreFlashVisible then
love.graphics.setColor(Colors.neon_lime_splash)
Text.drawCenteredText("NEW HIGH", Settings.WINDOW_HEIGHT * 0.08, 0.8)
Text.drawCenteredText("SCORE!", Settings.WINDOW_HEIGHT * 0.18, 0.55)
Text.drawCenteredText(tostring(math.floor(hiScore)), Settings.WINDOW_HEIGHT * 0.27, 0.5, 12.0, 15.0)
end
end
local function drawContinuePrompt(actionText, actionTextSize, promptY, actionY)
local inputPrompt
if Settings.IS_MOBILE then
inputPrompt = "TOUCH / TAP ON SCREEN"
else
inputPrompt = "PRESS SPACE OR CLICK"
end
love.graphics.setColor(Colors.white)
Text.drawCenteredText(inputPrompt, promptY, 0.9)
Text.drawCenteredText(actionText, actionY, actionTextSize)
end
function Text.drawAttract(menuItems, selectedItem)
love.graphics.setColor(0, 0, 0, 0.5)
love.graphics.rectangle("fill", 0, 0, Settings.WINDOW_WIDTH, Settings.WINDOW_HEIGHT)
love.graphics.setColor(Colors.cyan)
Text.drawCenteredText("FLASH-BLIP", Settings.WINDOW_HEIGHT * 0.15, 0.95)
drawMenuItems(menuItems, selectedItem, Settings.WINDOW_HEIGHT * 0.4, 0.55)
Text.drawGameVersion()
love.graphics.setColor(1, 1, 1)
end
function Text.drawGameVersion()
love.graphics.setColor(Colors.light_blue_glow)
local gameVersionScale = Text.calculateScaleForWidth(GAME_VERSION, 0.09)
local gameVersionWidth = Text.getTextWidth(GAME_VERSION, gameVersionScale)
Text.drawText(
GAME_VERSION,
(Settings.WINDOW_WIDTH - gameVersionWidth) * 0.97,
Settings.WINDOW_HEIGHT * 0.97,
gameVersionScale
)
end
function Text.drawPauseMenu(menuItems, selectedItem, level_id)
love.graphics.setColor(0, 0, 0, 0.65)
love.graphics.rectangle("fill", 0, 0, Settings.WINDOW_WIDTH, Settings.WINDOW_HEIGHT)
love.graphics.setColor(Colors.cyan)
Text.drawCenteredText("PAUSED", Settings.WINDOW_HEIGHT * 0.25, 0.6)
if level_id then
local level_text = "LEVEL " .. level_id
love.graphics.setColor(Colors.spring_green)
Text.drawCenteredText(level_text, Settings.WINDOW_HEIGHT * 0.35, 0.3)
end
drawMenuItems(menuItems, selectedItem, Settings.WINDOW_HEIGHT * 0.5, 0.5)
love.graphics.setColor(1, 1, 1)
end
function Text.drawGameOver(hiScore, nuHiScore, hiScoreFlashVisible)
love.graphics.setColor(0, 0, 0, 0.65)
love.graphics.rectangle("fill", 0, 0, Settings.WINDOW_WIDTH, Settings.WINDOW_HEIGHT)
drawHighScoreFlash(hiScore, nuHiScore, hiScoreFlashVisible)
love.graphics.setColor(Colors.naranjaRojo)
Text.drawCenteredText("GAME OVER", Settings.WINDOW_HEIGHT * 0.4, 0.9)
drawContinuePrompt("TO RESTART", 0.45, Settings.WINDOW_HEIGHT * 0.55, Settings.WINDOW_HEIGHT * 0.6)
end
local function drawCompletionBackground(hiScore, nuHiScore, hiScoreFlashVisible)
love.graphics.setColor(0, 0, 0, 0.65)
love.graphics.rectangle("fill", 0, 0, Settings.WINDOW_WIDTH, Settings.WINDOW_HEIGHT)
drawHighScoreFlash(hiScore, nuHiScore, hiScoreFlashVisible)
end
function Text.drawLevelCompleted(hiScore, nuHiScore, hiScoreFlashVisible)
drawCompletionBackground(hiScore, nuHiScore, hiScoreFlashVisible)
love.graphics.setColor(Colors.neon_lime_splash)
Text.drawCenteredText("LEVEL", Settings.WINDOW_HEIGHT * 0.4, 0.5)
Text.drawCenteredText("COMPLETED!", Settings.WINDOW_HEIGHT * 0.5, 0.9)
drawContinuePrompt("TO CONTINUE", 0.5, Settings.WINDOW_HEIGHT * 0.7, Settings.WINDOW_HEIGHT * 0.75)
end
function Text.drawAllLevelsCompleted(hiScore, nuHiScore, hiScoreFlashVisible)
drawCompletionBackground(hiScore, nuHiScore, hiScoreFlashVisible)
love.graphics.setColor(Colors.neon_lime_splash)
Text.drawCenteredText("YOU COMPLETED", Settings.WINDOW_HEIGHT * 0.4, 0.95)
Text.drawCenteredText("ALL LEVELS!", Settings.WINDOW_HEIGHT * 0.48, 0.8)
Text.drawCenteredText("A GREAT FEAT!", Settings.WINDOW_HEIGHT * 0.56, 0.9)
drawContinuePrompt()
end
function Text.drawScore(score, hiScore, isMultiplying)
local currentScoreText = tostring(math.floor(score))
local scoreColor = Colors.white
local scoreScale = Text.calculateScaleForWidth(currentScoreText, 0.15)
if isMultiplying then
currentScoreText = currentScoreText .. " X4"
scoreScale = Text.calculateScaleForWidth(currentScoreText, 0.4)
scoreColor = Colors.yellow
end
-- Apply min/max scale based on window height
local height_factor = Settings.WINDOW_HEIGHT / 800
local minScale = 3 * height_factor
local maxScale = 5 * height_factor
scoreScale = math.max(minScale, math.min(maxScale, scoreScale))
love.graphics.setColor(scoreColor)
local currentScoreTextHeight = Text.getTextHeight(scoreScale)
-- Bottom left Score
Text.drawText(currentScoreText, 10, Settings.WINDOW_HEIGHT - currentScoreTextHeight - 10, scoreScale)
love.graphics.setColor(Colors.white)
local hiScoreText = "HI: " .. math.floor(hiScore)
local hiScoreScale = Text.calculateScaleForWidth(hiScoreText, 0.15)
hiScoreScale = math.max(minScale, math.min(maxScale, hiScoreScale))
local hiScoreTextWidth = Text.getTextWidth(hiScoreText, hiScoreScale)
local hiScoreTextHeight = Text.getTextHeight(hiScoreScale)
-- Bootom right High Score
Text.drawText(
hiScoreText,
Settings.WINDOW_WIDTH - hiScoreTextWidth - 10,
Settings.WINDOW_HEIGHT - hiScoreTextHeight - 10,
hiScoreScale
)
end
function Text.drawLevelProgress(current, total, finalColor)
local progress = math.min(1, current / total)
-- Bar size to just below the drawing position of the bolt powerup
local barHeight = Settings.WINDOW_HEIGHT * 0.29
local barWidth = 4
local margin = 12
local x = Settings.WINDOW_WIDTH - margin
-- Starting position it just above the Hi Score area
local hiScoreAreaHeight = Settings.WINDOW_HEIGHT * 0.05
local y = Settings.WINDOW_HEIGHT - hiScoreAreaHeight
-- Background track (dim black bar)
love.graphics.setColor(0, 0, 0, 0.8)
love.graphics.rectangle("fill", x, y - barHeight, barWidth, barHeight, 1, 1)
-- Completion Fill (Bottom to Top)
local startColor = Colors.periwinkle_mist
local endColor = finalColor or Colors.antique_gold
local fillColor = Colors.lerp(startColor, endColor, progress)
love.graphics.setColor(fillColor)
local currentHeight = barHeight * progress
love.graphics.rectangle("fill", x, y - currentHeight, barWidth, currentHeight, 1, 1)
-- Percentage text
local percentValue = math.floor(progress * 100)
local percentText = tostring(percentValue) .. "%"
-- Use a fixed reference to calculate scale so it doesn't change as numbers grow
local percentScale = Text.calculateScaleForWidth("100", 0.05)
local percentWidth = Text.getTextWidth(percentText, percentScale)
local percentHeight = Text.getTextHeight(percentScale)
love.graphics.setColor(fillColor)
Text.drawText(percentText, x - percentWidth - 2, y - currentHeight - (percentHeight / 2), percentScale)
love.graphics.setColor(1, 1, 1, 1)
end
function Text.drawTextByPercentage(text, xPosition, yPosition, widthPercentage)
local scale = Text.calculateScaleForWidth(text, widthPercentage)
Text.drawText(text, xPosition, yPosition, scale)
end
function Text.drawText(text, x, y, scale)
scale = scale or 1
local currentX = x or 0
-- Display block characters such as █.
for char in text:gmatch(UTF8_PATTERN) do
char = string.upper(char)
local glyph = CustomFont.glyphs[char]
if glyph then
for row = 1, #glyph do
for col = 1, #glyph[row] do
if glyph[row]:sub(col, col) ~= " " then
love.graphics.rectangle("fill", currentX + (col - 1) * scale, y + (row - 1) * scale, scale, scale)
end
end
end
local width = CustomFont.glyphWidths[char] or CustomFont.spaceWidth
currentX = currentX + (width + CustomFont.tracking) * scale
else
-- Character not found, advance as a space
currentX = currentX + (CustomFont.spaceWidth + CustomFont.tracking) * scale
end
end
end
function Text.getTextWidth(text, scale)
scale = scale or 1
local totalWidth = 0
for char in text:gmatch(UTF8_PATTERN) do
char = string.upper(char)
local width = CustomFont.glyphWidths[char] or CustomFont.spaceWidth
totalWidth = totalWidth + (width + CustomFont.tracking) * scale
end
return totalWidth
end
function Text.getTextHeight(scale)
scale = scale or 1
return CustomFont.charHeight * scale
end
function Text.calculateScaleForWidth(text, widthPercentage)
local targetWidth = Settings.WINDOW_WIDTH * widthPercentage
local textWidthAtScale1 = Text.getTextWidth(text, 1)
if textWidthAtScale1 == 0 then
return 1
end
return targetWidth / textWidthAtScale1
end
function Text.calculateUniformScale(menuItems, widthPercentage)
-- Find the text with the maximum width at scale 1 to determine the uniform scale
local maxWidth = 0
local maxWidthText = ""
for _, item in ipairs(menuItems) do
local textWidth = Text.getTextWidth(item.text, 1)
if textWidth > maxWidth then
maxWidth = textWidth
maxWidthText = item.text
end
end
-- Calculate the uniform scale based on the longest text
return Text.calculateScaleForWidth(maxWidthText, widthPercentage)
end
return Text