Browse Source

tab icon

master
Nicholas Hayashi 4 years ago
parent
commit
997b839620
  1. BIN
      .DS_Store
  2. 24
      NOTES.md
  3. 78
      main.lua
  4. BIN
      res/.DS_Store
  5. BIN
      res/radar.aseprite
  6. BIN
      res/radar.png
  7. BIN
      res/tab_icon.png
  8. BIN
      res/tab_icon.zip
  9. BIN
      res/tab_icon/Tab-02.eps
  10. BIN
      res/tab_icon/Tab-02.jpg
  11. BIN
      res/tab_icon/Tab-02.png
  12. 11
      res/tab_icon/Tab-02.svg
  13. BIN
      res/wider_button1.png
  14. 3
      sound.lua
  15. 7
      src/entity.lua
  16. 21
      src/grid.lua
  17. 3
      src/hexyz.lua
  18. 8
      src/mob.lua
  19. 27
      src/tower.lua
  20. 1
      src/tower_spec.lua
  21. 12
      src/tower_spec.luaa
  22. 3
      texture.lua

BIN
.DS_Store

24
NOTES.md

@ -1,36 +1,34 @@
SEEED 1835 has bad start SEEED 1835 has bad start
todoooos & notes
@TODO test optimizing pathfinding via breadth first search/djikstra @TODO test optimizing pathfinding via breadth first search/djikstra
i think i want more or less no such thing as 'impassable' terrain
all mobs always can always traverse everything, though they initially will give the impression that certain tiles are impassable by prefering certain tiles.
the illusion is likely to be broken when you attempt to fully wall-off an area, and mobs begin deciding to climb over mountains or swim through lakes. this will come at great cost to them, but they will be capable of it
MAP RESOURCES MAP RESOURCES
- spawn diamonds or special floating resources that give you bonuses for building on, whether it's score, money, or boosting the effectiveness of the tower you place on top, etc. - spawn diamonds or special floating resources that give you bonuses for building on, whether it's score, money, or boosting the effectiveness of the tower you place on top, etc.
- killing certain mobs may cause these resources to spawn on the hex they died on - killing certain mobs may cause these resources to spawn on the hex they died on
towers: towers:
0 - wall
1 - redeye
long-range laser tower
only buildable on mountains and upgraded walls
upgrades:
???
-1 - 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
upgrades: upgrades:
- +height - making the tower taller makes it more difficult/costly for mobs to climb over it
- spikes - mobs take damage when climbing
- fortifications - lets you build some qualifying towers on top of this tower
- spikes - mobs take damage when climbing
1 - moat
-2 - 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
upgrades: upgrades:
- +depth - making the moat deeper makes it more difficult/costly for mobs to swim through it
- alligators - mobs take damage while swimming - alligators - mobs take damage while swimming

78
main.lua

@ -27,7 +27,7 @@ WIN = am.window{
title = "hexyz", title = "hexyz",
highdpi = true, highdpi = true,
letterbox = true, letterbox = true,
clear_color = COLORS.TRUE_BLACK
clear_color = color_at(0)
} }
OFF_SCREEN = vec2(WIN.width * 2) -- arbitrary pixel position that is garunteed to be off screen OFF_SCREEN = vec2(WIN.width * 2) -- arbitrary pixel position that is garunteed to be off screen
@ -61,8 +61,15 @@ local TRDTS = {
} }
local TRDT = TRDTS.SEED local TRDT = TRDTS.SEED
-- a function - get sets later inside toolbelt
--local select_tower_type
local function select_hex(hex)
local tower = tower_on_hex(hex)
local tile = HEX_MAP.get(hex.x, hex.y)
log(tile)
end
local function can_do_build(hex, tile, tower_type)
return tower_is_buildable_on(hex, tile, SELECTED_TOWER_TYPE)
end
local function game_action(scene) local function game_action(scene)
if SCORE < 0 then game_end() end if SCORE < 0 then game_end() end
@ -78,13 +85,13 @@ local function game_action(scene)
local centered_evenq = evenq{ y = -evenq.y } - vec2(math.floor(HEX_GRID_WIDTH/2) local centered_evenq = evenq{ y = -evenq.y } - vec2(math.floor(HEX_GRID_WIDTH/2)
, math.floor(HEX_GRID_HEIGHT/2)) , math.floor(HEX_GRID_HEIGHT/2))
local tile = HEX_MAP.get(hex.x, hex.y) local tile = HEX_MAP.get(hex.x, hex.y)
local hot = is_interactable(tile, evenq{ y = -evenq.y })
local hot = evenq_is_interactable(evenq{ y = -evenq.y })
do_entity_updates() do_entity_updates()
do_mob_spawning() do_mob_spawning()
if WIN:mouse_pressed"left" then if WIN:mouse_pressed"left" then
if hot and is_buildable(hex, tile, nil) then
if hot and can_do_build(hex, tile, SELECTED_TOWER_TYPE) then
build_tower(hex, SELECTED_TOWER_TYPE) build_tower(hex, SELECTED_TOWER_TYPE)
end end
end end
@ -105,6 +112,19 @@ local function game_action(scene)
elseif WIN:key_pressed"tab" then elseif WIN:key_pressed"tab" then
select_tower_type((SELECTED_TOWER_TYPE) % #table.keys(TOWER_TYPE) + 1) select_tower_type((SELECTED_TOWER_TYPE) % #table.keys(TOWER_TYPE) + 1)
elseif WIN:key_pressed"1" then select_tower_type(TOWER_TYPE.REDEYE)
elseif WIN:key_pressed"2" then select_tower_type(2)
elseif WIN:key_pressed"3" then select_tower_type(3)
elseif WIN:key_pressed"4" then --select_tower_type(4)
elseif WIN:key_pressed"5" then --select_tower_type(5)
elseif WIN:key_pressed"6" then --select_tower_type(6)
elseif WIN:key_pressed"7" then --select_tower_type(7)
elseif WIN:key_pressed"8" then --select_tower_type(8)
elseif WIN:key_pressed"9" then --select_tower_type(9)
elseif WIN:key_pressed"0" then --select_tower_type(10)
elseif WIN:key_pressed"-" then --select_tower_type(1)
elseif WIN:key_pressed"=" then --select_tower_type(1)
end end
if tile and hot then if tile and hot then
@ -142,7 +162,7 @@ local function game_action(scene)
WIN.scene"coords".text = str WIN.scene"coords".text = str
end end
do_day_night_cycle()
--do_day_night_cycle()
end end
function do_day_night_cycle() function do_day_night_cycle()
@ -151,11 +171,13 @@ function do_day_night_cycle()
end end
function game_end() function game_end()
WIN.scene.paused = true
-- de-initialize stuff -- de-initialize stuff
delete_all_entities() delete_all_entities()
TIME = 0
SCORE = 0 SCORE = 0
MONEY = 0
WORLD = false
WIN.scene = am.scale(1) ^ game_scene() WIN.scene = am.scale(1) ^ game_scene()
end end
@ -168,7 +190,6 @@ 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)
^ am.text(tower_type_tostring(SELECTED_TOWER_TYPE), "left"):tag"tower_tooltip" ^ am.text(tower_type_tostring(SELECTED_TOWER_TYPE), "left"):tag"tower_tooltip"
local toolbelt = am.group{ local toolbelt = am.group{
tower_tooltip, tower_tooltip,
am.rect(WIN.left, WIN.bottom, WIN.right, WIN.bottom + toolbelt_height, COLORS.TRANSPARENT) am.rect(WIN.left, WIN.bottom, WIN.right, WIN.bottom + toolbelt_height, COLORS.TRANSPARENT)
@ -176,34 +197,53 @@ local function toolbelt()
local padding = 15 local padding = 15
local size = toolbelt_height - padding local size = toolbelt_height - padding
local offset = vec2(WIN.left + padding/3, WIN.bottom + padding/3)
local half_size = size/2
local offset = vec2(WIN.left + padding*3, WIN.bottom + padding/3)
local keys = {
'1', '2', '3', '4', '5', '6', '7', '9', '0', '-', '='
}
local tab_button = am.translate(vec2(0, half_size) + offset)
^ am.group{
pack_texture_into_sprite(TEX_WIDER_BUTTON1, 54, 32),
pack_texture_into_sprite(TEX_TAB_ICON, 25, 25)
}
toolbelt:append(tab_button)
local tower_select_square = ( local tower_select_square = (
am.translate(vec2(size + padding, size/2) + offset)
am.translate(vec2(size + padding, half_size) + offset)
^ am.rect(-size/2-3, -size/2-3, size/2+3, size/2+3, COLORS.SUNRAY) ^ am.rect(-size/2-3, -size/2-3, size/2+3, size/2+3, COLORS.SUNRAY)
):tag"tower_select_square" ):tag"tower_select_square"
toolbelt:append(tower_select_square) toolbelt:append(tower_select_square)
local tower_type_values = table.values(TOWER_TYPE)
local tower_type_values = table.values(TOWER_TYPE)
local keys = { '1', '2', '3', '4', '5', '6', '7', '9', '0', '-', '=' }
for i = 1, #keys do for i = 1, #keys do
if tower_type_values[i] then if tower_type_values[i] then
toolbelt:append( toolbelt:append(
am.translate(vec2(size + padding, 0) * i + offset) am.translate(vec2(size + padding, 0) * i + offset)
^ am.group{ ^ am.group{
am.translate(0, size/2)
am.translate(0, half_size)
^ pack_texture_into_sprite(TEX_BUTTON1, size, size), ^ pack_texture_into_sprite(TEX_BUTTON1, size, size),
am.translate(0, size/2)
am.translate(0, half_size)
^ pack_texture_into_sprite(get_tower_texture(tower_type_values[i]), size, size), ^ pack_texture_into_sprite(get_tower_texture(tower_type_values[i]), size, size),
am.translate(vec2(size/2))
am.translate(vec2(half_size))
^ am.group{
pack_texture_into_sprite(TEX_BUTTON1, half_size, half_size),
am.scale(2)
^ am.text(keys[i], COLORS.BLACK)
}
}
)
else
toolbelt:append(
am.translate(vec2(size + padding, 0) * i + offset)
^ am.group{
am.translate(0, half_size)
^ pack_texture_into_sprite(TEX_BUTTON1, size, size),
am.translate(vec2(half_size))
^ am.group{ ^ am.group{
pack_texture_into_sprite(TEX_BUTTON1, size/2, size/2),
pack_texture_into_sprite(TEX_BUTTON1, half_size, half_size),
am.scale(2) am.scale(2)
^ am.text(keys[i], COLORS.BLACK) ^ am.text(keys[i], COLORS.BLACK)
} }

BIN
res/.DS_Store

BIN
res/radar.aseprite

BIN
res/radar.png

After

Width: 64  |  Height: 64  |  Size: 1.8 KiB

BIN
res/tab_icon.png

After

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

BIN
res/tab_icon.zip

BIN
res/tab_icon/Tab-02.eps

BIN
res/tab_icon/Tab-02.jpg

After

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

BIN
res/tab_icon/Tab-02.png

After

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

11
res/tab_icon/Tab-02.svg

@ -0,0 +1,11 @@
<?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/wider_button1.png

After

Width: 256  |  Height: 128  |  Size: 533 B

3
sound.lua

@ -5,7 +5,8 @@ SOUNDS = {
EXPLOSION2 = 19725402, EXPLOSION2 = 19725402,
EXPLOSION3 = 69338002, EXPLOSION3 = 69338002,
EXPLOSION4 = 92224102, EXPLOSION4 = 92224102,
HIT1 = 25811004,
COIN1 = 10262800,
HIT2 = 25811004,
LASER1 = 79859301, LASER1 = 79859301,
LASER2 = 86914201, LASER2 = 86914201,
PUSH1 = 30455908, PUSH1 = 30455908,

7
src/entity.lua

@ -21,7 +21,8 @@ function make_basic_entity(hex, node, update, position)
-- usually you'll provide a hex and not a position, and the entity will spawn in the center -- 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 -- of the hex. if you want an entity to exist not at the center of a hex, you can provide a
-- pixel position instead
-- pixel position instead, then the provided hex is ignored and instead we calculate what hex
-- corresponds to the provided pixel position
if position then if position then
entity.position = position entity.position = position
entity.hex = pixel_to_hex(entity.position) entity.hex = pixel_to_hex(entity.position)
@ -30,8 +31,8 @@ function make_basic_entity(hex, node, update, position)
entity.position = hex_to_pixel(hex) entity.position = hex_to_pixel(hex)
end end
entity.update = update
entity.node = am.translate(entity.position) ^ node
entity.update = update
entity.node = am.translate(entity.position) ^ node
return entity return entity
end end

21
src/grid.lua

@ -37,9 +37,9 @@ end
-- transform coordinates by this to pretend 0,0 is elsewhere -- transform coordinates by this to pretend 0,0 is elsewhere
WORLDSPACE_COORDINATE_OFFSET = -HEX_GRID_PIXEL_DIMENSIONS/2 WORLDSPACE_COORDINATE_OFFSET = -HEX_GRID_PIXEL_DIMENSIONS/2
-- the outer edges of the map are not interactable, most action occurs in the center
-- the outer edges of the map are not interactable, most action occurs in the center-ish
HEX_GRID_INTERACTABLE_REGION_PADDING = 4 HEX_GRID_INTERACTABLE_REGION_PADDING = 4
function is_interactable(tile, evenq)
function evenq_is_interactable(evenq)
return point_in_rect(evenq, { return point_in_rect(evenq, {
x1 = HEX_GRID_INTERACTABLE_REGION_PADDING, x1 = HEX_GRID_INTERACTABLE_REGION_PADDING,
x2 = HEX_GRID_WIDTH - HEX_GRID_INTERACTABLE_REGION_PADDING, x2 = HEX_GRID_WIDTH - HEX_GRID_INTERACTABLE_REGION_PADDING,
@ -48,6 +48,14 @@ function is_interactable(tile, evenq)
}) })
end end
local function tile_is_medium_elevation(tile)
return tile.elevation >= -0.5 and tile.elevation < 0.5
end
function tilehex_is_buildable(tile, hex)
return tile_is_medium_elevation(tile) and hex ~= HEX_GRID_CENTER
end
-- map elevation to appropriate color -- 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
@ -92,9 +100,15 @@ function random_map(seed)
or -evenq.y == 0 or -evenq.y == (HEX_GRID_HEIGHT - 1) then or -evenq.y == 0 or -evenq.y == (HEX_GRID_HEIGHT - 1) then
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
noise = 0
else else
-- scale noise to be closer to 0 the closer we are to the center -- scale noise to be closer to 0 the closer we are to the center
-- @NOTE i don't know if this 100% of the time makes the center tile passable, but it seems to 99.9+% of the time -- @NOTE i don't know if this 100% of the time makes the center tile passable, but it seems to 99.9+% of the time
-- @NOTE it doesn't. seed: 1835
local nx, ny = evenq.x/HEX_GRID_WIDTH - 0.5, -evenq.y/HEX_GRID_HEIGHT - 0.5 local nx, ny = evenq.x/HEX_GRID_WIDTH - 0.5, -evenq.y/HEX_GRID_HEIGHT - 0.5
local d = (nx^2 + ny^2)^0.5 / 0.5^0.5 local d = (nx^2 + ny^2)^0.5 / 0.5^0.5
noise = noise * d^0.125 -- arbitrary, seems to work good noise = noise * d^0.125 -- arbitrary, seems to work good
@ -124,7 +138,8 @@ function random_map(seed)
end end
end end
world:append(am.circle(hex_to_pixel(HEX_GRID_CENTER), HEX_SIZE/2, COLORS.MAGENTA, 4))
world:append(am.translate(hex_to_pixel(HEX_GRID_CENTER))
^ pack_texture_into_sprite(TEX_RADAR1, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y))
return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world return map, am.translate(WORLDSPACE_COORDINATE_OFFSET) ^ world
end end

3
src/hexyz.lua

@ -551,9 +551,6 @@ function Astar(map, start, goal, heuristic, cost_f)
end end
end end
end end
if not made_it then
log('aaaa')
end
return path, made_it return path, made_it
end end

8
src/mob.lua

@ -92,13 +92,11 @@ local function mob_update(mob, mob_index)
local frame_target = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y] local frame_target = mob.path[mob.hex.x] and mob.path[mob.hex.x][mob.hex.y]
-- frame_target will be false when we are one hex away from the center, -- frame_target will be false when we are one hex away from the center,
-- or nil if something went wrong -- or nil if something went wrong
if frame_target == false then
if not frame_target then
frame_target = { hex = HEX_GRID_CENTER, priority = 0 } frame_target = { hex = HEX_GRID_CENTER, priority = 0 }
end
elseif frame_target == nil then
log("bad")
elseif mob_can_pass_through(mob, frame_target.hex) then
if mob_can_pass_through(mob, frame_target.hex) 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 * (1/frame_target.priority) / PERF_STATS.avg_fps local rate = 1 + mob.speed * (1/frame_target.priority) / PERF_STATS.avg_fps

27
src/tower.lua

@ -41,8 +41,8 @@ local function make_tower_sprite(tower_type)
return pack_texture_into_sprite(texture, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y) return pack_texture_into_sprite(texture, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)
elseif tower_type == TOWER_TYPE.WALL then elseif tower_type == TOWER_TYPE.WALL then
--return pack_texture_into_sprite(TEX_WALL_CLOSED, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)
return am.circle(vec2(0), HEX_SIZE, COLORS.VERY_DARK_GRAY, 6)
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)
elseif tower_type == TOWER_TYPE.MOAT then elseif tower_type == TOWER_TYPE.MOAT then
--return pack_texture_into_sprite(TEX_MOAT1, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y) --return pack_texture_into_sprite(TEX_MOAT1, HEX_PIXEL_SIZE.x, HEX_PIXEL_SIZE.y)
@ -50,9 +50,26 @@ local function make_tower_sprite(tower_type)
end end
end end
function is_buildable(hex, tile, tower)
function tower_on_hex(hex)
return table.find(TOWERS, function(tower)
return tower.hex == hex
end)
end
function tower_is_buildable_on(hex, tile, tower_type)
if hex == HEX_GRID_CENTER then return false end
local blocked = #mobs_on_hex(hex) ~= 0 local blocked = #mobs_on_hex(hex) ~= 0
return not blocked and tile.elevation <= 0.5 and tile.elevation > -0.5
if tower_type == TOWER_TYPE.REDEYE then
return not blocked and tile.elevation > 0.5
elseif tower_type == TOWER_TYPE.WALL then
return not blocked and tile.elevation <= 0.5 and tile.elevation > -0.5
elseif tower_type == TOWER_TYPE.MOAT then
return not blocked and tile.elevation <= 0.5 and tile.elevation > -0.5
end
end end
function update_tower_redeye(tower, tower_index) function update_tower_redeye(tower, tower_index)
@ -94,7 +111,7 @@ function make_and_register_tower(hex, tower_type)
get_tower_update_function(tower_type) get_tower_update_function(tower_type)
) )
tower.range = 10
tower.range = 7
tower.last_shot_time = tower.TOB tower.last_shot_time = tower.TOB
tower.target_index = false tower.target_index = false

1
src/tower_spec.lua

@ -0,0 +1 @@

12
src/tower_spec.luaa

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

3
texture.lua

@ -4,9 +4,12 @@ function load_textures()
TEX_MARQUIS = am.texture2d("res/marquis.png") 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_TAB_ICON = am.texture2d("res/tab_icon.png")
TEX_ARROW = am.texture2d("res/arrow.png") TEX_ARROW = am.texture2d("res/arrow.png")
TEX_RADAR1 = am.texture2d("res/radar.png")
TEX_WALL_CLOSED = am.texture2d("res/wall_closed.png") TEX_WALL_CLOSED = am.texture2d("res/wall_closed.png")
TEX_MOAT1 = am.texture2d("res/moat1.png") TEX_MOAT1 = am.texture2d("res/moat1.png")
TEX_TOWER1 = am.texture2d("res/tower1.png") TEX_TOWER1 = am.texture2d("res/tower1.png")

Loading…
Cancel
Save