Browse Source

only re-apply/generate flow field if we need to

master
Nicholas Hayashi 4 years ago
parent
commit
2e35dbb287
  1. 19
      src/game.lua
  2. 41
      src/grid.lua
  3. 2
      src/mob.lua
  4. 7
      src/tower.lua

19
src/game.lua

@ -23,7 +23,7 @@ local TRDTS = {
} }
local function get_initial_game_state(seed) local function get_initial_game_state(seed)
local STARTING_MONEY = 50
local STARTING_MONEY = 10000
local map, world = random_map(seed) local map, world = random_map(seed)
return { return {
@ -130,15 +130,28 @@ local function game_action(scene)
if WIN:mouse_pressed"left" then if WIN:mouse_pressed"left" then
if interactable then if interactable then
if buildable then if buildable then
local broken, flow_field = making_hex_unwalkable_breaks_flow_field(hex, tile)
local cost = get_tower_cost(state.selected_tower_type) local cost = get_tower_cost(state.selected_tower_type)
if cost > state.money then
if broken then
local node = WIN.scene("cursor"):child(2)
node.color = COLORS.CLARET
node:action(am.tween(0.1, { color = COLORS.TRANSPARENT }))
play_sfx(SOUNDS.BIRD2)
elseif cost > state.money then
local node = WIN.scene("cursor"):child(2) local node = WIN.scene("cursor"):child(2)
node.color = COLORS.CLARET node.color = COLORS.CLARET
node:action(am.tween(0.1, { color = COLORS.TRANSPARENT })) node:action(am.tween(0.1, { color = COLORS.TRANSPARENT }))
play_sfx(SOUNDS.BIRD2) play_sfx(SOUNDS.BIRD2)
else else
update_money(-cost) update_money(-cost)
build_tower(hex, state.selected_tower_type)
build_tower(hex, state.selected_tower_type, flow_field)
if flow_field then
apply_flow_field(state.map, flow_field, state.world)
end
end end
end end
end end

41
src/grid.lua

@ -54,18 +54,17 @@ function tile_is_medium_elevation(tile)
return tile.elevation >= -0.5 and tile.elevation < 0.5 return tile.elevation >= -0.5 and tile.elevation < 0.5
end end
-- map elevation to appropriate color
function color_at(elevation) function color_at(elevation)
if elevation < -0.5 then -- lowest elevation
if elevation <= -0.5 then -- lowest elevation
return COLORS.WATER{ a = (elevation + 1.4) / 2 + 0.2 } return COLORS.WATER{ a = (elevation + 1.4) / 2 + 0.2 }
elseif elevation < 0 then -- med-low elevation
elseif elevation <= 0 then -- med-low elevation
return math.lerp(COLORS.DIRT, COLORS.GRASS, elevation + 0.5){ a = (elevation + 1.8) / 2 + 0.3 } return math.lerp(COLORS.DIRT, COLORS.GRASS, elevation + 0.5){ a = (elevation + 1.8) / 2 + 0.3 }
elseif elevation < 0.5 then -- med-high elevation
elseif elevation <= 0.5 then -- med-high elevation
return math.lerp(COLORS.DIRT, COLORS.GRASS, elevation + 0.5){ a = (elevation + 1.6) / 2 + 0.3 } return math.lerp(COLORS.DIRT, COLORS.GRASS, elevation + 0.5){ a = (elevation + 1.6) / 2 + 0.3 }
elseif elevation < 1 then -- high elevation
elseif elevation <= 1 then -- high elevation
return COLORS.MOUNTAIN{ ra = elevation } return COLORS.MOUNTAIN{ ra = elevation }
end end
end end
@ -74,17 +73,6 @@ function grid_heuristic(source, target)
return math.distance(source, target) return math.distance(source, target)
end end
function making_hex_unwalkable_breaks_flow_field(hex, tile)
local original_elevation = tile.elevation
-- making the tile's elevation very large *should* make it unwalkable
tile.elevation = 999
local flow_field = generate_flow_field(state.map, HEX_GRID_CENTER)
local result = not hex_map_get(flow_field, 0, 0)
tile.elevation = original_elevation
return result, flow_field
end
function grid_cost(map, from, to) function grid_cost(map, from, to)
local t1, t2 = map.get(from.x, from.y), map.get(to.x, to.y) local t1, t2 = map.get(from.x, from.y), map.get(to.x, to.y)
@ -102,9 +90,7 @@ function generate_flow_field(map, start)
return dijkstra(map, start, nil, grid_cost) return dijkstra(map, start, nil, grid_cost)
end end
function generate_and_apply_flow_field(map, start, world)
local flow_field = generate_flow_field(map, start)
function apply_flow_field(map, flow_field, world)
local flow_field_hidden = world and world"flow_field" and world"flow_field".hidden or true local flow_field_hidden = world and world"flow_field" and world"flow_field".hidden or true
if world and world"flow_field" then if world and world"flow_field" then
world:remove"flow_field" world:remove"flow_field"
@ -136,6 +122,21 @@ function generate_and_apply_flow_field(map, start, world)
end end
end end
function making_hex_unwalkable_breaks_flow_field(hex, tile)
if not mob_can_pass_through(nil, hex, tile) then
return false
end
local original_elevation = tile.elevation
-- making the tile's elevation very large *should* make it unwalkable
tile.elevation = 999
local flow_field = generate_flow_field(state.map, HEX_GRID_CENTER)
local result = not hex_map_get(flow_field, 0, 0)
tile.elevation = original_elevation
return result, flow_field
end
function random_map(seed) function random_map(seed)
local map = rectangular_map(HEX_GRID_DIMENSIONS.x, HEX_GRID_DIMENSIONS.y, seed) local map = rectangular_map(HEX_GRID_DIMENSIONS.x, HEX_GRID_DIMENSIONS.y, seed)
math.randomseed(map.seed) math.randomseed(map.seed)
@ -197,7 +198,7 @@ function random_map(seed)
end) end)
end end
generate_and_apply_flow_field(map, HEX_GRID_CENTER, world)
apply_flow_field(map, generate_flow_field(map, HEX_GRID_CENTER), world)
return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world
end end

2
src/mob.lua

@ -25,7 +25,7 @@ end
-- check if a the tile at |hex| is passable by |mob| -- check if a the tile at |hex| is passable by |mob|
function mob_can_pass_through(mob, hex) function mob_can_pass_through(mob, hex)
local tile = state.map.get(hex.x, hex.y) local tile = state.map.get(hex.x, hex.y)
return tile and tile_is_medium_elevation(tile)
return tile_is_medium_elevation(tile)
end end
function mob_die(mob, mob_index) function mob_die(mob, mob_index)

7
src/tower.lua

@ -330,13 +330,18 @@ function make_and_register_tower(hex, tower_type)
if tower_type == TOWER_TYPE.REDEYE then if tower_type == TOWER_TYPE.REDEYE then
elseif tower_type == TOWER_TYPE.LIGHTHOUSE then elseif tower_type == TOWER_TYPE.LIGHTHOUSE then
tower.perimeter = ring_map(tower.hex, tower.range) tower.perimeter = ring_map(tower.hex, tower.range)
local tile = state.map.get(hex.x, hex.y)
tile.elevation = tile.elevation + 0.5
elseif tower_type == TOWER_TYPE.WALL then elseif tower_type == TOWER_TYPE.WALL then
state.map.get(hex.x, hex.y).elevation = 0.5
elseif tower_type == TOWER_TYPE.MOAT then elseif tower_type == TOWER_TYPE.MOAT then
state.map.get(hex.x, hex.y).elevation = -0.49
elseif tower_type == TOWER_TYPE.RADAR then elseif tower_type == TOWER_TYPE.RADAR then
end end
generate_and_apply_flow_field(state.map, HEX_GRID_CENTER, state.world)
register_entity(TOWERS, tower) register_entity(TOWERS, tower)
end end

Loading…
Cancel
Save