feat: added intro sequence, fixed norman's sprite, placed him in various places
This commit is contained in:
@@ -2,9 +2,7 @@
|
||||
local _available_decisions = {}
|
||||
local _selected_decision_index = 1
|
||||
|
||||
--- Draws the game window.
|
||||
--- @within GameWindow
|
||||
function GameWindow.draw()
|
||||
local function draw_game_scene(underlay_draw)
|
||||
local screen = Screen.get_by_id(Context.game.current_screen)
|
||||
if not screen then return end
|
||||
if screen.background then
|
||||
@@ -12,6 +10,9 @@ function GameWindow.draw()
|
||||
elseif screen.background_color then
|
||||
rect(0, 0, Config.screen.width, Config.screen.height, screen.background_color)
|
||||
end
|
||||
if underlay_draw then
|
||||
underlay_draw()
|
||||
end
|
||||
if not Context.stat_screen_active and #_available_decisions > 0 then
|
||||
Decision.draw(_available_decisions, _selected_decision_index)
|
||||
end
|
||||
@@ -20,6 +21,19 @@ function GameWindow.draw()
|
||||
screen.draw()
|
||||
end
|
||||
|
||||
--- Draws the game window.
|
||||
--- @within GameWindow
|
||||
function GameWindow.draw()
|
||||
draw_game_scene()
|
||||
end
|
||||
|
||||
--- Draws the game window with a custom underlay.
|
||||
--- @within GameWindow
|
||||
--- @param underlay_draw function A draw callback rendered after the background but before overlays.<br/>
|
||||
function GameWindow.draw_with_underlay(underlay_draw)
|
||||
draw_game_scene(underlay_draw)
|
||||
end
|
||||
|
||||
--- Updates the game window logic.
|
||||
--- @within GameWindow
|
||||
function GameWindow.update()
|
||||
@@ -31,12 +45,13 @@ function GameWindow.update()
|
||||
end
|
||||
|
||||
local screen = Screen.get_by_id(Context.game.current_screen)
|
||||
if not screen or not screen.update then return end
|
||||
screen.update()
|
||||
|
||||
-- Handle current situation updates
|
||||
if Context.game.current_situation then
|
||||
local current_situation_obj = Situation.get_by_id(Context.game.current_situation)
|
||||
if current_situation_obj and current_situation_obj.update then
|
||||
if current_situation_obj and type(current_situation_obj.update) == "function" then
|
||||
current_situation_obj.update()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,7 +26,6 @@ end
|
||||
--- @within MenuWindow
|
||||
function MenuWindow.new_game()
|
||||
Context.new_game()
|
||||
GameWindow.set_state("game")
|
||||
end
|
||||
|
||||
--- Loads a game from the menu.
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
function MinigameButtonMashWindow.init_context()
|
||||
return {
|
||||
bar_fill = 0,
|
||||
max_fill = 100,
|
||||
target_points = 100,
|
||||
fill_per_press = 8,
|
||||
base_degradation = 0.15,
|
||||
degradation_multiplier = 0.006,
|
||||
button_pressed_timer = 0,
|
||||
button_press_duration = 8,
|
||||
instruction_text = "MASH Z!",
|
||||
show_progress_text = true,
|
||||
return_window = nil,
|
||||
bar_x = 20,
|
||||
bar_y = 10,
|
||||
@@ -35,6 +37,9 @@ function MinigameButtonMashWindow.init(params)
|
||||
for k, v in pairs(params) do
|
||||
defaults[k] = v
|
||||
end
|
||||
if params.max_fill and not params.target_points then
|
||||
defaults.target_points = params.max_fill
|
||||
end
|
||||
end
|
||||
Context.minigame_button_mash = defaults
|
||||
end
|
||||
@@ -78,11 +83,11 @@ function MinigameButtonMashWindow.update()
|
||||
if Input.select() then
|
||||
mg.bar_fill = mg.bar_fill + mg.fill_per_press
|
||||
mg.button_pressed_timer = mg.button_press_duration
|
||||
if mg.bar_fill > mg.max_fill then
|
||||
mg.bar_fill = mg.max_fill
|
||||
if mg.bar_fill > mg.target_points then
|
||||
mg.bar_fill = mg.target_points
|
||||
end
|
||||
end
|
||||
if mg.bar_fill >= mg.max_fill then
|
||||
if mg.bar_fill >= mg.target_points then
|
||||
mg.win_timer = Config.timing.minigame_win_duration
|
||||
return
|
||||
end
|
||||
@@ -95,7 +100,7 @@ function MinigameButtonMashWindow.update()
|
||||
mg.button_pressed_timer = mg.button_pressed_timer - 1
|
||||
end
|
||||
if mg.focus_center_x then
|
||||
Focus.set_percentage(mg.bar_fill / mg.max_fill)
|
||||
Focus.set_percentage(mg.bar_fill / mg.target_points)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -104,14 +109,16 @@ end
|
||||
function MinigameButtonMashWindow.draw()
|
||||
local mg = Context.minigame_button_mash
|
||||
if mg.return_window == "game" then
|
||||
GameWindow.draw()
|
||||
GameWindow.draw_with_underlay(function()
|
||||
Sprite.draw_at("sleeping_norman", (Config.screen.width / 2) - 30, (Config.screen.height / 2) - 22)
|
||||
end)
|
||||
end
|
||||
if not mg.focus_center_x then
|
||||
rect(0, 0, Config.screen.width, Config.screen.height, Config.colors.black)
|
||||
end
|
||||
rect(mg.bar_x - 2, mg.bar_y - 2, mg.bar_width + 4, mg.bar_height + 4, Config.colors.light_grey)
|
||||
rectb(mg.bar_x - 2, mg.bar_y - 2, mg.bar_width + 4, mg.bar_height + 4, Config.colors.dark_grey)
|
||||
local fill_width = (mg.bar_fill / mg.max_fill) * mg.bar_width
|
||||
local fill_width = (mg.bar_fill / mg.target_points) * mg.bar_width
|
||||
if fill_width > 0 then
|
||||
local bar_color = Config.colors.light_blue
|
||||
if mg.bar_fill > 66 then
|
||||
@@ -130,9 +137,11 @@ function MinigameButtonMashWindow.draw()
|
||||
circ(mg.button_x, mg.button_y, mg.button_size - 2, button_color)
|
||||
end
|
||||
Print.text_center("Z", mg.button_x, mg.button_y - 3, button_color)
|
||||
Print.text_center("MASH Z!", Config.screen.width / 2, mg.bar_y + mg.bar_height + 10, Config.colors.light_grey)
|
||||
local percentage = math.floor((mg.bar_fill / mg.max_fill) * 100)
|
||||
Print.text_center(percentage .. "%", mg.bar_x + mg.bar_width / 2, mg.bar_y + 2, Config.colors.black)
|
||||
Print.text_center(mg.instruction_text, Config.screen.width / 2, mg.bar_y + mg.bar_height + 10, Config.colors.light_grey)
|
||||
if mg.show_progress_text then
|
||||
local points_text = math.floor(mg.bar_fill) .. "/" .. mg.target_points
|
||||
Print.text_center(points_text, mg.bar_x + mg.bar_width / 2, mg.bar_y + 2, Config.colors.black)
|
||||
end
|
||||
|
||||
if mg.win_timer > 0 then
|
||||
Minigame.draw_win_overlay()
|
||||
|
||||
@@ -130,7 +130,9 @@ end
|
||||
function MinigameRhythmWindow.draw()
|
||||
local mg = Context.minigame_rhythm
|
||||
if mg.return_window == "game" then
|
||||
GameWindow.draw()
|
||||
GameWindow.draw_with_underlay(function()
|
||||
Sprite.draw_at("sleeping_norman", (Config.screen.width / 2) - 30, (Config.screen.height / 2) - 22)
|
||||
end)
|
||||
end
|
||||
if not mg.focus_center_x then
|
||||
rect(0, 0, Config.screen.width, Config.screen.height, Config.colors.black)
|
||||
@@ -144,12 +146,10 @@ function MinigameRhythmWindow.draw()
|
||||
rect(target_x, mg.bar_y, target_width_pixels, mg.bar_height, Config.colors.light_blue)
|
||||
local line_x = mg.bar_x + (mg.line_position * mg.bar_width)
|
||||
rect(line_x - 1, mg.bar_y, 2, mg.bar_height, Config.colors.item)
|
||||
local score_text = "SCORE: " .. mg.score .. " / " .. mg.max_score
|
||||
Print.text_center(score_text, Config.screen.width / 2, mg.bar_y + mg.bar_height + 8, Config.colors.light_grey)
|
||||
Print.text_center(
|
||||
"Press Z when line is in green!",
|
||||
"Sleep Norman ... Sleep!",
|
||||
Config.screen.width / 2,
|
||||
mg.bar_y + mg.bar_height + 20,
|
||||
mg.bar_y + mg.bar_height + 14,
|
||||
Config.colors.light_grey
|
||||
)
|
||||
local button_color = Config.colors.light_grey
|
||||
|
||||
@@ -4,12 +4,25 @@ local STATE_TEXT = "text"
|
||||
local STATE_DAY = "day"
|
||||
local STATE_CHOICE = "choice"
|
||||
|
||||
local DEFAULT_TEXT = [[
|
||||
Misterious man appears
|
||||
during your sleep.
|
||||
|
||||
He says nothing.
|
||||
He doesn't need to.
|
||||
|
||||
He says nothing.
|
||||
]]
|
||||
|
||||
local state = STATE_TEXT
|
||||
local text_y = Config.screen.height
|
||||
local text_speed = 0.4
|
||||
local day_timer = 0
|
||||
local day_display_frames = 120
|
||||
local selected_choice = 1
|
||||
local text = DEFAULT_TEXT
|
||||
local day_text_override = nil
|
||||
local on_text_complete = nil
|
||||
|
||||
local choices = {
|
||||
{
|
||||
@@ -20,16 +33,6 @@ local choices = {
|
||||
},
|
||||
}
|
||||
|
||||
local text = [[
|
||||
Misterious man appears
|
||||
during your sleep.
|
||||
|
||||
He says nothing.
|
||||
He doesn't need to.
|
||||
|
||||
He says nothing.
|
||||
]]
|
||||
|
||||
--- Sets the scrolling text content.
|
||||
--- @within MysteriousManWindow
|
||||
--- @param new_text string The text to display.
|
||||
@@ -39,22 +42,49 @@ end
|
||||
|
||||
--- Starts the mysterious man window.
|
||||
--- @within MysteriousManWindow
|
||||
function MysteriousManWindow.start()
|
||||
--- @param[opt] options table Optional window configuration.</br>
|
||||
--- Fields: </br>
|
||||
--- * text (string) Override for the scrolling text.<br/>
|
||||
--- * day_text (string) Override for the centered day label.<br/>
|
||||
--- * on_text_complete (function) Callback fired once when the text phase ends.<br/>
|
||||
function MysteriousManWindow.start(options)
|
||||
options = options or {}
|
||||
state = STATE_TEXT
|
||||
text_y = Config.screen.height
|
||||
day_timer = 0
|
||||
selected_choice = 1
|
||||
text = options.text or DEFAULT_TEXT
|
||||
day_text_override = options.day_text
|
||||
on_text_complete = options.on_text_complete
|
||||
Meter.hide()
|
||||
Window.set_current("mysterious_man")
|
||||
end
|
||||
|
||||
local function go_to_day_state()
|
||||
if on_text_complete then
|
||||
on_text_complete()
|
||||
on_text_complete = nil
|
||||
end
|
||||
if Window.get_current_id() ~= "mysterious_man" then
|
||||
return
|
||||
end
|
||||
state = STATE_DAY
|
||||
day_timer = day_display_frames
|
||||
end
|
||||
|
||||
local function wake_up()
|
||||
Context.home_norman_visible = false
|
||||
Util.go_to_screen_by_id("home")
|
||||
MinigameButtonMashWindow.start("game", {
|
||||
focus_center_x = Config.screen.width / 2,
|
||||
focus_center_y = Config.screen.height / 2,
|
||||
focus_center_x = (Config.screen.width / 2) - 22,
|
||||
focus_center_y = (Config.screen.height / 2) - 18,
|
||||
focus_initial_radius = 0,
|
||||
target_points = 100,
|
||||
instruction_text = "Wake up Norman!",
|
||||
show_progress_text = false,
|
||||
on_win = function()
|
||||
Audio.music_play_wakingup()
|
||||
Context.home_norman_visible = true
|
||||
Meter.show()
|
||||
Window.set_current("game")
|
||||
end,
|
||||
@@ -79,13 +109,11 @@ function MysteriousManWindow.update()
|
||||
end
|
||||
|
||||
if text_y < -lines * 8 then
|
||||
state = STATE_DAY
|
||||
day_timer = day_display_frames
|
||||
go_to_day_state()
|
||||
end
|
||||
|
||||
if Input.select() then
|
||||
state = STATE_DAY
|
||||
day_timer = day_display_frames
|
||||
go_to_day_state()
|
||||
end
|
||||
elseif state == STATE_DAY then
|
||||
day_timer = day_timer - 1
|
||||
@@ -117,7 +145,7 @@ function MysteriousManWindow.draw()
|
||||
local x = (Config.screen.width - 132) / 2
|
||||
Print.text(text, x, text_y, Config.colors.light_grey)
|
||||
elseif state == STATE_DAY then
|
||||
local day_text = "Day " .. Context.day_count
|
||||
local day_text = day_text_override or ("Day " .. Context.day_count)
|
||||
Print.text_center(
|
||||
day_text,
|
||||
Config.screen.width / 2,
|
||||
|
||||
Reference in New Issue
Block a user