Browse Source

farms

master
Nicholas Hayashi 3 years ago
parent
commit
e8f2557a9e
  1. 2
      lib/texture.lua
  2. BIN
      res/img/farm2.jpeg
  3. BIN
      res/img/farm2.png
  4. 11
      src/entity.lua
  5. 4
      src/game.lua
  6. 120
      src/grid.lua
  7. 39
      src/tower.lua

2
lib/texture.lua

@ -61,6 +61,8 @@ TEXTURES = {
TOWER_RADAR_ICON = load_texture("tower_radar_icon.png"),
TOWER_LIGHTHOUSE = load_texture("tower_lighthouse.png"),
TOWER_LIGHTHOUSE_ICON = load_texture("tower_lighthouse_icon.png"),
TOWER_FARM = load_texture("farm2.png"),
TOWER_FARM_ICON = load_texture("farm2.png"),
-- mob stuff
MOB_BEEPER = load_texture("mob_beeper.png"),

BIN
res/img/farm2.jpeg

After

Width: 256  |  Height: 256  |  Size: 93 KiB

BIN
res/img/farm2.png

After

Width: 256  |  Height: 256  |  Size: 192 KiB

11
src/entity.lua

@ -8,11 +8,16 @@ entity structure:
update - function - runs every frame with itself and its index in some array as an argument
node - node - scene graph node - should be initialized by caller after, though all entities have a node
z - number - z-index of the scene node, what layer should this node be rendered at?
we currently reserve z index 0 for just the 'floor', no towers or mobs or anything.
most things will set this to 1 (or leave it unset, 1 is the default)
we might use index -1 for underwater shit at some point
type - enum - sub type
props - table - table of properties specific to this entity subtype
}
--]]
function make_basic_entity(hex, update_f, position)
function make_basic_entity(hex, update_f, position, z)
local entity = {}
entity.TOB = game_state.time
@ -30,6 +35,7 @@ function make_basic_entity(hex, update_f, position)
end
entity.update = update_f
entity.z = z or 1
entity.props = {}
return entity
@ -37,7 +43,8 @@ end
function register_entity(t, entity)
table.insert(t, entity)
game_state.world:append(entity.node)
game_state.world(world_layer_tag(entity.z)):append(entity.node)
end
-- |t| is the source table, probably game_state.mobs, game_state.towers, or game_state.projectiles

4
src/game.lua

@ -67,6 +67,7 @@ local game_scene_menu_options = {
local function get_initial_game_state(seed)
local STARTING_MONEY = 75
--local STARTING_MONEY = 10000
local map = random_map(seed)
local world = make_hex_grid_scene(map, true)
@ -122,7 +123,8 @@ local function get_top_right_display_text(hex, evenq, centered_evenq, display_ty
str = table.tostring(hex_map_get(game_state.map, hex))
elseif display_type == TRDTS.MOUSE then
str = win:mouse_position()
local mouse = win:mouse_position()
str = mouse.x .. "," .. mouse.y .. " (mouse)"
end
return str
end

120
src/grid.lua

@ -188,28 +188,49 @@ function map_elevation_to_color(elevation)
end
end
function make_hex_node(hex, tile, color)
if not color then
local evenq = hex_to_evenq(vec2(hex.x, hex.y))
do
local s60 = math.sin(math.rad(60))
local c60 = math.cos(math.rad(60))
local radius = HEX_SIZE
-- light shading on edge cells
local mask = vec4(0, 0, 0, math.max(((evenq.x - HEX_GRID_WIDTH/2) / HEX_GRID_WIDTH) ^ 2
, ((-evenq.y - HEX_GRID_HEIGHT/2) / HEX_GRID_HEIGHT) ^ 2))
-- adds a pair of quads constructed to quads via quads:add_quad that draws a hexagon
function make_hex_quads_node(quads, position, color, uvs)
local p = position or vec2(0)
color = map_elevation_to_color(tile.elevation) - mask
quads:add_quad{
vert = {
p.x - c60 * radius, p.y + s60 * radius,
p.x - radius, p.y,
p.x + radius, p.y,
p.x + c60 * radius, p.y + s60 * radius
},
uv = am.vec2_array{
vec2(0, 0),
vec2(0, 0.5),
vec2(1, 0.5),
vec2(1, 0)
},
color = color or vec4(1),
}
quads:add_quad{
vert = {
p.x - radius, p.y,
p.x - c60 * radius, p.y - s60 * radius,
p.x + c60 * radius, p.y - s60 * radius,
p.x + radius, p.y
},
uv = am.vec2_array{
vec2(0, 0.5),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0.5)
},
color = color or vec4(1),
}
end
return am.translate(hex_to_pixel(vec2(hex.x, hex.y), vec2(HEX_SIZE)))
^ am.circle(vec2(0), HEX_SIZE, color, 6)
end
function make_hex_grid_scene(map, do_generate_flow_field)
local world = am.group():tag"world"
local texture = TEXTURES.WHITE
local quads = am.quads(map.size * 2, {"vert", "vec2", "uv", "vec2", "color", "vec4"})
quads.usage = "static" -- see am.buffer documentation, hint to gpu
local prog = am.program([[
local HEX_VSHADER_PROGRAM = [[
precision highp float;
attribute vec2 uv;
@ -227,7 +248,8 @@ function make_hex_grid_scene(map, do_generate_flow_field)
v_color = color;
gl_Position = P * MV * vec4(vert, 0.0, 1.0);
}
]], [[
]]
local HEX_FSHADER_PROGRAM = [[
precision mediump float;
uniform sampler2D texture;
@ -238,58 +260,44 @@ function make_hex_grid_scene(map, do_generate_flow_field)
void main() {
gl_FragColor = texture2D(texture, v_uv) * v_color;
}
]])
]]
function make_hex_shader_program_node()
return am.program(HEX_VSHADER_PROGRAM, HEX_FSHADER_PROGRAM)
end
function world_layer_tag(i)
return string.format("layer-%d", i)
end
function make_hex_grid_scene(map, do_generate_flow_field)
local world = am.group():tag"world"
for i = 0, 10 do
world:append(am.group():tag(world_layer_tag(i)))
end
local floor = world(world_layer_tag(0))
local quads = am.quads(map.size * 2, {"vert", "vec2", "uv", "vec2", "color", "vec4"})
quads.usage = "static" -- see am.buffer documentation, hint to gpu
local prog = make_hex_shader_program_node()
local s60 = math.sin(math.rad(60))
local c60 = math.cos(math.rad(60))
for i,_ in pairs(map) do
for j,tile in pairs(map[i]) do
local v = vec2(i, j)
local p = hex_to_pixel(v)
local d = math.distance(p, vec2(0)) -- distance to center
local d = math.distance(p, hex_to_pixel(HEX_GRID_CENTER)) -- distance to center
-- light shading on edge cells, scaled by distance to center
local mask = vec4(0, 0, 0, 1/d)
local mask = vec4(d/(HEX_GRID_PIXEL_WIDTH * 6))
local color = map_elevation_to_color(tile.elevation) - mask
local radius = HEX_SIZE
quads:add_quad{
vert = {
p.x - c60 * radius, p.y + s60 * radius,
p.x - radius, p.y,
p.x + radius, p.y,
p.x + c60 * radius, p.y + s60 * radius
},
uv = am.vec2_array{
vec2(0, 0),
vec2(1, 0),
vec2(1, 1),
vec2(0, 1)
},
color = color,
}
quads:add_quad{
vert = {
p.x - radius, p.y,
p.x - c60 * radius, p.y - s60 * radius,
p.x + c60 * radius, p.y - s60 * radius,
p.x + radius, p.y
},
uv = am.vec2_array{
vec2(0, 0),
vec2(1, 0),
vec2(1, 1),
vec2(0, 1)
},
color = color,
}
make_hex_quads_node(quads, p, color)
end
end
world:append(am.blend("alpha") ^ am.use_program(prog) ^ am.bind{ texture = texture } ^ quads)
local texture = TEXTURES.WHITE
floor:append((am.blend("alpha") ^ am.use_program(prog) ^ am.bind{ texture = texture } ^ quads))
-- add the magenta diamond that represents 'home'
world:append(
floor:append(
am.translate(hex_to_pixel(HEX_GRID_CENTER, vec2(HEX_SIZE)))
^ pack_texture_into_sprite(TEXTURES.GEM1, HEX_SIZE, HEX_SIZE*1.1)
)

39
src/tower.lua

@ -84,13 +84,16 @@ function init_tower_specs()
local lines = am.rotate(math.rad(-30)) ^ am.group()
for i,n in pairs(hex_neighbours(hex)) do
local no_towers_adjacent = true
local no_walls_adjacent = true
for _,t in pairs(towers_on_hex(n)) do
no_towers_adjacent = false
if t.type == TOWER_TYPE.WALL then
no_walls_adjacent = false
break
end
end
if no_towers_adjacent then
if no_walls_adjacent then
local p1 = hex_corner_offset(vec2(0), i)
local j = i == 6 and 1 or i + 1
local p2 = hex_corner_offset(vec2(0), j)
@ -112,6 +115,7 @@ function init_tower_specs()
texture = TEXTURES.TOWER_GATTLER,
icon_texture = TEXTURES.TOWER_GATTLER_ICON,
cost = 20,
height = 2,
weapons = {
{
projectile_type = PROJECTILE_TYPE.BULLET,
@ -161,6 +165,7 @@ function init_tower_specs()
texture = TEXTURES.TOWER_HOWITZER,
icon_texture = TEXTURES.TOWER_HOWITZER_ICON,
cost = 50,
height = 2,
weapons = {
{
projectile_type = PROJECTILE_TYPE.SHELL,
@ -242,6 +247,7 @@ function init_tower_specs()
texture = TEXTURES.TOWER_REDEYE,
icon_texture = TEXTURES.TOWER_REDEYE_ICON,
cost = 75,
height = 2,
weapons = {
{
projectile_type = PROJECTILE_TYPE.LASER,
@ -299,6 +305,7 @@ function init_tower_specs()
cost = 150,
range = 7,
fire_rate = 1,
height = 2,
make_node_f = function(self)
return am.group(
make_tower_sprite(self),
@ -362,6 +369,27 @@ function init_tower_specs()
end
end
end
},
{
id = "FARM",
name = "Farm",
placement_rules_text = "Place on Ground",
short_description = "Increases income gained over time. Mobs can trample farms, reducing their income (never completely nullifying it).",
texture = TEXTURES.TOWER_FARM,
icon_texture = TEXTURES.TOWER_FARM_ICON,
cost = 50,
size = 2,
height = 0,
make_node_f = function(self)
local quads = am.quads(2*7, {"vert", "vec2", "uv", "vec2", "color", "vec4"})
local map = hex_spiral_map(vec2(0), 1)
for _,h in pairs(map) do
make_hex_quads_node(quads, hex_to_pixel(h))
end
return am.blend("alpha") ^ am.use_program(make_hex_shader_program_node()) ^ am.bind{ texture = TEXTURES.TOWER_FARM } ^ quads
end
}
}
@ -516,6 +544,8 @@ function tower_type_is_buildable_on(hex, tile, tower_type)
local tower_spec = get_tower_spec(tower_type)
for _,h in pairs(hex_spiral_map(hex, get_tower_size(tower_type) - 1)) do
if h == HEX_GRID_CENTER then return false end
table.merge(blocking_towers, towers_on_hex(h))
table.merge(blocking_mobs, mobs_on_hex(h))
@ -551,7 +581,7 @@ function make_and_register_tower(hex, tower_type)
table.merge(tower, spec)
tower.type = tower_type
tower.node = am.translate(tower.position) ^ tower.make_node_f(tower, hex, true)
tower.node = am.translate(tower.position) ^ tower.make_node_f(tower, hex)
-- initialize each weapons' last shot time to the negation of the fire rate -
-- this lets the tower fire immediately upon being placed
@ -577,7 +607,6 @@ function build_tower(hex, tower_type)
-- check for that now
for _,t in pairs(game_state.towers) do
if t ~= tower and t.type == TOWER_TYPE.WALL then
log('replacin')
t.node:replace("group", t.make_node_f(t, t.hex))
end
end

Loading…
Cancel
Save