Browse Source

fix buggies

master
Nicholas Hayashi 4 years ago
parent
commit
6620215d43
  1. BIN
      .DS_Store
  2. 12
      NOTES.md
  3. 39
      main.lua
  4. BIN
      res/arrow.png
  5. 0
      res/cells.jpg
  6. BIN
      res/marquis.png
  7. 0
      res/mob_beeper.png
  8. BIN
      res/radar.aseprite
  9. BIN
      res/tab_icon.zip
  10. BIN
      res/tab_icon/Tab-02.eps
  11. BIN
      res/tab_icon/Tab-02.jpg
  12. BIN
      res/tab_icon/Tab-02.png
  13. 11
      res/tab_icon/Tab-02.svg
  14. BIN
      res/tower1.png
  15. BIN
      res/tower2.png
  16. BIN
      res/tower_lighthouse.png
  17. 0
      res/tower_moat.png
  18. BIN
      res/tower_redeye.png
  19. BIN
      res/tower_wall.aseprite
  20. BIN
      res/tower_wall.png
  21. BIN
      res/wall_closed.png
  22. BIN
      res/wall_open.png
  23. 11
      sound.lua
  24. 30
      src/extra.lua
  25. 1
      src/game.lua
  26. 28
      src/grid.lua
  27. 108
      src/mob.lua
  28. 6
      src/projectile.lua
  29. 49
      src/tower.lua
  30. 12
      src/tower_spec.luaa
  31. 18
      texture.lua

BIN
.DS_Store

12
NOTES.md

@ -10,14 +10,16 @@ MAP RESOURCES
towers: towers:
1 - redeye
- redeye
long-range laser tower long-range laser tower
only buildable on mountains and upgraded walls only buildable on mountains and upgraded walls
upgrades:
???
- lighthouse
light-emitting static tower
only buildable on tiles adjacent to water
mobs strongly prefer to path around lighthouses
-1 - wall
- wall
some fraction of the height of the tallest mountain some fraction of the height of the tallest mountain
makes mob pathing more difficult makes mob pathing more difficult
@ -25,7 +27,7 @@ towers:
- fortifications - lets you build some qualifying towers on top of this tower - fortifications - lets you build some qualifying towers on top of this tower
- spikes - mobs take damage when climbing - spikes - mobs take damage when climbing
-2 - moat
- moat
some fraction of the depth of the deepest lake some fraction of the depth of the deepest lake
makes mob pathing more difficult makes mob pathing more difficult

39
main.lua

@ -36,10 +36,11 @@ PERF_STATS = false -- result of am.perf_stats() -- should be calle
WORLD = false -- root scene node of everything considered to be in the game world WORLD = false -- root scene node of everything considered to be in the game world
-- aka non gui stuff -- 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
MOUSE = false -- position of the mouse at the start of every frame, if an action is tracking it
TIME = 0 -- runtime of the current game in seconds (not whole program runtime)
SCORE = 0 -- score of the player
STARTING_MONEY = 50
MONEY = STARTING_MONEY -- available resources
MOUSE = false -- position of the mouse at the start of every frame, if an action is tracking it
-- global audio settings -- global audio settings
MUSIC_VOLUME = 0.1 MUSIC_VOLUME = 0.1
@ -68,7 +69,7 @@ local function select_hex(hex)
end end
local function can_do_build(hex, tile, tower_type) local function can_do_build(hex, tile, tower_type)
return tower_is_buildable_on(hex, tile, SELECTED_TOWER_TYPE)
return can_afford_tower(MONEY, tower_type) and tower_is_buildable_on(hex, tile, tower_type)
end end
local function game_action(scene) local function game_action(scene)
@ -105,7 +106,14 @@ local function game_action(scene)
end end
if WIN:key_pressed"escape" then if WIN:key_pressed"escape" then
game_end()
WIN.scene"game".paused = true
WIN.scene:action(function()
if WIN:key_pressed"escape" then
WIN.scene"game".paused = false
return true
end
end)
--game_end()
elseif WIN:key_pressed"f1" then elseif WIN:key_pressed"f1" then
TRDT = (TRDT + 1) % #table.keys(TRDTS) TRDT = (TRDT + 1) % #table.keys(TRDTS)
@ -171,26 +179,30 @@ local function game_action(scene)
end end
function do_day_night_cycle() function do_day_night_cycle()
local tstep = (math.sin(TIME) / PERF_STATS.avg_fps + 1)/8
WORLD"negative_mask".color = vec4(tstep)
local slow = 100
local tstep = (math.sin(TIME / 100) + 1) / PERF_STATS.avg_fps
WORLD"negative_mask".color = vec4(tstep){a=1}
end end
function game_end() function game_end()
-- de-initialize stuff -- de-initialize stuff
delete_all_entities() delete_all_entities()
TIME = 0 TIME = 0
SCORE = 0 SCORE = 0
MONEY = 0
MONEY = STARTING_MONEY
WORLD = false WORLD = false
WIN.scene = am.scale(1) ^ game_scene()
WIN.scene = am.group(am.scale(1) ^ game_scene())
end end
function update_score(diff) function update_score(diff)
SCORE = SCORE + diff SCORE = SCORE + diff
end end
function update_money(diff)
MONEY = MONEY + diff
end
local function toolbelt() local function toolbelt()
local toolbelt_height = hex_height(HEX_SIZE) * 2 local toolbelt_height = hex_height(HEX_SIZE) * 2
local tower_tooltip = am.translate(WIN.left + 10, WIN.bottom + toolbelt_height + 20) local tower_tooltip = am.translate(WIN.left + 10, WIN.bottom + toolbelt_height + 20)
@ -283,6 +295,7 @@ function game_scene()
WIN.scene:remove(curtain) WIN.scene:remove(curtain)
end)) end))
-- 2227
HEX_MAP, WORLD = random_map() HEX_MAP, WORLD = random_map()
local scene = am.group{ local scene = am.group{
@ -293,7 +306,7 @@ function game_scene()
score, score,
money, money,
coords, coords,
}
}:tag"game"
scene:action(game_action) scene:action(game_action)
--scene:action(am.play(SOUNDS.TRACK1)) --scene:action(am.play(SOUNDS.TRACK1))
@ -302,6 +315,6 @@ function game_scene()
end end
load_textures() load_textures()
WIN.scene = am.scale(vec2(1)) ^ game_scene()
WIN.scene = am.group(am.scale(vec2(1)) ^ game_scene())
noglobals() noglobals()

BIN
res/arrow.png

Before

Width: 46  |  Height: 58  |  Size: 518 B

0
res/077-8332_001.jpg → res/cells.jpg

Before

Width: 2000  |  Height: 2000  |  Size: 716 KiB

After

Width: 2000  |  Height: 2000  |  Size: 716 KiB

BIN
res/marquis.png

Before

Width: 306  |  Height: 40  |  Size: 452 B

0
res/mob1_1.png → res/mob_beeper.png

Before

Width: 638  |  Height: 639  |  Size: 6.1 KiB

After

Width: 638  |  Height: 639  |  Size: 6.1 KiB

BIN
res/radar.aseprite

BIN
res/tab_icon.zip

BIN
res/tab_icon/Tab-02.eps

BIN
res/tab_icon/Tab-02.jpg

Before

Width: 512  |  Height: 512  |  Size: 32 KiB

BIN
res/tab_icon/Tab-02.png

Before

Width: 512  |  Height: 512  |  Size: 3.8 KiB

11
res/tab_icon/Tab-02.svg

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g id="XMLID_1_">
<rect id="XMLID_3_" x="480.3" width="31.7" height="256"/>
<rect id="XMLID_4_" y="256" width="31.7" height="256"/>
<polygon id="XMLID_5_" points="160.1,351.9 512,351.9 512,416.1 160.1,416.1 160.1,496.2 48.4,384.5 160.1,271.8 "/>
<polygon id="XMLID_6_" points="351.9,160.1 0,160.1 0,95.9 351.9,95.9 351.9,15.8 463.6,128.5 351.9,240.2 "/>
</g>
</svg>

BIN
res/tower1.png

Before

Width: 137  |  Height: 137  |  Size: 2.5 KiB

BIN
res/tower2.png

Before

Width: 32  |  Height: 32  |  Size: 487 B

BIN
res/tower_lighthouse.png

After

Width: 64  |  Height: 64  |  Size: 934 B

0
res/moat1.png → res/tower_moat.png

Before

Width: 137  |  Height: 137  |  Size: 1.8 KiB

After

Width: 137  |  Height: 137  |  Size: 1.8 KiB

BIN
res/tower_redeye.png

After

Width: 64  |  Height: 64  |  Size: 640 B

BIN
res/tower_wall.aseprite

BIN
res/tower_wall.png

After

Width: 100  |  Height: 88  |  Size: 2.0 KiB

BIN
res/wall_closed.png

Before

Width: 100  |  Height: 88  |  Size: 1.9 KiB

BIN
res/wall_open.png

Before

Width: 137  |  Height: 137  |  Size: 1.8 KiB

11
sound.lua

@ -23,12 +23,13 @@ SOUNDS = {
TRACK1 = am.track(am.load_audio("res/track1.ogg"), true, 1, 0.1) TRACK1 = am.track(am.load_audio("res/track1.ogg"), true, 1, 0.1)
} }
-- play a sound with variable pitch
function vplay_sound(seed, range)
return am.play(am.sfxr_synth(seed), false, (math.random() + 0.5)/(range and 1/range or 2))
-- play sound effect with variable pitch
function vplay_sfx(sound, pitch_range)
local pitch = (math.random() + 0.5)/(pitch_range and 1/pitch_range or 2)
WIN.scene:action(am.play(sound, false, pitch, SFX_VOLUME))
end end
function play_sound(seed)
return am.play(am.sfxr_synth(seed), false)
function play_sfx(sound)
WIN.scene:action(am.play(sound, false, 1, SFX_VOLUME))
end end

30
src/extra.lua

@ -24,3 +24,33 @@ function table.find(t, predicate)
return nil return nil
end end
function quicksort(t, low_index, high_index, comparator)
local function partition(t, low_index, high_index)
local i = low_index - 1
local pivot = t[high_index]
for j = low_index, high_index - 1 do
if comparator(t[j], t[pivot]) <= 0 then
i = i + 1
t[i], t[j] = t[j], t[i]
end
end
t[i + 1], t[high_index] = t[high_index], t[i + 1]
return i + 1
end
if #t == 1 then
return t
end
if comparator(t[low_index], t[high_index]) < 0 then
local partition_index = partition(t, low_index, high_index)
quicksort(t, low_index, partition_index - 1, comparator)
quicksort(t, partition_index + 1, high_index, comparator)
end
return t
end

1
src/tower_spec.lua → src/game.lua

@ -1 +1,2 @@

28
src/grid.lua

@ -2,8 +2,10 @@
-- distance from hex centerpoint to any vertex -- distance from hex centerpoint to any vertex
HEX_SIZE = 20 HEX_SIZE = 20
HEX_PIXEL_SIZE = vec2(hex_width(HEX_SIZE, ORIENTATION.FLAT)
, hex_height(HEX_SIZE, ORIENTATION.FLAT))
HEX_PIXEL_WIDTH = hex_width(HEX_SIZE, ORIENTATION.FLAT)
HEX_PIXEL_HEIGHT = hex_height(HEX_SIZE, ORIENTATION.FLAT)
HEX_PIXEL_DIMENSIONS = vec2(HEX_PIXEL_WIDTH, HEX_PIXEL_HEIGHT)
-- with 1920x1080, this is the minimal dimensions to cover the screen (65x33) -- with 1920x1080, this is the minimal dimensions to cover the screen (65x33)
-- @NOTE added 2 cell padding, because we terraform the very outer edge and it looks ugly -- @NOTE added 2 cell padding, because we terraform the very outer edge and it looks ugly
@ -17,6 +19,9 @@ HEX_GRID_CENTER = vec2(math.floor(HEX_GRID_WIDTH/2)
, 0) , 0)
-- math.floor(HEX_GRID_HEIGHT/2)) -- math.floor(HEX_GRID_HEIGHT/2))
HEX_GRID_MINIMUM_ELEVATION = -1
HEX_GRID_MAXIMUM_ELEVATION = 1
-- index is hex coordinates [x][y] -- index is hex coordinates [x][y]
-- { { elevation, node, etc. } } -- { { elevation, node, etc. } }
HEX_MAP = {} HEX_MAP = {}
@ -78,8 +83,9 @@ 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)
return 1 + 10 * math.abs(math.abs(t1.elevation)^0.5
- math.abs(t2.elevation)^0.5)
local epsilon = HEX_GRID_MAXIMUM_ELEVATION - HEX_GRID_MINIMUM_ELEVATION
return epsilon + 10 * math.abs(math.abs(t1.elevation)^0.5
- math.abs(t2.elevation)^0.5)
end end
function generate_and_apply_flow_field(map, start, world) function generate_and_apply_flow_field(map, start, world)
@ -94,7 +100,7 @@ function generate_and_apply_flow_field(map, start, world)
^ am.text(string.format("%.1f", f.priority * 10))) ^ am.text(string.format("%.1f", f.priority * 10)))
else else
-- should fire exactly once per goal hex -- should fire exactly once per goal hex
log('no priority')
--log('no priority')
end end
end end
end end
@ -135,14 +141,14 @@ function random_map(seed)
for j,noise in pairs(map[i]) do for j,noise in pairs(map[i]) do
local evenq = hex_to_evenq(vec2(i, j)) local evenq = hex_to_evenq(vec2(i, j))
-- check if we're on an edge -- terraform edges to be passable
if evenq.x == 0 or evenq.x == (HEX_GRID_WIDTH - 1) if evenq.x == 0 or evenq.x == (HEX_GRID_WIDTH - 1)
or -evenq.y == 0 or -evenq.y == (HEX_GRID_HEIGHT - 1) then or -evenq.y == 0 or -evenq.y == (HEX_GRID_HEIGHT - 1) then
-- if we're on an edge -- terraform edges to be passable
noise = 0 noise = 0
-- also terraform the center of the grid to be passable
-- very infrequently, but still sometimes it is not medium elevation
elseif i == HEX_GRID_CENTER.x and j == HEX_GRID_CENTER.y then elseif i == HEX_GRID_CENTER.x and j == HEX_GRID_CENTER.y then
-- also terraform the center of the grid to be passable
-- very infrequently, but still sometimes it is not medium elevation
noise = 0 noise = 0
else else
@ -178,10 +184,10 @@ function random_map(seed)
end) end)
end end
generate_and_apply_flow_field(map, HEX_GRID_CENTER)
generate_and_apply_flow_field(map, HEX_GRID_CENTER, world)
--world:append(am.translate(hex_to_pixel(HEX_GRID_CENTER))
-- ^ pack_texture_into_sprite(TEX_SATELLITE, HEX_PIXEL_SIZE.x*2, HEX_PIXEL_SIZE.y*2))
world:append(am.translate(hex_to_pixel(HEX_GRID_CENTER))
^ pack_texture_into_sprite(TEX_SATELLITE, HEX_PIXEL_WIDTH, HEX_PIXEL_HEIGHT))
return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world
end end

108
src/mob.lua

@ -11,7 +11,7 @@ mob(entity) structure:
--]] --]]
MAX_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
MOB_SIZE = MAX_MOB_SIZE
function mobs_on_hex(hex) function mobs_on_hex(hex)
local t = {} local t = {}
@ -37,7 +37,7 @@ function mob_can_pass_through(mob, hex)
end end
function mob_die(mob, mob_index) function mob_die(mob, mob_index)
WORLD:action(vplay_sound(SOUNDS.EXPLOSION1))
vplay_sfx(SOUNDS.EXPLOSION1)
delete_entity(MOBS, mob_index) delete_entity(MOBS, mob_index)
end end
@ -45,6 +45,7 @@ function do_hit_mob(mob, damage, mob_index)
mob.health = mob.health - damage mob.health = mob.health - damage
if mob.health <= 0 then if mob.health <= 0 then
update_score(mob.bounty) update_score(mob.bounty)
update_money(mob.bounty)
mob_die(mob, mob_index) mob_die(mob, mob_index)
end end
end end
@ -79,90 +80,97 @@ local function get_spawn_hex()
return evenq_to_hex(vec2(x, -y)) return evenq_to_hex(vec2(x, -y))
end end
local function mob_update(mob, mob_index)
local function update_mob(mob, mob_index)
local last_frame_hex = mob.hex local last_frame_hex = mob.hex
mob.hex = pixel_to_hex(mob.position) mob.hex = pixel_to_hex(mob.position)
if mob.hex == HEX_GRID_CENTER then if mob.hex == HEX_GRID_CENTER then
log('die')
update_score(-mob.health) update_score(-mob.health)
mob_die(mob, mob_index) mob_die(mob, mob_index)
return true return true
end end
-- figure out movement -- figure out movement
local frame_target, tile = nil, nil
if mob.path then
log('A*')
-- we have an explicitly stored target
local path_entry = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y]
frame_target = path_entry.hex
-- check if our target is valid, and if it's not we aren't going to move this frame.
-- recalculate our path.
if last_frame_hex ~= mob.hex and not mob_can_pass_through(mob, frame_target) then
log('recalc')
mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER)
frame_target = nil
end
else
-- use the map's flow field - gotta find the the best neighbour
local neighbours = HEX_MAP.neighbours(mob.hex)
if #neighbours > 0 then
local first_neighbour = neighbours[1]
tile = HEX_MAP.get(first_neighbour.x, first_neighbour.y)
local lowest_cost_hex = first_neighbour
local lowest_cost = tile.priority or 0
for _,n in pairs(neighbours) do
tile = HEX_MAP.get(n.x, n.y)
local current_cost = tile.priority
if current_cost and current_cost < lowest_cost then
lowest_cost_hex = n
lowest_cost = current_cost
end
if last_frame_hex ~= mob.hex or not mob.frame_target then
local frame_target, tile = nil, nil
if mob.path then
log('A*')
-- we have an explicitly stored target
local path_entry = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y]
mob.frame_target = path_entry.hex
-- check if our target is valid, and if it's not we aren't going to move this frame.
-- recalculate our path.
if last_frame_hex ~= mob.hex and not mob_can_pass_through(mob, frame_target) then
log('recalc')
mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER)
mob.frame_target = nil
end end
frame_target = lowest_cost_hex
else else
log('no neighbours')
log(table.tostring(neighbours) .. mob.hex .. mob.position)
-- use the map's flow field - gotta find the the best neighbour
local neighbours = HEX_MAP.neighbours(mob.hex)
if #neighbours > 0 then
local first_neighbour = neighbours[1]
tile = HEX_MAP.get(first_neighbour.x, first_neighbour.y)
local lowest_cost_hex = first_neighbour
local lowest_cost = tile.priority or 0
for _,n in pairs(neighbours) do
tile = HEX_MAP.get(n.x, n.y)
local current_cost = tile.priority
if current_cost and current_cost < lowest_cost then
lowest_cost_hex = n
lowest_cost = current_cost
end
end
mob.frame_target = lowest_cost_hex
else
log('no neighbours')
end
end end
end end
if mob.frame_target and mob.frame_target == last_frame_hex then
log('backpedaling')
log(mob.frame_target)
log(mob.hex)
log(last_frame_hex)
--WIN.scene.paused = true
end
-- do movement -- do movement
if frame_target then
if mob.frame_target then
-- this is supposed to achieve frame rate independence, but i have no idea if it actually does -- this is supposed to achieve frame rate independence, but i have no idea if it actually does
local rate = 1 + mob.speed / PERF_STATS.avg_fps
-- the constant multiplier at the beginning is how many pixels we want a mob with speed 1 to move in one frame
local rate = 4 * mob.speed / PERF_STATS.avg_fps
mob.position = mob.position + math.normalize(hex_to_pixel(frame_target) - mob.position) * rate
mob.position = mob.position + math.normalize(hex_to_pixel(mob.frame_target) - mob.position) * rate
mob.node.position2d = mob.position mob.node.position2d = mob.position
else else
log('no target') log('no target')
end end
--[[ passive animation
-- passive animation
if math.random() < 0.01 then if math.random() < 0.01 then
mob.node"rotate":action(am.tween(0.3, { angle = mob.node"rotate".angle + math.pi*3 })) mob.node"rotate":action(am.tween(0.3, { angle = mob.node"rotate".angle + math.pi*3 }))
else else
mob.node"rotate".angle = math.wrapf(mob.node"rotate".angle + am.delta_time, math.pi*2) mob.node"rotate".angle = math.wrapf(mob.node"rotate".angle + am.delta_time, math.pi*2)
end end
--]]
end end
local function make_and_register_mob()
local function make_and_register_mob(mob_type)
local mob = make_basic_entity( local mob = make_basic_entity(
get_spawn_hex(), get_spawn_hex(),
am.circle(vec2(0), MOB_SIZE, COLORS.SUNRAY),
mob_update
am.rotate(TIME) ^ pack_texture_into_sprite(TEX_MOB_BEEPER, MOB_SIZE, MOB_SIZE),
update_mob
) )
--mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER) --mob.path = get_mob_path(mob, HEX_MAP, mob.hex, HEX_GRID_CENTER)
mob.health = 10 mob.health = 10
mob.speed = 100
mob.speed = 10
mob.bounty = 5 mob.bounty = 5
mob.hurtbox_radius = MOB_SIZE mob.hurtbox_radius = MOB_SIZE

6
src/projectile.lua

@ -10,7 +10,7 @@ bullet/projectile(entity) structure
} }
--]] --]]
function projectile_update(projectile, projectile_index)
function update_projectile(projectile, projectile_index)
projectile.position = projectile.position + projectile.vector * projectile.velocity projectile.position = projectile.position + projectile.vector * projectile.velocity
projectile.node.position2d = projectile.position projectile.node.position2d = projectile.position
projectile.hex = pixel_to_hex(projectile.position) projectile.hex = pixel_to_hex(projectile.position)
@ -63,13 +63,13 @@ function projectile_update(projectile, projectile_index)
-- hit the mob, delete ourselves, affect the world -- hit the mob, delete ourselves, affect the world
do_hit_mob(closest_mob, projectile.damage, closest_mob_index) do_hit_mob(closest_mob, projectile.damage, closest_mob_index)
delete_entity(PROJECTILES, projectile_index) delete_entity(PROJECTILES, projectile_index)
WORLD:action(vplay_sound(SOUNDS.HIT1, 0.5))
vplay_sfx(SOUNDS.HIT1, 0.5)
end end
function make_and_register_projectile(hex, vector, velocity, damage, hitbox_radius) function make_and_register_projectile(hex, vector, velocity, damage, hitbox_radius)
local projectile = make_basic_entity(hex local projectile = make_basic_entity(hex
, am.line(vector, vector*hitbox_radius, 3, COLORS.CLARET) , am.line(vector, vector*hitbox_radius, 3, COLORS.CLARET)
, projectile_update)
, update_projectile)
projectile.vector = vector projectile.vector = vector
projectile.velocity = velocity projectile.velocity = velocity
projectile.damage = damage projectile.damage = damage

49
src/tower.lua

@ -11,14 +11,30 @@ tower(entity) structure:
TOWER_TYPE = { TOWER_TYPE = {
REDEYE = 1, REDEYE = 1,
WALL = 11,
MOAT = 12,
WALL = 2,
MOAT = 3,
} }
function get_tower_build_cost(tower_type)
if tower_type == TOWER_TYPE.REDEYE then return 25
elseif tower_type == TOWER_TYPE.WALL then return 5
elseif tower_type == TOWER_TYPE.MOAT then return 15
end
end
function can_afford_tower(money, tower_type)
local cost = get_tower_build_cost(tower_type)
if tower_type == TOWER_TYPE.REDEYE then return (money - cost) > 0
elseif tower_type == TOWER_TYPE.WALL then return (money - cost) > 0
elseif tower_type == TOWER_TYPE.MOAT then return (money - cost) > 0
end
end
function get_tower_texture(tower_type) function get_tower_texture(tower_type)
if tower_type == TOWER_TYPE.REDEYE then return TEX_TOWER2
elseif tower_type == TOWER_TYPE.WALL then return TEX_WALL_CLOSED
elseif tower_type == TOWER_TYPE.MOAT then return TEX_MOAT1
if tower_type == TOWER_TYPE.REDEYE then return TEX_TOWER_REDEYE
elseif tower_type == TOWER_TYPE.WALL then return TEX_TOWER_WALL
elseif tower_type == TOWER_TYPE.MOAT then return TEX_TOWER_MOAT
end end
end end
@ -35,21 +51,17 @@ local function get_tower_update_function(tower_type)
end end
end end
local function make_tower_sprite(tower_type)
local texture = get_tower_texture(tower_type)
if tower_type == TOWER_TYPE.REDEYE then
return pack_texture_into_sprite(texture, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)
elseif tower_type == TOWER_TYPE.WALL then
return pack_texture_into_sprite(TEX_WALL_CLOSED, HEX_PIXEL_SIZE.x + 1, HEX_PIXEL_SIZE.y + 1)
--return am.circle(vec2(0), HEX_SIZE, COLORS.VERY_DARK_GRAY, 6)
function update_wall_texture(hex)
for _,n in pairs(hex_neighbours(hex)) do
local tile = HEX_MAP.get(hex.x, hex.y)
elseif tower_type == TOWER_TYPE.MOAT then
--return pack_texture_into_sprite(TEX_MOAT1, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)
return am.circle(vec2(0), HEX_SIZE, COLORS.YALE_BLUE, 6)
end end
end end
local function make_tower_sprite(tower_type)
return pack_texture_into_sprite(get_tower_texture(tower_type), HEX_PIXEL_WIDTH, HEX_PIXEL_HEIGHT)
end
function tower_on_hex(hex) function tower_on_hex(hex)
return table.find(TOWERS, function(tower) return table.find(TOWERS, function(tower)
return tower.hex == hex return tower.hex == hex
@ -99,7 +111,7 @@ function update_tower_redeye(tower, tower_index)
) )
tower.last_shot_time = TIME tower.last_shot_time = TIME
tower.node:action(vplay_sound(SOUNDS.LASER2))
vplay_sfx(SOUNDS.LASER2)
end end
end end
end end
@ -123,7 +135,8 @@ function make_and_register_tower(hex, tower_type)
end end
function build_tower(hex, tower_type) function build_tower(hex, tower_type)
update_money(-get_tower_build_cost(tower_type))
make_and_register_tower(hex, tower_type) make_and_register_tower(hex, tower_type)
WIN.scene:action(am.play(am.sfxr_synth(SOUNDS.EXPLOSION4)))
vplay_sfx(SOUNDS.EXPLOSION4)
end end

12
src/tower_spec.luaa

@ -1,12 +0,0 @@
REDEYE = {
}

18
texture.lua

@ -1,23 +1,17 @@
function load_textures() function load_textures()
TEX_MARQUIS = am.texture2d("res/marquis.png")
TEX_BUTTON1 = am.texture2d("res/button1.png") TEX_BUTTON1 = am.texture2d("res/button1.png")
TEX_WIDER_BUTTON1 = am.texture2d("res/wider_button1.png") TEX_WIDER_BUTTON1 = am.texture2d("res/wider_button1.png")
TEX_TAB_ICON = am.texture2d("res/tab_icon.png") TEX_TAB_ICON = am.texture2d("res/tab_icon.png")
TEX_ARROW = am.texture2d("res/arrow.png")
TEX_RADAR1 = am.texture2d("res/radar.png")
TEX_SATELLITE = am.texture2d("res/satelite.png") TEX_SATELLITE = am.texture2d("res/satelite.png")
TEX_WALL_CLOSED = am.texture2d("res/wall_closed.png")
TEX_MOAT1 = am.texture2d("res/moat1.png")
TEX_TOWER1 = am.texture2d("res/tower1.png")
TEX_TOWER2 = am.texture2d("res/tower2.png")
TEX_MOB1_1 = am.texture2d("res/mob1_1.png")
TEX_MOB2_1 = am.texture2d("res/mob2_1.png")
TEX_TOWER_WALL = am.texture2d("res/tower_wall.png")
TEX_TOWER_MOAT = am.texture2d("res/tower_moat.png")
TEX_TOWER_REDEYE = am.texture2d("res/tower_redeye.png")
TEX_TOWER_LIGHTHOUSE = am.texture2d("res/tower_lighthouse.png")
TEX_MOB_BEEPER = am.texture2d("res/mob_beeper.png")
end end
function pack_texture_into_sprite(texture, width, height) function pack_texture_into_sprite(texture, width, height)

Loading…
Cancel
Save