Compare commits
1 Commits
47e5e0ca17
...
credits-wi
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ba02c894c |
@@ -24,6 +24,7 @@ globals = {
|
||||
"Minigame",
|
||||
"Window",
|
||||
"ContinuedWindow",
|
||||
"CreditsWindow",
|
||||
"TTGIntroWindow",
|
||||
"BriefIntroWindow",
|
||||
"TitleIntroWindow",
|
||||
@@ -38,10 +39,6 @@ globals = {
|
||||
"MysteriousManScreen",
|
||||
"DiscussionWindow",
|
||||
"EndWindow",
|
||||
"PlayerNameWindow",
|
||||
"TextInput",
|
||||
"CodeGenerator",
|
||||
"CreditsWindow",
|
||||
"mset",
|
||||
"mget",
|
||||
"btnp",
|
||||
|
||||
@@ -6,7 +6,6 @@ init/init.context.lua
|
||||
system/system.util.lua
|
||||
system/system.print.lua
|
||||
system/system.input.lua
|
||||
system/system.textinput.lua
|
||||
system/system.mouse.lua
|
||||
system/system.asciiart.lua
|
||||
system/system.rle.lua
|
||||
@@ -17,7 +16,6 @@ logic/logic.timer.lua
|
||||
logic/logic.trigger.lua
|
||||
logic/logic.minigame.lua
|
||||
logic/logic.glitch.lua
|
||||
logic/logic.codegenerator.lua
|
||||
logic/logic.discussion.lua
|
||||
system/system.ui.lua
|
||||
audio/audio.manager.lua
|
||||
@@ -82,7 +80,6 @@ window/window.minigame.ddr.lua
|
||||
window/window.discussion.lua
|
||||
window/window.continued.lua
|
||||
window/window.credits.lua
|
||||
window/window.player_name.lua
|
||||
window/window.game.lua
|
||||
system/system.main.lua
|
||||
meta/meta.assets.lua
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
--- @section CodeGenerator
|
||||
|
||||
CodeGenerator = {}
|
||||
|
||||
local SALT = 27471
|
||||
local BASE36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local NAME_LEN = 3
|
||||
|
||||
-- Per-position offsets derived from SALT so each character slot
|
||||
-- maps to a different region of the 2-char base-36 space.
|
||||
local SALTS = {
|
||||
SALT % 36,
|
||||
math.floor(SALT / 36) % 36,
|
||||
math.floor(SALT / 1296) % 36,
|
||||
}
|
||||
|
||||
--- Encodes a number (0–935) as exactly 2 base-36 characters.
|
||||
--- @within CodeGenerator
|
||||
function CodeGenerator.encode_pair(n)
|
||||
return BASE36:sub(math.floor(n / 36) + 1, math.floor(n / 36) + 1)
|
||||
.. BASE36:sub(n % 36 + 1, n % 36 + 1)
|
||||
end
|
||||
|
||||
--- Decodes 2 base-36 characters back to a number.
|
||||
--- @within CodeGenerator
|
||||
function CodeGenerator.decode_pair(s)
|
||||
local d1 = BASE36:find(s:sub(1, 1), 1, true) - 1
|
||||
local d2 = BASE36:find(s:sub(2, 2), 1, true) - 1
|
||||
return d1 * 36 + d2
|
||||
end
|
||||
|
||||
--- Encrypts a player name into a code twice its length.
|
||||
--- Each input character (A-Z, value 0-25) is encoded as
|
||||
--- c + SALTS[i] * 26, producing 2 base-36 output characters.
|
||||
--- @within CodeGenerator
|
||||
--- @param text string NAME_LEN-character uppercase player name.
|
||||
--- @return string Encrypted code (2 * NAME_LEN base-36 characters).
|
||||
function CodeGenerator.encrypt(text)
|
||||
local result = ""
|
||||
for i = 1, NAME_LEN do
|
||||
local c = math.max(0, (string.byte(text, i) or 65) - 65)
|
||||
result = result .. CodeGenerator.encode_pair(c + SALTS[i] * 26)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
--- Decrypts a personal code back to the original player name.
|
||||
--- @within CodeGenerator
|
||||
--- @param encrypted_text string The code to decrypt (2 * NAME_LEN chars).
|
||||
--- @return string Original player name, or "???" if the code is invalid.
|
||||
function CodeGenerator.decrypt(encrypted_text)
|
||||
local t = encrypted_text:upper()
|
||||
if #t ~= NAME_LEN * 2 then return "???" end
|
||||
local result = ""
|
||||
for i = 1, NAME_LEN do
|
||||
local pair = CodeGenerator.decode_pair(t:sub((i - 1) * 2 + 1, i * 2))
|
||||
result = result .. string.char(pair % 26 + 65)
|
||||
end
|
||||
return result
|
||||
end
|
||||
@@ -30,9 +30,3 @@ function Input.back() return btnp(INPUT_KEY_B) or keyp(INPUT_KEY_BACKSPACE) end
|
||||
--- Checks if Enter is pressed.
|
||||
--- @within Input
|
||||
function Input.enter() return keyp(INPUT_KEY_ENTER) end
|
||||
--- Checks if Up is pressed or held (with repeat).
|
||||
--- @within Input
|
||||
function Input.up_repeat() return btnp(INPUT_KEY_UP, 20, 4) end
|
||||
--- Checks if Down is pressed or held (with repeat).
|
||||
--- @within Input
|
||||
function Input.down_repeat() return btnp(INPUT_KEY_DOWN, 20, 4) end
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
--- @section TextInput
|
||||
|
||||
TextInput = {}
|
||||
|
||||
local LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
local _pos = {}
|
||||
local _cursor = 1
|
||||
local _max_len = 3
|
||||
|
||||
--- Initialises a new text input session.
|
||||
--- @within TextInput
|
||||
--- @param max_len number Maximum character count (default 3).
|
||||
function TextInput.init(max_len)
|
||||
_max_len = max_len or 3
|
||||
_pos = {}
|
||||
for i = 1, _max_len do _pos[i] = 1 end
|
||||
_cursor = 1
|
||||
end
|
||||
|
||||
--- Advances to the next letter at the cursor position (wraps Z→A).
|
||||
--- @within TextInput
|
||||
function TextInput.next_letter()
|
||||
_pos[_cursor] = (_pos[_cursor] % #LETTERS) + 1
|
||||
end
|
||||
|
||||
--- Goes back to the previous letter at the cursor position (wraps A→Z).
|
||||
--- @within TextInput
|
||||
function TextInput.prev_letter()
|
||||
_pos[_cursor] = ((_pos[_cursor] - 2) % #LETTERS) + 1
|
||||
end
|
||||
|
||||
--- Confirms the current letter and advances the cursor to the next position.
|
||||
--- When called on the last position the cursor moves into the done state.
|
||||
--- @within TextInput
|
||||
function TextInput.select_letter()
|
||||
if _cursor <= _max_len then _cursor = _cursor + 1 end
|
||||
end
|
||||
|
||||
--- Moves the cursor one position to the right (stops at last position).
|
||||
--- @within TextInput
|
||||
function TextInput.next_position()
|
||||
if _cursor < _max_len then _cursor = _cursor + 1 end
|
||||
end
|
||||
|
||||
--- Moves the cursor one position to the left (stops at first position).
|
||||
--- Also steps back out of the done state.
|
||||
--- @within TextInput
|
||||
function TextInput.prev_position()
|
||||
if _cursor > 1 then _cursor = _cursor - 1 end
|
||||
end
|
||||
|
||||
--- Returns the assembled name string.
|
||||
--- @within TextInput
|
||||
--- @return string
|
||||
function TextInput.get_name()
|
||||
local s = ""
|
||||
for i = 1, _max_len do s = s .. LETTERS:sub(_pos[i], _pos[i]) end
|
||||
return s
|
||||
end
|
||||
|
||||
--- Returns the current 1-based cursor position.
|
||||
--- @within TextInput
|
||||
--- @return number
|
||||
function TextInput.get_position()
|
||||
return _cursor
|
||||
end
|
||||
|
||||
--- Returns the letter at the given 1-based position.
|
||||
--- @within TextInput
|
||||
--- @param i number
|
||||
--- @return string
|
||||
function TextInput.get_letter(i)
|
||||
return LETTERS:sub(_pos[i], _pos[i])
|
||||
end
|
||||
|
||||
--- Returns true when all positions have been confirmed.
|
||||
--- @within TextInput
|
||||
--- @return boolean
|
||||
function TextInput.is_done()
|
||||
return _cursor > _max_len
|
||||
end
|
||||
197
inc/window/window.credits.lua
Normal file
197
inc/window/window.credits.lua
Normal file
@@ -0,0 +1,197 @@
|
||||
--- @section CreditsWindow
|
||||
|
||||
local _time = 0.0
|
||||
local _scroll_x = 0.0
|
||||
local _scroll_total_w = 0
|
||||
local _scroll_chars = {}
|
||||
local _title_chars = {}
|
||||
local _title_total_w = 0
|
||||
local _stars = {}
|
||||
|
||||
local TITLE = "TELETYPE GAMES"
|
||||
|
||||
local SCROLL_PARTS = {
|
||||
"WEB: GAMES.TELETYPE.HU",
|
||||
"BBS: GAMES.TELETYPE.HU:2323",
|
||||
"IRC: LIBERA.CHAT #TELETYPEGAMES",
|
||||
"YOUTUBE.COM/@TELETYPEGAMES",
|
||||
}
|
||||
|
||||
local SCROLL_SEP = " * "
|
||||
|
||||
local SCROLL_SPEED = 55.0
|
||||
local SCROLL_Y = 129
|
||||
local SCROLL_ZONE_COLS = { 7, 4, 9 }
|
||||
|
||||
local TITLE_Y = 4
|
||||
local TITLE_FALL_DUR = 0.45
|
||||
local TITLE_DELAY_STEP = 0.18
|
||||
|
||||
local RASTER_COLS = { 1, 3, 9, 10, 11, 4, 11, 10, 9, 3, 1 }
|
||||
local RASTER_Y_TOP = 26
|
||||
local RASTER_Y_BOT = 110
|
||||
|
||||
local AUTHORS = {
|
||||
"Mr. Zero - Zsolt Tasnadi",
|
||||
"Mr. One - Balazs Tari",
|
||||
"Mr. Two - Zoltan Timar",
|
||||
"Mr. Three - Bela Mezo",
|
||||
}
|
||||
local AUTHORS_BASE_Y = 56
|
||||
local AUTHORS_LINE_H = 12
|
||||
local AUTHORS_ENTRY_DT = 0.65
|
||||
local AUTHORS_ENTRY_V = 2.5
|
||||
|
||||
local RAINBOW = { 4, 9, 3, 7, 13, 2, 9, 4 }
|
||||
local NUM_STARS = 40
|
||||
|
||||
--- Initialises credits state and pre-computes character metrics.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.init()
|
||||
_time = 0.0
|
||||
_scroll_x = Config.screen.width + 4.0
|
||||
|
||||
_title_chars = {}
|
||||
_title_total_w = 0
|
||||
for i = 1, #TITLE do
|
||||
local ch = TITLE:sub(i, i)
|
||||
local w = print(ch, 0, -100, 0, false, 2)
|
||||
_title_chars[i] = { ch = ch, ox = _title_total_w, w = w }
|
||||
_title_total_w = _title_total_w + w
|
||||
end
|
||||
|
||||
_scroll_chars = {}
|
||||
_scroll_total_w = 0
|
||||
local function append_str(str, col)
|
||||
for i = 1, #str do
|
||||
local ch = str:sub(i, i)
|
||||
local w = print(ch, 0, -100, 0, false, 1)
|
||||
_scroll_chars[#_scroll_chars + 1] = { ch = ch, ox = _scroll_total_w, w = w, col = col }
|
||||
_scroll_total_w = _scroll_total_w + w
|
||||
end
|
||||
end
|
||||
for _, part in ipairs(SCROLL_PARTS) do
|
||||
append_str(part, RAINBOW[math.random(#RAINBOW)])
|
||||
append_str(SCROLL_SEP, Config.colors.white)
|
||||
end
|
||||
|
||||
_stars = {}
|
||||
for i = 1, NUM_STARS do
|
||||
_stars[i] = {
|
||||
x = math.random(0, Config.screen.width - 1) + 0.0,
|
||||
y = math.random(0, Config.screen.height - 1),
|
||||
spd = (i % 3 + 1) * 10.0,
|
||||
col = ({ 1, 2, 4, 4 })[(i % 4) + 1],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_stars()
|
||||
for _, s in ipairs(_stars) do
|
||||
pix(math.floor(s.x), s.y, s.col)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_rasters()
|
||||
local cy = RASTER_Y_TOP + math.floor(math.sin(_time * 1.3) * 6)
|
||||
for i, col in ipairs(RASTER_COLS) do
|
||||
local y = cy + i - 1
|
||||
if y >= 0 and y < Config.screen.height then
|
||||
line(0, y, Config.screen.width - 1, y, col)
|
||||
end
|
||||
end
|
||||
local cy2 = RASTER_Y_BOT + math.floor(math.sin(_time * 1.7 + 1.5) * 5)
|
||||
for i, col in ipairs(RASTER_COLS) do
|
||||
local y = cy2 + i - 1
|
||||
if y >= 0 and y < Config.screen.height then
|
||||
line(0, y, Config.screen.width - 1, y, col)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function bounce_out(p)
|
||||
local n1, d1 = 7.5625, 2.75
|
||||
if p < 1 / d1 then
|
||||
return n1 * p * p
|
||||
elseif p < 2 / d1 then
|
||||
p = p - 1.5 / d1; return n1 * p * p + 0.75
|
||||
elseif p < 2.5 / d1 then
|
||||
p = p - 2.25 / d1; return n1 * p * p + 0.9375
|
||||
else
|
||||
p = p - 2.625 / d1; return n1 * p * p + 0.984375
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_title()
|
||||
local sx = math.floor((Config.screen.width - _title_total_w) / 2)
|
||||
local n = #_title_chars
|
||||
local max_dist = (n - 1) / 2.0
|
||||
for i, tc in ipairs(_title_chars) do
|
||||
local dist = math.abs(i - (n + 1) / 2.0)
|
||||
local delay = (max_dist - dist) * TITLE_DELAY_STEP
|
||||
local t = math.max(0, _time - delay)
|
||||
local p = math.min(1, t / TITLE_FALL_DUR)
|
||||
local y = math.floor(-14 + bounce_out(p) * (TITLE_Y + 14))
|
||||
print(tc.ch, sx + tc.ox + 1, y + 1, 0, false, 2)
|
||||
print(tc.ch, sx + tc.ox, y, Config.colors.light_blue, false, 2)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_authors()
|
||||
local col = Config.colors.light_blue
|
||||
for i, lbl in ipairs(AUTHORS) do
|
||||
local enter_t = math.max(0, _time - (i - 1) * AUTHORS_ENTRY_DT)
|
||||
local slide = math.max(0, 1 - enter_t * AUTHORS_ENTRY_V)
|
||||
local x_off = math.floor(slide * (Config.screen.width + 40))
|
||||
local yo = (slide < 0.01) and math.floor(math.sin(_time * 2.0 + i * 1.1) * 2) or 0
|
||||
Print.text(lbl, 12 + x_off, AUTHORS_BASE_Y + (i - 1) * AUTHORS_LINE_H + yo, col)
|
||||
end
|
||||
end
|
||||
|
||||
local function draw_scroller()
|
||||
local third = Config.screen.width / 3
|
||||
for pass = 0, 1 do
|
||||
local base = _scroll_x + pass * _scroll_total_w
|
||||
for _, sc in ipairs(_scroll_chars) do
|
||||
local x = math.floor(base + sc.ox)
|
||||
if x >= Config.screen.width then break end
|
||||
if x + sc.w > 0 then
|
||||
local zone = math.max(1, math.min(3, math.floor(x / third) + 1))
|
||||
print(sc.ch, x, SCROLL_Y, SCROLL_ZONE_COLS[zone], false, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws the credits window.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.draw()
|
||||
cls(Config.colors.black)
|
||||
draw_stars()
|
||||
draw_rasters()
|
||||
draw_title()
|
||||
Print.text_center("Authors", Config.screen.width / 2, 47, Config.colors.light_grey)
|
||||
draw_authors()
|
||||
draw_scroller()
|
||||
|
||||
end
|
||||
|
||||
--- Updates credits window logic.
|
||||
--- @within CreditsWindow
|
||||
function CreditsWindow.update()
|
||||
_time = _time + Context.delta_time
|
||||
|
||||
for _, s in ipairs(_stars) do
|
||||
s.x = s.x + s.spd * Context.delta_time
|
||||
if s.x >= Config.screen.width then s.x = s.x - Config.screen.width end
|
||||
end
|
||||
|
||||
_scroll_x = _scroll_x - SCROLL_SPEED * Context.delta_time
|
||||
if _scroll_x <= -_scroll_total_w then
|
||||
_scroll_x = _scroll_x + _scroll_total_w
|
||||
end
|
||||
|
||||
if Input.back() or Input.select() then
|
||||
Window.set_current("menu")
|
||||
end
|
||||
end
|
||||
@@ -30,15 +30,9 @@ function EndWindow.draw()
|
||||
Print.text(yes_text, centerX - 40, y, yes_color)
|
||||
Print.text(no_text, centerX + 10, y, no_color)
|
||||
elseif Context._end.state == "ending" then
|
||||
local cx = Config.screen.width / 2
|
||||
local name = Context.player_name or "AAA"
|
||||
local code = CodeGenerator.encrypt(name)
|
||||
Print.text_center("Game over -- good ending.", cx, 40, Config.colors.light_blue)
|
||||
Print.text_center("Congrats " .. name .. "!", cx, 54, Config.colors.white)
|
||||
Print.text_center("Your personal code:", cx, 72, Config.colors.light_grey)
|
||||
Print.text_center(code, cx, 84, Config.colors.white, false, 3)
|
||||
Print.text_center("Write it down!", cx, 112, Config.colors.item)
|
||||
Print.text_center("Press Z to return to menu", cx, 126, Config.colors.dark_grey)
|
||||
Print.text_center("Game over -- good ending.", Config.screen.width / 2, 50, Config.colors.light_blue)
|
||||
Print.text_center("Congratulations!", Config.screen.width / 2, 70, Config.colors.white)
|
||||
Print.text_center("Press Z to return to menu", Config.screen.width / 2, 110, Config.colors.light_grey)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -102,13 +102,17 @@ function MenuWindow.update()
|
||||
end
|
||||
end
|
||||
|
||||
--- Opens player name entry then starts a new game.
|
||||
--- Starts a new game from the menu.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.new_game()
|
||||
PlayerNameWindow.init(function()
|
||||
Context.new_game()
|
||||
end)
|
||||
Window.set_current("player_name")
|
||||
Context.new_game()
|
||||
end
|
||||
|
||||
--- Loads a game from the menu.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.load_game()
|
||||
Context.load_game()
|
||||
GameWindow.set_state("game")
|
||||
end
|
||||
|
||||
--- Saves the current game from the menu.
|
||||
@@ -135,13 +139,6 @@ function MenuWindow.controls()
|
||||
Window.set_current("controls")
|
||||
end
|
||||
|
||||
--- Opens the player name entry screen (test mode shortcut).
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.player_name()
|
||||
PlayerNameWindow.init()
|
||||
Window.set_current("player_name")
|
||||
end
|
||||
|
||||
--- Opens the credits screen.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.credits()
|
||||
@@ -149,7 +146,6 @@ function MenuWindow.credits()
|
||||
Window.set_current("credits")
|
||||
end
|
||||
|
||||
|
||||
--- Opens the audio test menu.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.audio_test()
|
||||
@@ -164,14 +160,6 @@ function MenuWindow.continued()
|
||||
GameWindow.set_state("continued")
|
||||
end
|
||||
|
||||
--- Opens the end screen for testing.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.end_screen()
|
||||
Context._end.state = "ending"
|
||||
Context._end.selection = 1
|
||||
GameWindow.set_state("end")
|
||||
end
|
||||
|
||||
--- Opens the DDR minigame test.
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.ddr_test()
|
||||
@@ -190,6 +178,7 @@ function MenuWindow.refresh_menu_items()
|
||||
end
|
||||
|
||||
table.insert(_menu_items, {label = "New Game", decision = MenuWindow.new_game})
|
||||
table.insert(_menu_items, {label = "Load Game", decision = MenuWindow.load_game})
|
||||
table.insert(_menu_items, {label = "Controls", decision = MenuWindow.controls})
|
||||
table.insert(_menu_items, {label = "Credits", decision = MenuWindow.credits})
|
||||
|
||||
@@ -197,8 +186,6 @@ function MenuWindow.refresh_menu_items()
|
||||
table.insert(_menu_items, {label = "Audio Test", decision = MenuWindow.audio_test})
|
||||
table.insert(_menu_items, {label = "To Be Continued...", decision = MenuWindow.continued})
|
||||
table.insert(_menu_items, {label = "DDR Test", decision = MenuWindow.ddr_test})
|
||||
table.insert(_menu_items, {label = "End Screen", decision = MenuWindow.end_screen})
|
||||
table.insert(_menu_items, {label = "Player Name", decision = MenuWindow.player_name})
|
||||
end
|
||||
|
||||
table.insert(_menu_items, {label = "Exit", decision = MenuWindow.exit})
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
--- @section PlayerNameWindow
|
||||
|
||||
local _frame = 0
|
||||
local _on_confirm = nil
|
||||
local MAX_LEN = 3
|
||||
local BOX_W = 24
|
||||
local BOX_H = 24
|
||||
local BOX_GAP = 12
|
||||
local BOX_Y = 50
|
||||
local WARN_Y = 104
|
||||
|
||||
local function box_start_x()
|
||||
return math.floor((Config.screen.width - (MAX_LEN * BOX_W + (MAX_LEN - 1) * BOX_GAP)) / 2)
|
||||
end
|
||||
|
||||
local function box_x(i)
|
||||
return box_start_x() + (i - 1) * (BOX_W + BOX_GAP)
|
||||
end
|
||||
|
||||
--- Initialises the player name window.
|
||||
--- @within PlayerNameWindow
|
||||
--- @param on_confirm function Called with the entered name when the player saves.
|
||||
function PlayerNameWindow.init(on_confirm)
|
||||
_frame = 0
|
||||
_on_confirm = on_confirm
|
||||
TextInput.init(MAX_LEN)
|
||||
end
|
||||
|
||||
local function draw_boxes()
|
||||
local cursor = TextInput.get_position()
|
||||
local blink = math.floor(_frame / 18) % 2 == 0
|
||||
|
||||
for i = 1, MAX_LEN do
|
||||
local x = box_x(i)
|
||||
local is_cur = (i == cursor)
|
||||
local done = TextInput.is_done()
|
||||
|
||||
local fill = (is_cur and not done) and Config.colors.blue or Config.colors.black
|
||||
local border = (is_cur and not done) and Config.colors.white
|
||||
or done and Config.colors.light_blue
|
||||
or Config.colors.dark_grey
|
||||
|
||||
rect (x, BOX_Y, BOX_W, BOX_H, fill)
|
||||
rectb(x, BOX_Y, BOX_W, BOX_H, border)
|
||||
|
||||
local show = not (is_cur and blink and not done)
|
||||
if show then
|
||||
local ch = TextInput.get_letter(i)
|
||||
local cw = print(ch, 0, -100, 0, false, 2)
|
||||
local cx = x + math.floor((BOX_W - cw) / 2)
|
||||
local cy = BOX_Y + math.floor((BOX_H - 11) / 2)
|
||||
local col = (is_cur and not done) and Config.colors.white or Config.colors.light_grey
|
||||
print(ch, cx, cy, col, false, 2)
|
||||
end
|
||||
end
|
||||
|
||||
-- caret arrow below active box
|
||||
if not TextInput.is_done() then
|
||||
local cx = box_x(cursor) + math.floor(BOX_W / 2)
|
||||
local ay = BOX_Y + BOX_H + 4
|
||||
line(cx - 4, ay, cx, ay + 4, Config.colors.white)
|
||||
line(cx + 4, ay, cx, ay + 4, Config.colors.white)
|
||||
end
|
||||
end
|
||||
|
||||
--- Draws the player name window.
|
||||
--- @within PlayerNameWindow
|
||||
function PlayerNameWindow.draw()
|
||||
cls(Config.colors.black)
|
||||
|
||||
Print.text_center("Player Name", Config.screen.width / 2, 14, Config.colors.white, false, 2)
|
||||
|
||||
draw_boxes()
|
||||
|
||||
if TextInput.is_done() then
|
||||
Print.text_center("Z: save name B: edit", Config.screen.width / 2, BOX_Y + BOX_H + 12, Config.colors.light_blue)
|
||||
else
|
||||
Print.text_center("Up/Dn: letter Lft/Rgt: move Z: ok", Config.screen.width / 2, BOX_Y + BOX_H + 12, Config.colors.dark_grey)
|
||||
end
|
||||
|
||||
-- Warning section
|
||||
rect(0, WARN_Y, Config.screen.width, Config.screen.height - WARN_Y, Config.colors.blue)
|
||||
rectb(0, WARN_Y, Config.screen.width, Config.screen.height - WARN_Y, Config.colors.light_blue)
|
||||
Print.text_center("Remember your name!", Config.screen.width / 2, WARN_Y + 8, Config.colors.white)
|
||||
Print.text_center("You will need it to load the game.", Config.screen.width / 2, WARN_Y + 20, Config.colors.light_grey)
|
||||
end
|
||||
|
||||
--- Updates player name window logic.
|
||||
--- @within PlayerNameWindow
|
||||
function PlayerNameWindow.update()
|
||||
_frame = _frame + 1
|
||||
|
||||
if TextInput.is_done() then
|
||||
if Input.select() then
|
||||
Context.player_name = TextInput.get_name()
|
||||
if _on_confirm then _on_confirm() else Window.set_current("menu") end
|
||||
elseif Input.back() then
|
||||
TextInput.prev_position()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if Input.up_repeat() then TextInput.next_letter() end
|
||||
if Input.down_repeat() then TextInput.prev_letter() end
|
||||
if Input.right() then TextInput.next_position() end
|
||||
if Input.select() then TextInput.select_letter() end
|
||||
|
||||
if Input.left() or Input.back() then
|
||||
if TextInput.get_position() > 1 then
|
||||
TextInput.prev_position()
|
||||
else
|
||||
Window.set_current("menu")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -42,6 +42,3 @@ Window.register("continued", ContinuedWindow)
|
||||
|
||||
CreditsWindow = {}
|
||||
Window.register("credits", CreditsWindow)
|
||||
|
||||
PlayerNameWindow = {}
|
||||
Window.register("player_name", PlayerNameWindow)
|
||||
|
||||
Reference in New Issue
Block a user