From c2466d0ed442c7edf72c8e1c85b68fcb6bf51220 Mon Sep 17 00:00:00 2001 From: Nicholas Hayashi Date: Sat, 8 Jan 2022 12:51:56 -0500 Subject: [PATCH] fix some buggies --- lib/texture.lua | 2 ++ main.lua | 1 + res/img/wall0.png | Bin 0 -> 4023 bytes src/game.lua | 7 ++++-- src/hexyz.lua | 31 +++++++++++++----------- src/tower.lua | 60 +++++++++++++++++++++++++++++++++++++++------- 6 files changed, 76 insertions(+), 25 deletions(-) create mode 100644 res/img/wall0.png diff --git a/lib/texture.lua b/lib/texture.lua index 0628236..67a497c 100644 --- a/lib/texture.lua +++ b/lib/texture.lua @@ -44,6 +44,8 @@ TEXTURES = { SELECT_BOX = load_texture("select_box.png"), + TOWER_WALL0 = load_texture("wall0.png"), + -- tower stuff TOWER_WALL = load_texture("tower_wall.png"), TOWER_WALL_ICON = load_texture("tower_wall_icon.png"), diff --git a/main.lua b/main.lua index 2caeec5..26da753 100644 --- a/main.lua +++ b/main.lua @@ -45,6 +45,7 @@ TRDTS = { PERF = 5, SEED = 6, TILE = 7, + MOUSE = 8 } function make_top_right_display_node() diff --git a/res/img/wall0.png b/res/img/wall0.png new file mode 100644 index 0000000000000000000000000000000000000000..2bf5ef805e2287b6732e23b19f53281d777bac75 GIT binary patch literal 4023 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 literal 0 HcmV?d00001 diff --git a/src/game.lua b/src/game.lua index c5c025d..6f361ef 100644 --- a/src/game.lua +++ b/src/game.lua @@ -120,6 +120,9 @@ local function get_top_right_display_text(hex, evenq, centered_evenq, display_ty elseif display_type == TRDTS.TILE then str = table.tostring(hex_map_get(game_state.map, hex)) + + elseif display_type == TRDTS.MOUSE then + str = win:mouse_position() end return str end @@ -682,7 +685,7 @@ local function game_scene() -- dangling actions run before the main action scene:late_action(game_action) - play_track(SOUNDS.MAIN_THEME) + --play_track(SOUNDS.MAIN_THEME) return scene end @@ -727,7 +730,7 @@ function game_end() gui_alert(string.format( "\nmobs spawned: %d\ntowers built: %d\nprojectiles spawned: %d\n", - hmob, htower, hprojectile + hmob or 0, htower or 0, hprojectile or 0 ), COLORS.WHITE, 1000) game_state = {} diff --git a/src/hexyz.lua b/src/hexyz.lua index a121483..fcaae73 100644 --- a/src/hexyz.lua +++ b/src/hexyz.lua @@ -19,25 +19,28 @@ HEX_ORIENTATION = { FLAT = { M = mat2(3.0/2.0, 0.0, 3.0^0.5/2.0, 3.0^0.5 ), W = mat2(2.0/3.0, 0.0, -1.0/3.0 , 3.0^0.5/3.0), - angle = 0.0 + angle = 30 -- degrees }, -- Forward & Inverse Matrices used for the Pointy Orientation POINTY = { M = mat2(3.0^0.5, 3.0^0.5/2.0, 0.0, 3.0/2.0), W = mat2(3.0^0.5/3.0, -1.0/3.0, 0.0, 2.0/3.0), - angle = 0.5 + angle = 0 -- degrees } } -- whenever |orientation| appears as an argument, if it isn't provided, this is used instead. -- this is useful because most of the time you will only care about one orientation local HEX_DEFAULT_ORIENTATION = HEX_ORIENTATION.FLAT +-- if you need to dynamically calculate the default hexagon orientation (or use a non-standard one), you can pass it here +function hex_set_default_orientation(orientation) + HEX_DEFAULT_ORIENTATION = orientation +end -- whenever |size| for a hexagon appears as an argument, if it isn't provided, use this -- 'size' here is distance from the centerpoint to any vertex in pixel local HEX_DEFAULT_SIZE = vec2(26) - --- if you need to dynamically calculate the default hexagon size, you can pass it here after +-- if you need to dynamically calculate the default hexagon size, you can pass it here function hex_set_default_size(size) HEX_DEFAULT_SIZE = size end @@ -170,21 +173,21 @@ function pixel_to_hex(pix, size, orientation) return hex_round(x, y, -x - y) end --- TODO test, learn am.draw -function hex_corner_offset(corner, size, orientation) +-- you should provide |center| in pixels, not hexes, or any other coordinate system +function hex_corner_offset(center, corner, size, orientation) local orientation = orientation or HEX_DEFAULT_ORIENTATION - local angle = 2.0 * math.pi * orientation.angle + corner / 6 - return vec2(size[1] * math.cos(angle), size[2] * math.sin(angle)) + local size = size or HEX_DEFAULT_SIZE + local angle_rad = math.rad((60 * corner) - orientation.angle) + return vec2(center[1] + size[1] * math.cos(angle_rad), center[2] + size[2] * math.sin(angle_rad)) end --- TODO test this thing -function hex_corners(hex, size, orientation) +function hex_corners(hex, center, size, orientation) local orientation = orientation or HEX_DEFAULT_ORIENTATION + local size = size or HEX_DEFAULT_SIZE local corners = {} - local center = hex_to_pixel(hex, size, orientation) - for i = 0, 5 do - local offset = hex_corner_offset(i, size, orientation) - table.insert(corners, center + offset) + for i = 1, 6 do + local offset = hex_corner_offset(center, i, size, orientation) + table.insert(corners, offset) end return corners end diff --git a/src/tower.lua b/src/tower.lua index ae53ec2..9e676ae 100644 --- a/src/tower.lua +++ b/src/tower.lua @@ -75,8 +75,47 @@ function init_tower_specs() range = 0, fire_rate = 2, update_f = false, - make_node_f = function(self) - return am.circle(vec2(0), HEX_SIZE, COLORS.TAN1{a=0.6}, 6) + make_node_f = function(self, hex, cause_repaint) + local group = am.group(am.circle(vec2(0), HEX_SIZE, COLORS.VERY_DARK_GRAY, 6)) + if not hex then + -- should only happen when making the hex-cursor for the wall + return group + end + + local wall_neighbours = {} + local lines = am.rotate(math.rad(-30)) ^ am.group() + for i,n in pairs(hex_neighbours(hex)) do + local no_towers_adjacent = true + for _,t in pairs(towers_on_hex(n)) do + no_towers_adjacent = false + break + end + + if no_towers_adjacent then + local center = hex_to_pixel(hex, vec2(HEX_SIZE)) + lines:append(am.circle(center, 4, COLORS.WATER)) + local p1 = hex_corner_offset(center, i) + local j = i == 6 and 1 or i + 1 + local p2 = hex_corner_offset(center, j) + lines:append( + am.line(p1, p2, 3, vec4(1, 0, 0, 1)) + ) + end + end + + group:append(lines) + + if cause_repaint then + -- building a wall could change the adjacency between other walls, so we have to re-render them + -- (or atleast check if we need to) + for _,t in pairs(game_state.towers) do + if not t.completed_render and t.type == TOWER_TYPE.WALL then + t.node:replace("group", t.make_node_f(t, t.hex, false)) + end + end + end + + return group end }, { @@ -451,6 +490,8 @@ function tower_deserialize(json_string) return tower end +-- note that the table returned has towers at their index into the global towers table, +-- so #t will often not work correctly (the table will often be sparse) function towers_on_hex(hex) local t = {} for tower_index,tower in pairs(game_state.towers) do @@ -524,7 +565,7 @@ function make_and_register_tower(hex, tower_type) table.merge(tower, spec) tower.type = tower_type - tower.node = am.translate(tower.position) ^ tower.make_node_f(tower) + tower.node = am.translate(tower.position) ^ tower.make_node_f(tower, hex, true) -- initialize each weapons' last shot time to the negation of the fire rate - -- this lets the tower fire immediately upon being placed @@ -539,18 +580,19 @@ function make_and_register_tower(hex, tower_type) tower.hexes = hex_spiral_map(tower.hex, tower.size - 1) end - -- should we be permuting the map here? - for _,h in pairs(tower.hexes) do - local tile = hex_map_get(game_state.map, h.x, h.y) - tile.elevation = tile.elevation + tower.height - end - register_entity(game_state.towers, tower) return tower end function build_tower(hex, tower_type) local tower = make_and_register_tower(hex, tower_type) + + -- modify the hexes the tower sits atop to be impassable (actually just taller by the tower's height value) + for _,h in pairs(tower.hexes) do + local tile = hex_map_get(game_state.map, h.x, h.y) + tile.elevation = tile.elevation + tower.height + end + vplay_sfx(SOUNDS.EXPLOSION4) return tower