Browse Source

reorganize

master
Nicholas Hayashi 4 years ago
parent
commit
75f74b324a
  1. BIN
      res/mob1_1.png
  2. 26
      src/color.lua
  3. 17
      src/colors.lua
  4. 4
      src/grid.lua
  5. 58
      src/hexyz.lua
  6. 37
      src/main.lua
  7. 9
      src/math.lua
  8. 92
      src/mob.lua
  9. 14
      src/sound.lua
  10. 14
      src/table.lua
  11. 5
      src/texture.lua
  12. 10
      src/util.lua

BIN
res/mob1_1.png

After

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

26
src/color.lua

@ -0,0 +1,26 @@
COLORS = {
TRANSPARENT = vec4(0.4),
-- tones
WHITE = vec4(0.8, 0.8, 0.7, 1),
BLACK = vec4(0, 0, 0, 1),
TRUEBLACK = vec4(0, 0, 0, 1),
-- hues
BLUE_STONE = vec4(0.12, 0.3, 0.3, 1),
MYRTLE = vec4(0.10, 0.25, 0.10, 1),
BROWN_POD = vec4(0.25, 0.20, 0.10, 1),
BOTTLE_GREEN = vec4(0.15, 0.30, 0.20, 1),
MAGENTA = vec4(1, 0, 1, 1),
TEAL = vec4(16/255, 126/255, 124/244, 1),
YALE_BLUE = vec4(4/255, 75/255, 127/255, 1),
OLIVE = vec4(111/255, 124/254, 18/255, 1),
LIGHT_CYAN = vec4(224/255, 251/255, 252/255, 1),
PALE_SILVER = vec4(193/255, 178/255, 171/255, 1),
CLARET = vec4(139/255, 30/255, 63/255, 1),
BISTRO = vec4(73/255, 44/255, 29/255, 1),
DEEP_SPACE_SPARKLE = vec4(61/255, 90/255, 108/255, 1)
}

17
src/colors.lua

@ -1,17 +0,0 @@
COLORS = {
TRANSPARENT = vec4(0.4),
-- tones
WHITE = vec4(0.8, 0.8, 0.7, 1),
BLACK = vec4(0, 0, 0, 1),
TRUEBLACK = vec4(0, 0, 0, 1),
-- hues
BLUE_STONE = vec4(0.12, 0.3, 0.3, 1),
MYRTLE = vec4(0.10, 0.25, 0.10, 1),
BROWN_POD = vec4(0.25, 0.20, 0.10, 1),
BOTTLE_GREEN = vec4(0.15, 0.30, 0.20, 1),
MAGENTA = vec4(1, 0, 1, 1)
}

4
src/grid.lua

@ -1,6 +1,5 @@
require "colors"
require "gui"
require "hexyz"
HEX_SIZE = 20 HEX_SIZE = 20
HEX_GRID_WIDTH = 65 -- 65 HEX_GRID_WIDTH = 65 -- 65
@ -79,6 +78,7 @@ function random_map(seed, do_seed_rng)
-- the center of the map in some radius is always considered 'passable' terrain and is home base -- the center of the map in some radius is always considered 'passable' terrain and is home base
-- terraform this area to ensure it's passable -- terraform this area to ensure it's passable
-- @NOTE no idea why the y-coord doesn't need to be transformed -- @NOTE no idea why the y-coord doesn't need to be transformed
-- @TODO @FIXME also terraform the edges of the map to be passable - it is theoretically possible to get maps where mobs can be stuck from the very beginning
local home = spiral_map(HEX_GRID_CENTER, 3) local home = spiral_map(HEX_GRID_CENTER, 3)
for _,hex in pairs(home) do for _,hex in pairs(home) do
map[hex.x][hex.y].elevation = 0 map[hex.x][hex.y].elevation = 0

58
src/hexyz.lua

@ -170,12 +170,44 @@ function hex_corners(hex, size, orientation)
return corners return corners
end end
-- @TODO test
function hex_to_oddr(hex)
local z = -hex.x - hex.y
return vec2(hex.x + (z - (z % 2)) / 2)
end
-- @TODO test
function oddr_to_hex(oddr)
return vec2(hex.x - (hex.y - (hex.y % 2)) / 2, -hex.x - hex.y)
end
-- @TODO test
function hex_to_evenr(hex)
local z = -hex.x - hex.y
return vec2(hex.x + (z + (z % 2)) / 2, z)
end
-- @TODO test
function evenr_to_hex(evenr)
return vec2(hex.x - (hex.y + (hex.y % 2)) / 2, -hex.x - hex.y)
end
-- @TODO test
function hex_to_oddq(hex)
return vec2(hex.x, -hex.x - hex.y + (hex.x - (hex.x % 2)) / 2)
end
-- @TODO test
function oddq_to_hex(oddq)
return vec2(hex.x, -hex.x - (hex.y - (hex.x - (hex.y % 2)) / 2))
end
function hex_to_evenq(hex) function hex_to_evenq(hex)
return vec2(hex.x, (-hex.x - hex.y) + (hex.x + (hex.x % 2)) / 2) return vec2(hex.x, (-hex.x - hex.y) + (hex.x + (hex.x % 2)) / 2)
end end
function evenq_to_hex(off)
return vec2(off.x, -off.x - (off.y - (off.x + (off.x % 2)) / 2))
function evenq_to_hex(evenq)
return vec2(evenq.x, -evenq.x - (evenq.y - (evenq.x + (evenq.x % 2)) / 2))
end end
--============================================================================ --============================================================================
@ -404,19 +436,15 @@ function Astar(map, start, goal, neighbour_f, heuristic_f, cost_f)
end end
for _,next_ in pairs(neighbour_f(current.hex)) do for _,next_ in pairs(neighbour_f(current.hex)) do
local entry = map.get(next_.x, next_.y)
if entry then
local new_cost = map_get(cost_so_far, current.hex.x, current.hex.y)
+ cost_f(entry)
local next_cost = map_get(cost_so_far, next_.x, next_.y)
if not next_cost or new_cost < next_cost then
map_set(cost_so_far, next_.x, next_.y, new_cost)
local priority = new_cost + heuristic_f(goal, next_)
table.insert(frontier, { hex = next_, priority = priority })
map_set(came_from, next_.x, next_.y, current)
end
local new_cost = map_get(cost_so_far, current.hex.x, current.hex.y)
+ cost_f(next_)
local next_cost = map_get(cost_so_far, next_.x, next_.y)
if not next_cost or new_cost < next_cost then
map_set(cost_so_far, next_.x, next_.y, new_cost)
local priority = new_cost + heuristic_f(goal, next_)
table.insert(frontier, { hex = next_, priority = priority })
map_set(came_from, next_.x, next_.y, current)
end end
end end
end end

37
src/main.lua

@ -3,34 +3,21 @@
math.randomseed(os.time()); math.random(); math.random(); math.random() math.randomseed(os.time()); math.random(); math.random(); math.random()
--============================================================================ --============================================================================
-- Imports -- Imports
require "hexyz"
require "color"
require "grid" require "grid"
require "mob" require "mob"
require "util"
require "math"
require "table"
--============================================================================ --============================================================================
-- Globals -- Globals
TIME = 0
win = am.window{ width = 1920, height = 1080 } win = am.window{ width = 1920, height = 1080 }
function mask()
return am.rect(win.left, win.bottom, win.right, win.top, COLORS.TRANSPARENT):tag"mask"
end
function get_menu_for_tile(x, y, tile)
local pos = hex_to_pixel(vec2(x, y)) + WORLDSPACE_COORDINATE_OFFSET
return am.translate(pos) ^ am.group{
am.rect(-50, -50, 50, 50, COLORS.TRANSPARENT),
make_button_widget(x .. y, pos, vec2(100, 37), "close")
}
end
function invoke_tile_menu(x, y, tile)
win.scene:append(get_menu_for_tile(x, y, tile))
end
function game_action(scene) function game_action(scene)
local time = am.current_time()
TIME = am.current_time()
local mouse = win:mouse_position() local mouse = win:mouse_position()
local hex = pixel_to_hex(mouse - WORLDSPACE_COORDINATE_OFFSET) local hex = pixel_to_hex(mouse - WORLDSPACE_COORDINATE_OFFSET)
@ -44,18 +31,12 @@ function game_action(scene)
if win:key_pressed"f1" then end if win:key_pressed"f1" then end
for wid,widget in pairs(get_widgets()) do
if widget.poll() then
log('we clicked button with id %s!', wid)
end
end
do_mob_updates() do_mob_updates()
do_mob_spawning() do_mob_spawning()
-- draw stuff -- draw stuff
win.scene"hex_cursor".center = hex_to_pixel(hex) + WORLDSPACE_COORDINATE_OFFSET win.scene"hex_cursor".center = hex_to_pixel(hex) + WORLDSPACE_COORDINATE_OFFSET
win.scene"score".text = string.format("SCORE: %.2f", time)
win.scene"score".text = string.format("SCORE: %.2f", TIME)
win.scene"coords".text = string.format("%d,%d", hex.x, hex.y) win.scene"coords".text = string.format("%d,%d", hex.x, hex.y)
end end
@ -79,7 +60,7 @@ function game_scene()
curtain, curtain,
hex_cursor, hex_cursor,
score, score,
coords,
coords
} }
scene:action(game_action) scene:action(game_action)
@ -88,6 +69,8 @@ function game_scene()
end end
function init() function init()
require "texture"
load_textures()
win.scene = am.scale(1) ^ game_scene() win.scene = am.scale(1) ^ game_scene()
end end

9
src/math.lua

@ -0,0 +1,9 @@
function math.wrapf(float, range)
return float - range * math.floor(float / range)
end
function math.lerpv2(v1, v2, t)
return v1 * t + v2 * (1 - t)
end

92
src/mob.lua

@ -1,5 +1,47 @@
MOBS = {} MOBS = {}
--[[
mob structure:
{
position - vec2 -- true pixel coordinates
TOB - float -- time stamp in seconds of when the mob when spawned
node - node -- the root graph node for this mob
hex - vec2 -- hexagon the mob is on top of
update - function -- the function that gets called every frame
}
]]
require "sound"
require "util"
MOB_UPDATES = {
BEEPER = function(mob, index)
mob.hex = pixel_to_hex(mob.position - WORLDSPACE_COORDINATE_OFFSET)
local frame_target = map_get(mob.path, mob.hex.x, mob.hex.y)
if frame_target then
mob.position = math.lerpv2(mob.position, hex_to_pixel(frame_target.hex) + WORLDSPACE_COORDINATE_OFFSET, 0.91)
mob.node.position2d = mob.position
-- can't find path, or dead
else
win.scene:action(am.play(am.sfxr_synth(SOUNDS.EXPLOSION1), false, math.random() + 0.5))
local i,v = table.find(MOBS, function(_mob) return _mob == mob end)
table.remove(MOBS, index)
win.scene:remove(mob.node)
end
-- passive animation
if math.random() < 0.01 then
mob.node"rotate":action(am.tween(0.3, { angle = mob.node"rotate".angle + math.pi*3 }))
else
mob.node"rotate".angle = math.wrapf(mob.node"rotate".angle + am.delta_time, math.pi*2)
end
end
}
-- check if a the tile at |hex| is passable by |mob| -- check if a the tile at |hex| is passable by |mob|
function can_pass_through(mob, hex) function can_pass_through(mob, hex)
@ -7,10 +49,7 @@ function can_pass_through(mob, hex)
return tile and tile.elevation < 0.5 and tile.elevation > -0.5 return tile and tile.elevation < 0.5 and tile.elevation > -0.5
end end
function get_movement_cost(mob, start_hex, goal_hex)
return 1
end
-- @FIXME there's a bug here where the position of the spawn hex is sometimes 1 closer to the center than we want
function get_spawn_hex(mob) function get_spawn_hex(mob)
local spawn_hex local spawn_hex
repeat repeat
@ -40,16 +79,15 @@ function get_spawn_hex(mob)
return spawn_hex return spawn_hex
end end
-- @NOTE spawn hex
--
function make_mob() function make_mob()
local mob = {} local mob = {}
local spawn_hex = get_spawn_hex(mob)
local spawn_position = hex_to_pixel(spawn_hex) + WORLDSPACE_COORDINATE_OFFSET
mob.position = spawn_position
mob.hex = spawn_hex
mob.path = Astar(HEX_MAP, HEX_GRID_CENTER, spawn_hex,
mob.TOB = TIME
mob.update = MOB_UPDATES.BEEPER
mob.hex = get_spawn_hex(mob)
mob.position = hex_to_pixel(mob.hex) + WORLDSPACE_COORDINATE_OFFSET
mob.path = Astar(HEX_MAP, HEX_GRID_CENTER, mob.hex,
-- neighbour function -- neighbour function
function(hex) function(hex)
@ -64,39 +102,31 @@ function make_mob()
end, end,
-- cost function -- cost function
function(map_entry)
return math.abs(map_entry.elevation)
function(hex)
return math.abs(HEX_MAP.get(hex.x, hex.y).elevation)
end end
) )
mob.sprite = am.circle(spawn_position, 18, COLORS.WHITE, 4)
win.scene:append(mob.sprite)
mob.node = am.translate(mob.position)
^ am.scale(2)
^ am.rotate(mob.TOB)
^ pack_texture_into_sprite(TEX_MOB1_1, 20, 20)
win.scene:append(mob.node)
return mob return mob
end end
local SPAWN_CHANCE = 25
local SPAWN_CHANCE = 50
function do_mob_spawning() function do_mob_spawning()
if win:key_pressed"space" then
--if math.random(SPAWN_CHANCE) == 1 then
if math.random(SPAWN_CHANCE) == 1 then
table.insert(MOBS, make_mob()) table.insert(MOBS, make_mob())
end end
end end
function do_mob_updates() function do_mob_updates()
--if win:key_pressed"a" then
for _,mob in pairs(MOBS) do
mob.hex = pixel_to_hex(mob.position - WORLDSPACE_COORDINATE_OFFSET)
local frame_target = map_get(mob.path, mob.hex.x, mob.hex.y)
if frame_target then
mob.position = lerp(mob.position, hex_to_pixel(frame_target.hex) + WORLDSPACE_COORDINATE_OFFSET, 0.9)
mob.sprite.center = mob.position
else
end
for i,mob in pairs(MOBS) do
mob.update(mob, i)
end end
--end
end end

14
src/sound.lua

@ -0,0 +1,14 @@
SOUNDS = {
EXPLOSION1 = 49179102, -- this slowed sounds metal as fuck
EXPLOSION2 = 19725402,
LASER1 = 79859301,
PUSH1 = 30455908,
BIRD1 = 50838307,
RANDOM1 = 85363309,
RANDOM2 = 15482409,
RANDOM3 = 58658009,
RANDOM4 = 89884209,
RANDOM5 = 36680709
}

14
src/table.lua

@ -0,0 +1,14 @@
function table.rchoice(t)
return t[math.floor(math.random() * #t) + 1]
end
function table.find(t, predicate)
for i,v in pairs(t) do
if predicate(v) then
return i,v
end
end
return nil
end

5
src/texture.lua

@ -0,0 +1,5 @@
function load_textures()
TEX_MOB1_1 = am.texture2d("../res/mob1_1.png")
end

10
src/util.lua

@ -1,6 +1,10 @@
function lerp(v1, v2, t)
return v1 * t + v2 * (1 - t)
function pack_texture_into_sprite(texture, width, height)
return am.sprite{
texture = texture,
s1 = 0, s2 = 1, t1 = 0, t2 = 1,
x1 = 0, x2 = width, width = width,
y1 = 0, y2 = height, height = height
}
end end
Loading…
Cancel
Save