From dc0eae52c20e08168e277c06b69c9377ccd6d491 Mon Sep 17 00:00:00 2001 From: Nicholas Hayashi Date: Mon, 11 Jan 2021 04:53:41 -0500 Subject: [PATCH] better debug stuff --- NOTES.md | 1 + main.lua | 28 +++++++++++++--- res/boi.aseprite | Bin 0 -> 1368 bytes src/entity.lua | 10 +++--- src/grid.lua | 42 ++++++++++++++++++++---- src/hexyz.lua | 17 +++++----- src/mob.lua | 82 ++++++++++++++++++++++------------------------- src/tower.lua | 11 +++---- 8 files changed, 117 insertions(+), 74 deletions(-) create mode 100644 res/boi.aseprite diff --git a/NOTES.md b/NOTES.md index 6fb7f9d..d4a32c3 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,4 +1,5 @@ +SEEED 1835 has bad start todoooos & notes diff --git a/main.lua b/main.lua index b5e77a4..77b7069 100644 --- a/main.lua +++ b/main.lua @@ -26,12 +26,15 @@ WIN = am.window{ height = 1080, title = "hexyz", highdpi = true, - letterbox = true + letterbox = true, + clear_color = color_at(0) } OFF_SCREEN = vec2(WIN.width * 2) -- arbitrary pixel position that is garunteed to be off screen WORLD = false -- root scene node of everything considered to be in the game world + -- aka non gui stuff + TIME = 0 -- runtime of the current game in seconds (not whole program runtime) SCORE = 0 -- score of the player MONEY = 0 -- available resources @@ -52,7 +55,8 @@ local TRDTS = { HEX = 2, PLATFORM = 3, PERF = 4, - SEED = 5 + SEED = 5, + TILE = 6 } local TRDT = TRDTS.SEED @@ -64,9 +68,10 @@ end local function game_action(scene) if SCORE < 0 then game_end() end - TIME = TIME + am.delta_time + TIME = TIME + am.delta_time SCORE = SCORE + am.delta_time MOUSE = WIN:mouse_position() + local mwd = WIN:mouse_wheel_delta() local hex = pixel_to_hex(MOUSE - WORLDSPACE_COORDINATE_OFFSET) local rounded_mouse = hex_to_pixel(hex) + WORLDSPACE_COORDINATE_OFFSET @@ -85,12 +90,23 @@ local function game_action(scene) end end + if WIN:mouse_pressed"middle" then + WIN.scene"scale".scale2d = vec2(1) + else + local small_mwd = vec2(mwd.y / 1000) + WIN.scene"scale".scale = WIN.scene"scale".scale + small_mwd + WIN.scene"scale".scale = WIN.scene"scale".scale + small_mwd + end + if WIN:key_pressed"escape" then game_end() elseif WIN:key_pressed"f1" then TRDT = (TRDT + 1) % #table.keys(TRDTS) + elseif WIN:key_pressed"f2" then + WORLD"priority_overlay".hidden = not WORLD"priority_overlay".hidden + elseif WIN:key_pressed"tab" then select_tower((SELECTED_TOWER_TYPE + 1) % #table.keys(TOWER_TYPE)) end @@ -123,6 +139,9 @@ local function game_action(scene) elseif TRDT == TRDTS.SEED then str = "SEED: " .. HEX_MAP.seed + + elseif TRDT == TRDTS.TILE then + str = table.tostring(HEX_MAP.get(hex.x, hex.y)) end WIN.scene"coords".text = str end @@ -172,7 +191,6 @@ function game_scene() local coords = am.translate(WIN.right - 10, WIN.top - 20) ^ am.text("", "right", "top"):tag"coords" local hex_cursor = am.circle(OFF_SCREEN, HEX_SIZE, COLORS.TRANSPARENT, 6):tag"hex_cursor" - local curtain = am.rect(WIN.left, WIN.bottom, WIN.right, WIN.top, COLORS.TRUE_BLACK) curtain:action(coroutine.create(function() am.wait(am.tween(curtain, 3, { color = vec4(0) }, am.ease.out(am.ease.hyperbola))) @@ -198,6 +216,6 @@ function game_scene() end load_textures() -WIN.scene = game_scene() +WIN.scene = am.scale(vec2(1)) ^ game_scene() noglobals() diff --git a/res/boi.aseprite b/res/boi.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..ca463518d76d2c8558b9e47dee8fb1d8de825362 GIT binary patch literal 1368 zcmcJMc~DbV6o)UewFa#Nm9W~_vM50@EFxP$r&X#fNqp->1Qg3w`Uh%AAjAVJa-+D`LN|LnPQzqxbIym!9edqJ8A zjhCw-4_G*)h7gK|{co8gHRUDR1?&H)Aq|AqWm;QPwP1igY;D}uNR@GGa5lu5|9xYo z(%CvH5PBD95BzYSE0E+w0Op-_0lqkI0UW+f0?xOT0Od=Eft;z+K(g=<(D6DAcq-lo z=y%EtXzS_(ba(#@cqrlvU!SY zTU+38U=)ye)(<#%@d+@m=p-(&if#YA#2PsxM(JF!8_k5ElQpom=V-~?jusy4dGif*gGGJG zbNMbwVwT4KB!u0cw(Y%u2OSBY^LPd#;WwT+eV)PCy&e(i_I;I>Ic$r}gZvYUwTU~v zc&hbM_s-SI>0{jC<}<$zJ8}dOsFN=gD4o zH!MUR3l&(9lcXOiTlUMVsnHk%~SLX_)t8rI^^-X0f33|^8 or{(!3r{j$VGsad(*Dfy6KG4Ba8H4vCr9@x+z^mOkm^%;u1c?VCY5)KL literal 0 HcmV?d00001 diff --git a/src/entity.lua b/src/entity.lua index b7710f9..47b94ec 100644 --- a/src/entity.lua +++ b/src/entity.lua @@ -17,7 +17,7 @@ entity structure: function make_basic_entity(hex, node, update, position) local entity = {} - entity.TOB = TIME + entity.TOB = TIME -- usually you'll provide a hex and not a position, and the entity will spawn in the center -- of the hex. if you want an entity to exist not at the center of a hex, you can provide a @@ -51,17 +51,18 @@ end function delete_all_entities() for mob_index,mob in pairs(MOBS) do - delete_entity(MOBS, mob_index) + if mob then delete_entity(MOBS, mob_index) end end for tower_index,tower in pairs(TOWERS) do - delete_entity(TOWERS, tower_index) + if tower then delete_entity(TOWERS, tower_index) end end for projectile_index,projectile in pairs(PROJECTILES) do - delete_entity(PROJECTILES, projectile_index) + if projectile then delete_entity(PROJECTILES, projectile_index) end end end function do_entity_updates() + --if WIN:key_down"space" then for mob_index,mob in pairs(MOBS) do if mob and mob.update then mob.update(mob, mob_index) @@ -77,5 +78,6 @@ function do_entity_updates() projectile.update(projectile, projectile_index) end end + --end end diff --git a/src/grid.lua b/src/grid.lua index 818a3ab..70610fe 100644 --- a/src/grid.lua +++ b/src/grid.lua @@ -65,14 +65,19 @@ function color_at(elevation) end end -function grid_heuristic(source, target) +local function grid_heuristic(source, target) return math.distance(source, target) end -function grid_cost(from, to) - local t1, t2 = HEX_MAP.get(from.x, from.y), HEX_MAP.get(to.x, to.y) - --local baseline = math.log(math.abs(1 - t1.elevation) + math.abs(1 - t2.elevation)) - return math.abs(t1.elevation - t2.elevation) --+ baseline +local function grid_cost(map, from, to) + local t1, t2 = map.get(from.x, from.y), map.get(to.x, to.y) + if t2.elevation < -0.5 or t2.elevation >= 0.5 + or t1.elevation < -0.5 or t1.elevation >= 0.5 then return 999 end + return math.abs(math.abs(t1.elevation)^0.5 - math.abs(t2.elevation)^0.5) +end + +local function generate_flow_field(map, start) + return dijkstra(map, start, nil, grid_cost) end function random_map(seed) @@ -97,7 +102,7 @@ function random_map(seed) noise = noise * d^0.125 -- arbitrary, seems to work good end - -- light shading on edge cells + -- light shading on edge cells @TODO replace this with a skylight, that can move local mask = vec4(0, 0, 0, math.max(((evenq.x - HEX_GRID_WIDTH/2) / HEX_GRID_WIDTH) ^ 2 , ((-evenq.y - HEX_GRID_HEIGHT/2) / HEX_GRID_HEIGHT) ^ 2)) local color = color_at(noise) - mask @@ -114,9 +119,34 @@ function random_map(seed) end end + local flow_field = generate_flow_field(map, HEX_GRID_CENTER) + for i,_ in pairs(flow_field) do + for j,priority in pairs(flow_field[i]) do + if priority then + map[i][j].priority = priority.priority + end + end + end + + world:append(draw_priority_overlay(map)) + world:append(am.circle(hex_to_pixel(HEX_GRID_CENTER), HEX_SIZE/2, COLORS.MAGENTA, 4)) return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world:tag"world" end +function draw_priority_overlay(map) + local priority_overlay = am.group():tag"priority_overlay" + for i,_ in pairs(map) do + for j,tile in pairs(map[i]) do + if tile then + priority_overlay:append(am.translate(hex_to_pixel(vec2(i, j))) + ^ am.text(string.format("%.1f", tile.priority or 0))) + end + end + end + return priority_overlay +end + + diff --git a/src/hexyz.lua b/src/hexyz.lua index a89d84c..a960a35 100644 --- a/src/hexyz.lua +++ b/src/hexyz.lua @@ -448,7 +448,7 @@ end function breadth_first(map, start) local frontier = {} - frontier[1] = { start } + frontier[1] = start local distance = {} distance[start.x] = {} @@ -461,7 +461,8 @@ function breadth_first(map, start) local d = map_get(distance, neighbour.x, neighbour.y) if not d then table.insert(frontier, neighbour) - map_set(distance, neighbour.x, neighbour.y, d + 1) + local current_distance = map_get(distance, current.x, current.y) + map_set(distance, neighbour.x, neighbour.y, current_distance + 1) end end end @@ -471,7 +472,7 @@ end function dijkstra(map, start, goal, cost_f) local frontier = {} - frontier = { hex = start, priority = 0 } + frontier[1] = { hex = start, priority = 0 } local came_from = {} came_from[start.x] = {} @@ -484,17 +485,17 @@ function dijkstra(map, start, goal, cost_f) while not (#frontier == 0) do local current = table.remove(frontier, 1) - if current.hex == goal then + if goal and current.hex == goal then break end for _,neighbour in pairs(map.neighbours(current.hex)) do - local new_cost = map_get(cost_so_far, current.hex.x, current.hex.y) + cost_f(current.hex, neighbour) + local new_cost = map_get(cost_so_far, current.hex.x, current.hex.y) + cost_f(map, current.hex, neighbour) local neighbour_cost = map_get(cost_so_far, neighbour.x, neighbour.y) - if not neighbour_cost or new_cost < neighbour_cost then + if not neighbour_cost or (new_cost < neighbour_cost) then map_set(cost_so_far, neighbour.x, neighbour.y, new_cost) - local priority = new_cost + local priority = new_cost + math.distance(start, neighbour) table.insert(frontier, { hex = neighbour, priority = priority }) map_set(came_from, neighbour.x, neighbour.y, current) end @@ -539,7 +540,7 @@ function Astar(map, start, goal, heuristic, cost_f) end for _,next_ in pairs(map.neighbours(current.hex)) do - local new_cost = map_get(path_so_far, current.hex.x, current.hex.y) + cost_f(current.hex, next_) + local new_cost = map_get(path_so_far, current.hex.x, current.hex.y) + cost_f(map, current.hex, next_) local next_cost = map_get(path_so_far, next_.x, next_.y) if not next_cost or new_cost < next_cost then diff --git a/src/mob.lua b/src/mob.lua index 2a7dc54..4a00d03 100644 --- a/src/mob.lua +++ b/src/mob.lua @@ -10,12 +10,11 @@ mob(entity) structure: } --]] --- distance from hex centerpoint to nearest edge -MOB_SIZE = hex_height(HEX_SIZE, ORIENTATION.FLAT) / 2 +MAX_MOB_SIZE = hex_height(HEX_SIZE, ORIENTATION.FLAT) / 2 +MOB_SIZE = MAX_MOB_SIZE/2 function mobs_on_hex(hex) local t = {} - for mob_index,mob in pairs(MOBS) do if mob and mob.hex == hex then table.insert(t, mob_index, mob) @@ -33,39 +32,11 @@ end function mob_die(mob, mob_index) WORLD:action(vplay_sound(SOUNDS.EXPLOSION1)) - --WORLD:append(mob_death_explosion(mob)) delete_entity(MOBS, mob_index) end -function mob_death_explosion(mob) - local t = 0.5 - return am.particles2d{ - source_pos = mob.position, - source_pos_var = vec2(mob.hurtbox_radius), - max_particles = 25, - start_size = mob.hurtbox_radius/10, - start_size_var = mob.hurtbox_radius/15, - end_size = 0, - angle = 0, - angle_var = math.pi, - speed = 105, - speed_var = 55, - life = t * 0.8, - life_var = t * 0.2, - start_color = COLORS.CLARET, - start_color_var = COLORS.DIRT, - end_color = COLORS.DIRT, - end_color_var = COLORS.CLARET, - damping = 0.3 - }:action(coroutine.create(function(self) - am.wait(am.delay(t)) - WORLD:remove(self) - end)) -end - function do_hit_mob(mob, damage, mob_index) mob.health = mob.health - damage - if mob.health <= 0 then update_score(mob.bounty) mob_die(mob, mob_index) @@ -74,9 +45,9 @@ end function check_for_broken_mob_pathing(hex) for _,mob in pairs(MOBS) do - if mob and mob.path[hex.x] and mob.path[hex.x][hex.y] then - mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) - end + --if mob and mob.path[hex.x] and mob.path[hex.x][hex.y] then + --mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) + --end end end @@ -90,7 +61,7 @@ end -- try reducing map size by identifying key nodes (inflection points) -- there are performance hits everytime we spawn a mob and it's Astar's fault function get_mob_path(mob, map, start, goal) - return Astar(map, goal, start, grid_heuristic, grid_cost) + --return Astar(map, goal, start, grid_heuristic, grid_cost) end -- @FIXME there's a bug here where the position of the spawn hex is sometimes 1 closer to the center than we want @@ -124,20 +95,43 @@ local function get_spawn_hex() end local function mob_update(mob, mob_index) + local last_frame_hex = mob.hex mob.hex = pixel_to_hex(mob.position) - local frame_target = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y] + if mob.hex == HEX_GRID_CENTER then + update_score(-mob.health) + mob_die(mob, mob_index) + return true + end + + --local frame_target = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y] + local frame_target = nil + local neighbours = HEX_MAP.neighbours(mob.hex) + if #neighbours ~= 0 then + local first_entry = HEX_MAP.get(neighbours[1].x, neighbours[1].y) + + local best_hex = neighbours[1] + local best_cost = first_entry and first_entry.priority or HEX_MAP.get(last_frame_hex.x, last_frame_hex.y).priority + + for _,h in pairs(neighbours) do + --if h ~= last_frame_hex then + local map_entry = HEX_MAP.get(h.x, h.y) + local cost = map_entry.priority + + if cost and cost < best_cost then + best_cost = cost + best_hex = h + end + --end + end + frame_target = best_hex + end if frame_target then - mob.position = mob.position + math.normalize(hex_to_pixel(frame_target.hex) - mob.position) * mob.speed + mob.position = mob.position + math.normalize(hex_to_pixel(frame_target) - mob.position) * mob.speed mob.node.position2d = mob.position else - if mob.hex == HEX_GRID_CENTER then - update_score(-mob.health) - mob_die(mob, mob_index) - else - log("stuck") - end + log("no frame target") end --[[ passive animation @@ -165,7 +159,7 @@ local function make_and_register_mob() register_entity(MOBS, mob) end -local SPAWN_CHANCE = 100 +local SPAWN_CHANCE = 25 function do_mob_spawning() --if WIN:key_pressed"space" then if math.random(SPAWN_CHANCE) == 1 then diff --git a/src/tower.lua b/src/tower.lua index 91a5580..7dda72f 100644 --- a/src/tower.lua +++ b/src/tower.lua @@ -6,13 +6,10 @@ TOWER_TYPE = { MOAT = 2, } -function tower_type_tostring(type_) - if type_ == TOWER_TYPE.REDEYE then - return "Redeye Tower" - elseif type_ == TOWER_TYPE.WALL then - return "Wall" - elseif type_ == TOWER_TYPE.MOAT then - return "Moat" +function tower_type_tostring(tower_type) + if tower_type == TOWER_TYPE.REDEYE then return "Redeye Tower" + elseif tower_type == TOWER_TYPE.WALL then return "Wall" + elseif tower_type == TOWER_TYPE.MOAT then return "Moat" end end