From 7db2d292c8bc42c68b98c0013dd58dadb98e7493 Mon Sep 17 00:00:00 2001 From: Nicholas Hayashi Date: Fri, 7 Jan 2022 18:36:15 -0500 Subject: [PATCH] fix game pause menu not unpausing on escape --- lib/gui.lua | 7 ++++- lib/random.lua | 57 +++++++++++++++++++++--------------- lib/texture.lua | 2 ++ main.lua | 29 ++++++++++++++---- res/img/seed_colon_text.png | Bin 0 -> 3903 bytes src/game.lua | 13 ++++---- src/hexyz.lua | 4 +-- src/map-editor.lua | 2 +- 8 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 res/img/seed_colon_text.png diff --git a/lib/gui.lua b/lib/gui.lua index 6d7203b..b2cfe98 100644 --- a/lib/gui.lua +++ b/lib/gui.lua @@ -216,6 +216,7 @@ function gui_make_textfield( if self"text".text:len() ~= 0 then self"text".text = self"text".text:sub(1, self"text".text:len() - 1) self"cursor".position2d = self"cursor".position2d - vec2(9 * 2, 0) + self"cursor".hidden = false end elseif k == "tab" then -- @TODO @@ -230,9 +231,13 @@ function gui_make_textfield( for _,c in pairs(chars) do if validate(self"text".text .. c) then - if self"text".text:len() <= max then + local len = self"text".text:len() + if len <= max then self"text".text = self"text".text .. c self"cursor".position2d = self"cursor".position2d + vec2(9 * 2, 0) + if len == max then + self"cursor".hidden = true + end end end end diff --git a/lib/random.lua b/lib/random.lua index 11282a8..18908dc 100644 --- a/lib/random.lua +++ b/lib/random.lua @@ -1,4 +1,6 @@ +RANDOM_CALLS_COUNT = 0 + -- https://stackoverflow.com/a/32387452/12464892 local function bitwise_and(a, b) local result = 0 @@ -26,39 +28,46 @@ local function rand() X2 = V - X1*D20 return V/D40 end -local SEED_BOUNDS = 2^20 - 1 -math.randomseed = function(seed) - RANDOM_CALLS_COUNT = 0 +local SEED_BOUNDS = 2^20 - 1 +local function randomseed2(seed) -- 0 <= X1 <= 2^20-1, 1 <= X2 <= 2^20-1 (must be odd!) - -- ensure the number is odd, and within the bounds of + -- ensure the number is odd, and within bounds of the generator local seed = bitwise_and(seed, 1) local v = math.clamp(math.abs(seed), 0, SEED_BOUNDS) X1 = v X2 = v + 1 end -RANDOM_CALLS_COUNT = 0 + +local RS = math.randomseed +math.randomseed = function(seed) + RANDOM_CALLS_COUNT = 0 + RS(seed) +end local R = math.random local function random(n, m) RANDOM_CALLS_COUNT = RANDOM_CALLS_COUNT + 1 + local r if n then if m then - return (rand() + n) * m + r = R(n, m) else - return rand() * n + r = R(n) end else - return rand() + r = R() end + + return r end -- whenever we refer to math.random, actually use the function 'random' above math.random = random function g_octave_noise(x, y, num_octaves, seed) - local seed = seed or os.clock() + local seed = seed or os.time() local noise = 0 for oct = 1, num_octaves do @@ -71,21 +80,21 @@ function g_octave_noise(x, y, num_octaves, seed) return noise end ----- @TODO test, fix ---function poisson_knuth(lambda) --- local e = 2.71828 --- --- local L = e^-lambda --- local k = 0 --- local p = 1 --- --- while p > L do --- k = k + 1 --- p = p * math.random() --- end --- --- return k - 1 ---end +-- @TODO test, fix +function poisson_knuth(lambda) + local e = 2.71828 + + local L = e^-lambda + local k = 0 + local p = 1 + + while p > L do + k = k + 1 + p = p * math.random() + end + + return k - 1 +end -- seed the random number generator with the current time -- os.clock() is better if the program has been running for a little bit. diff --git a/lib/texture.lua b/lib/texture.lua index 36d528d..0628236 100644 --- a/lib/texture.lua +++ b/lib/texture.lua @@ -30,6 +30,8 @@ TEXTURES = { UNPAUSE_HEX = load_texture("unpausehex.png"), MAIN_MENU_HEX = load_texture("mainmenuhex.png"), + SEED_COLON_TEXT = load_texture("seed_colon_text.png"), + CURTAIN = load_texture("curtain1.png"), SOUND_ON1 = load_texture("sound-on.png"), diff --git a/main.lua b/main.lua index d45bc37..9ae35f6 100644 --- a/main.lua +++ b/main.lua @@ -151,9 +151,9 @@ function main_scene(do_backdrop, do_logo) end local seed_textfield, get_seed_textfield_value = gui_make_textfield{ - position = vec2(win.left + 150, 50), - dimensions = vec2(200, 40), - max = 9, + position = vec2(win.left + 500, 50), + dimensions = vec2(90, 40), + max = math.ceil(math.log(HEX_GRID_WIDTH * HEX_GRID_HEIGHT, 10)), validate = function(string) return not string.match(string, "%D") end, @@ -161,6 +161,9 @@ function main_scene(do_backdrop, do_logo) group:append( seed_textfield ) + group:append( + am.translate(win.left + 220, 50) ^ pack_texture_into_sprite(TEXTURES.SEED_COLON_TEXT) + ) local main_scene_options = { false, @@ -213,7 +216,7 @@ function main_scene(do_backdrop, do_logo) return group end -function make_scene_menu(scene_options, tag) +function make_scene_menu(scene_options, tag, do_curtain) -- calculate the dimensions of the whole grid local spacing = 150 local grid_width = 6 @@ -227,6 +230,11 @@ function make_scene_menu(scene_options, tag) -- generate a map of hexagons (the menu is made up of two rows of hexes) and populate their locations with buttons from the provided options local map = hex_rectangular_map(grid_width, grid_height, HEX_ORIENTATION.POINTY) local group = am.group():tag(tag or "menu") + if do_curtain then + group:append(pack_texture_into_sprite(TEXTURES.CURTAIN, win.width, win.height)) + end + + local menu = am.group() local option_index = 1 for i,_ in pairs(map) do for j,_ in pairs(map[i]) do @@ -250,6 +258,14 @@ function make_scene_menu(scene_options, tag) local hex_ = pixel_to_hex(mouse - pixel_offset, vec2(spacing), HEX_ORIENTATION.POINTY) if tile.option then + if tile.option.keys and tile.option.action then + + for _,key in pairs(win:keys_pressed()) do + if table.find(tile.option.keys, function(_key) return _key == key end) then + tile.option.action() + end + end + end if hex == hex_ then if not selected then play_sfx(SOUNDS.SELECT1) @@ -267,12 +283,13 @@ function make_scene_menu(scene_options, tag) end end) - group:append(node) + menu:append(node) option_index = option_index + 1 end end + group:append(am.translate(pixel_offset) ^ menu) - return am.translate(pixel_offset) ^ group + return group end function switch_context(scene, action) diff --git a/res/img/seed_colon_text.png b/res/img/seed_colon_text.png new file mode 100644 index 0000000000000000000000000000000000000000..2c48dd5d7d2148b5aa0f3e8c73aeb7bda2b47b2d GIT binary patch literal 3903 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 N002ovPDHLkV1gC0!`J`- literal 0 HcmV?d00001 diff --git a/src/game.lua b/src/game.lua index 9bf38da..5219b03 100644 --- a/src/game.lua +++ b/src/game.lua @@ -42,7 +42,10 @@ local game_scene_menu_options = { action = function() win.scene("context").paused = false win.scene:remove("menu") - end + end, + keys = { + "escape" + } }, { texture = TEXTURES.SETTINGS_HEX, @@ -149,12 +152,11 @@ end local function game_pause() win.scene("context").paused = true - win.scene:append(make_scene_menu(game_scene_menu_options)) + win.scene:append(make_scene_menu(game_scene_menu_options, nil, true)) end local function game_deserialize(json_string) local new_game_state = am.parse_json(json_string) - log(new_game_state.RANDOM_CALLS_COUNT) if new_game_state.version ~= version then gui_alert("loading incompatible old save data.\nstarting a fresh game instead.", nil, 10) @@ -167,10 +169,11 @@ local function game_deserialize(json_string) -- in order to restore the state of the random number generator on game deserialize, we first -- seed it with the same seed used in the original state. then, we discard N calls, where N -- is the number of calls we counted since seeding the generator last time. - for i = 0, new_game_state.RANDOM_CALLS_COUNT do + -- + -- this means it's important that deserializing the rest of the game state doesn't cause any math.random() calls. + for i = 1, new_game_state.RANDOM_CALLS_COUNT do math.random() end - log(RANDOM_CALLS_COUNT) new_game_state.world = make_hex_grid_scene(new_game_state.map, true) new_game_state.seed = nil diff --git a/src/hexyz.lua b/src/hexyz.lua index d5260a3..a121483 100644 --- a/src/hexyz.lua +++ b/src/hexyz.lua @@ -384,7 +384,7 @@ end -- Returns Unordered Hexagonal Map of |radius| with Simplex Noise function hex_hexagonal_map(radius, seed) - local seed = seed or os.time() + local seed = seed or math.floor(math.random() * (2 * math.pi * radius^2)) local size = 0 local map = {} @@ -435,7 +435,7 @@ end -- Returns Unordered Rectangular Map of |width| and |height| with Simplex Noise function hex_rectangular_map(width, height, orientation, seed, do_generate_noise) local orientation = orientation or HEX_DEFAULT_ORIENTATION - local seed = seed or os.time() + local seed = seed or math.floor(math.random() * (width * height)) local map = {} if orientation == HEX_ORIENTATION.FLAT then diff --git a/src/map-editor.lua b/src/map-editor.lua index 4c9a0f4..faad31d 100644 --- a/src/map-editor.lua +++ b/src/map-editor.lua @@ -81,7 +81,7 @@ function map_editor_action() if win:key_pressed"escape" then win.scene("map_editor").paused = true - win.scene:append(make_scene_menu(map_editor_scene_menu_options)) + win.scene:append(make_scene_menu(map_editor_scene_menu_options, nil, true)) end if win:mouse_down"left" then