Nicholas Hayashi
4 years ago
12 changed files with 314 additions and 202 deletions
-
BINres/mob2_1.png
-
12src/color.lua
-
64src/entity.lua
-
56src/grid.lua
-
63src/hexyz.lua
-
57src/main.lua
-
141src/mob.lua
-
33src/projectile.lua
-
5src/scratch
-
2src/sound.lua
-
3src/texture.lua
-
80src/tower.lua
After Width: 40 | Height: 40 | Size: 558 B |
@ -0,0 +1,64 @@ |
|||
|
|||
ENTITY_TYPE = { |
|||
ENTITY = 0, |
|||
MOB = 1, |
|||
TOWER = 2, |
|||
PROJECTILE = 3 |
|||
} |
|||
|
|||
ENTITIES = {} |
|||
-- entity structure: |
|||
-- { |
|||
-- TOB - number - time of birth, const |
|||
-- |
|||
-- hex - vec2 - current occupied hex, if any |
|||
-- position - vec2 - current pixel position of it's translate (forced parent) node |
|||
-- update - function - runs every frame with itself and its index as an argument |
|||
-- node - node - scene graph node |
|||
-- } |
|||
-- |
|||
-- mob(entity) structure: |
|||
-- { |
|||
-- path - 2d table - map of hexes to other hexes, forms a path |
|||
-- speed - number - multiplier on distance travelled per frame, up to the update function to use correctly |
|||
-- } |
|||
-- |
|||
-- tower(entity) structure: |
|||
-- { |
|||
-- -- @NOTE these should probably be wrapped in a 'weapon' struct or something, so towers can have multiple weapons |
|||
-- range - number - distance it can shoot |
|||
-- last_shot_time - number - timestamp (seconds) of last time it shot |
|||
-- target_index - number - index of entity it is currently shooting |
|||
-- } |
|||
-- |
|||
-- bullet/projectile structure |
|||
-- { |
|||
-- } |
|||
-- |
|||
function make_and_register_entity(type_, hex, node, update) |
|||
local entity = {} |
|||
|
|||
entity.type = type_ |
|||
entity.TOB = TIME |
|||
entity.hex = hex |
|||
entity.position = hex_to_pixel(hex) |
|||
entity.update = update or function() log("unimplemented update function!") end |
|||
entity.node = am.translate(entity.position) ^ node |
|||
|
|||
table.insert(ENTITIES, entity) |
|||
WIN.scene"world":append(entity.node) |
|||
return entity |
|||
end |
|||
|
|||
function delete_entity(index) |
|||
WIN.scene"world":remove(ENTITIES[index].node) |
|||
ENTITIES[index] = nil |
|||
end |
|||
|
|||
function do_entity_updates() |
|||
for index,entity in pairs(ENTITIES) do |
|||
entity.update(entity, index) |
|||
end |
|||
end |
|||
|
|||
|
@ -0,0 +1,33 @@ |
|||
|
|||
|
|||
|
|||
function make_and_register_projectile(hex, vector, velocity) |
|||
local projectile = make_and_register_entity( |
|||
-- type |
|||
ENTITY_TYPE.PROJECTILE, |
|||
|
|||
hex, |
|||
|
|||
-- node |
|||
am.line(vector, vector * 4, 2, COLORS.CLARET), |
|||
|
|||
function(_projectile, _projectile_index) |
|||
_projectile.position = _projectile.position + vector * velocity |
|||
_projectile.node.position2d = _projectile.position |
|||
_projectile.hex = pixel_to_hex(_projectile.position) |
|||
|
|||
local mob_index,mob = mob_on_hex(_projectile.hex) |
|||
if mob and (math.distance(mob.position, _projectile.position) > _projectile.hitbox_radius) then |
|||
do_hit_mob(mob, _projectile.damage, mob_index) |
|||
delete_entity(_projectile_index) |
|||
WIN.scene"world":action(am.play(am.sfxr_synth(SOUNDS.HIT1))) |
|||
end |
|||
end |
|||
) |
|||
|
|||
projectile.vector = vector |
|||
projectile.velocity = velocity |
|||
projectile.damage = 5 |
|||
projectile.hitbox_radius = 10 |
|||
end |
|||
|
@ -0,0 +1,5 @@ |
|||
|
|||
|
|||
x = y - floor(z/2) |
|||
|
|||
j + floor(z/2) = j2 |
@ -1,43 +1,59 @@ |
|||
|
|||
local TOWERS = {} |
|||
--[[ |
|||
tower structure: |
|||
{ |
|||
TOB - float -- time stamp in seconds of when the tower was spawned |
|||
hex - vec2 -- hexagon the tower is on |
|||
position - vec2 -- true pixel coordinates |
|||
node - node -- the root graph node for this tower |
|||
update - function -- function that gets called every frame with itself as an argument |
|||
} |
|||
]] |
|||
|
|||
function is_buildable(hex, tile, tower) |
|||
local blocked = mob_on_hex(hex) |
|||
return not blocked and is_passable(tile) |
|||
end |
|||
|
|||
function make_tower(hex) |
|||
local tower = {} |
|||
|
|||
tower.TOB = TIME |
|||
tower.hex = hex |
|||
tower.position = hex_to_pixel(tower.hex) |
|||
tower.node = am.translate(tower.position) |
|||
^ pack_texture_into_sprite(TEX_TOWER1, 55, 55) |
|||
|
|||
tower.update = function(_tower) end |
|||
function make_and_register_tower(hex) |
|||
local tower = make_and_register_entity( |
|||
-- type |
|||
ENTITY_TYPE.TOWER, |
|||
|
|||
-- spawning hex |
|||
hex, |
|||
|
|||
-- node |
|||
pack_texture_into_sprite(TEX_TOWER2, 45, 34), |
|||
|
|||
-- update function |
|||
function(_tower, _tower_index) |
|||
if not _tower.target_index then |
|||
for index,entity in pairs(ENTITIES) do |
|||
if entity and entity.type == ENTITY_TYPE.MOB then |
|||
local d = math.distance(entity.hex, _tower.hex) |
|||
if d <= _tower.range then |
|||
_tower.target_index = index |
|||
break |
|||
end |
|||
end |
|||
end |
|||
else |
|||
if ENTITIES[_tower.target_index] == nil then |
|||
_tower.target_index = false |
|||
|
|||
elseif (TIME - _tower.last_shot_time) > 1 then |
|||
local entity = ENTITIES[_tower.target_index] |
|||
|
|||
make_and_register_projectile( |
|||
_tower.hex, |
|||
math.normalize(hex_to_pixel(entity.hex) - _tower.position), |
|||
5 |
|||
) |
|||
|
|||
_tower.last_shot_time = TIME |
|||
_tower.node:action(am.play(am.sfxr_synth(SOUNDS.EXPLOSION3))) |
|||
end |
|||
end |
|||
end |
|||
) |
|||
|
|||
tower.range = 10 |
|||
tower.last_shot_time = tower.TOB |
|||
tower.target_index = false |
|||
|
|||
-- make this cell impassable |
|||
--HEX_MAP.get(hex.x, hex.y).elevation = 2 |
|||
|
|||
WIN.scene"world":append(tower.node) |
|||
|
|||
return tower |
|||
end |
|||
|
|||
function do_tower_updates() |
|||
for i,tower in pairs(TOWERS) do |
|||
tower.update(tower, i) |
|||
end |
|||
HEX_MAP[hex.x][hex.y].elevation = 2 |
|||
check_for_broken_mob_pathing(hex) |
|||
end |
|||
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue