/apps/demos/crawl: visuals and stuff
This commit is contained in:
parent
70fab28158
commit
66c525a0d4
BIN
apps/demos/crawl/data/assets/brick.png
(Stored with Git LFS)
Normal file
BIN
apps/demos/crawl/data/assets/brick.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
apps/demos/crawl/data/assets/pebbles.png
(Stored with Git LFS)
Normal file
BIN
apps/demos/crawl/data/assets/pebbles.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -11,16 +11,21 @@
|
||||
|
||||
@classes
|
||||
-- Defines classes under symbols, which could have properties attached.
|
||||
# wall
|
||||
. floor
|
||||
# stone_wall
|
||||
wall_texture : /assets/brick.png
|
||||
. stone_floor
|
||||
tile_texture : /assets/pebbles.png
|
||||
@ player_spawn
|
||||
unique :
|
||||
face : south
|
||||
hold : torch
|
||||
tile_texture : /assets/pebbles.png
|
||||
X door
|
||||
open_on : sg_torch0
|
||||
/ torch
|
||||
emit : sg_torch0
|
||||
open_on_signal : sg_torch0
|
||||
tile_texture : /assets/pebbles.png
|
||||
/ lever
|
||||
on_interact_emit : sg_torch0
|
||||
tile_texture : /assets/pebbles.png
|
||||
|
||||
@meta
|
||||
-- Arbitrary sections could be defined with value pairs.
|
||||
|
@ -1,98 +1,64 @@
|
||||
require("string")
|
||||
require("level")
|
||||
require("render")
|
||||
|
||||
function load_level(file)
|
||||
local f = file_read { file = file }
|
||||
|
||||
local result = {
|
||||
classes = {
|
||||
void = { },
|
||||
},
|
||||
glossary = {
|
||||
[" "] = "void",
|
||||
},
|
||||
grid = {},
|
||||
map = {},
|
||||
size = { x = 0, y = 0 },
|
||||
}
|
||||
|
||||
-- iterate over lines
|
||||
local section, subsection = "none", "none"
|
||||
local from = 1
|
||||
local start, limit = string.find(f, "\n", from)
|
||||
while start do
|
||||
local line = string.sub(f, from, start - 1)
|
||||
-- skip over
|
||||
if #line == 0 or line:find("^%-%-%s*") then
|
||||
goto skip
|
||||
-- start new section
|
||||
elseif line:find("^@%g+") then
|
||||
section = line:sub(2); subsection = "none"
|
||||
-- decode map one line at a time
|
||||
elseif section == "map" then
|
||||
local l = #result.map + 1
|
||||
if result.size.x < #line then
|
||||
result.size.x = #line
|
||||
end
|
||||
result.map[l] = {}
|
||||
for i = 1, #line do
|
||||
result.map[l][i] = line:sub(i,i)
|
||||
end
|
||||
-- templates to expand
|
||||
elseif section == "classes" then
|
||||
-- properties
|
||||
if line:find("^ %g+") then
|
||||
local _, _, property, value = line:find("^ (%g+)%s?:%s?(.*)")
|
||||
result.classes[subsection][property] = value
|
||||
goto skip
|
||||
end
|
||||
local symbol, classname = line:sub(1,1), line:sub(3)
|
||||
result.classes[classname] = {
|
||||
symbol = symbol,
|
||||
}
|
||||
result.glossary[symbol] = classname
|
||||
subsection = classname
|
||||
elseif section ~= "none" then
|
||||
local _, _, property, value = line:find("^(%g+)%s?:%s?(.*)")
|
||||
if result[section] == nil then
|
||||
result[section] = {}
|
||||
end
|
||||
result[section][property] = value
|
||||
end
|
||||
::skip::
|
||||
from = limit + 1
|
||||
start, limit = string.find(f, "\n", from)
|
||||
end
|
||||
-- post process
|
||||
for y = 1, #result.map do
|
||||
result.grid[y] = {}
|
||||
for x = 1, result.size.x do
|
||||
-- past defined for line
|
||||
local symbol
|
||||
if x > #result.map[y] then symbol = " "
|
||||
else symbol = result.map[y][x]
|
||||
end
|
||||
local class = result.classes[result.glossary[symbol]]
|
||||
if class["unique"] ~= nil then
|
||||
class.position = { x = x, y = y }
|
||||
end
|
||||
result.grid[y][x] = class
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
result.size.y = #result.map
|
||||
|
||||
print(result.meta.description)
|
||||
|
||||
return result
|
||||
function lerp(a, b, x)
|
||||
return a + ((b - a) * x)
|
||||
end
|
||||
|
||||
function qlerp(a, b, x)
|
||||
return lerp(a, b, x * x)
|
||||
end
|
||||
|
||||
function game_tick()
|
||||
if ctx.udata == nil then
|
||||
ctx.udata = {
|
||||
level = load_level("levels/00.lvl")
|
||||
}
|
||||
log_vec2 { value = ctx.udata.level.classes.player_spawn.position }
|
||||
ctx.udata.player = {
|
||||
position = ctx.udata.level.classes.player_spawn.position,
|
||||
position_lerp = ctx.udata.level.classes.player_spawn.position,
|
||||
direction = { x = 1, y = 0, z = 0 },
|
||||
direction_lerp = { x = 1, y = 0, z = 0 },
|
||||
}
|
||||
end
|
||||
|
||||
input_action { control = "A", name = "turn_left" }
|
||||
input_action { control = "D", name = "turn_right" }
|
||||
input_action { control = "W", name = "walk_forward" }
|
||||
input_action { control = "S", name = "walk_backward" }
|
||||
|
||||
if input_action_just_released { name = "turn_left" } then
|
||||
ctx.udata.player.direction = { x = ctx.udata.player.direction.z, y = ctx.udata.player.direction.y, z = -ctx.udata.player.direction.x }
|
||||
end
|
||||
|
||||
if input_action_just_released { name = "turn_right" } then
|
||||
ctx.udata.player.direction = { x = -ctx.udata.player.direction.z, y = ctx.udata.player.direction.y, z = ctx.udata.player.direction.x }
|
||||
end
|
||||
|
||||
local direction = { x = 0, z = 0 }
|
||||
if input_action_just_released { name = "walk_forward" } then
|
||||
direction = { x = direction.x + ctx.udata.player.direction.z, z = direction.z + ctx.udata.player.direction.x }
|
||||
end
|
||||
if input_action_just_released { name = "walk_backward" } then
|
||||
direction = { x = direction.x - ctx.udata.player.direction.z, z = direction.z - ctx.udata.player.direction.x }
|
||||
end
|
||||
|
||||
ctx.udata.player.position = { x = ctx.udata.player.position.x + direction.x, y = ctx.udata.player.position.y + direction.z }
|
||||
|
||||
ctx.udata.player.position_lerp.x = qlerp(ctx.udata.player.position_lerp.x, ctx.udata.player.position.x, ctx.frame_duration * 30)
|
||||
ctx.udata.player.position_lerp.y = qlerp(ctx.udata.player.position_lerp.y, ctx.udata.player.position.y, ctx.frame_duration * 30)
|
||||
ctx.udata.player.direction_lerp.x = qlerp(ctx.udata.player.direction_lerp.x, ctx.udata.player.direction.x, ctx.frame_duration * 40)
|
||||
ctx.udata.player.direction_lerp.z = qlerp(ctx.udata.player.direction_lerp.z, ctx.udata.player.direction.z, ctx.frame_duration * 40)
|
||||
|
||||
draw_camera {
|
||||
position = {
|
||||
x = ctx.udata.player.position_lerp.y * 2 + 1,
|
||||
y = 1,
|
||||
z = ctx.udata.player.position_lerp.x * 2 + 1,
|
||||
},
|
||||
direction = ctx.udata.player.direction_lerp,
|
||||
}
|
||||
|
||||
render_dungeon(ctx.udata.level)
|
||||
end
|
||||
|
87
apps/demos/crawl/data/scripts/level.lua
Normal file
87
apps/demos/crawl/data/scripts/level.lua
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
function load_level(file)
|
||||
local f = file_read { file = file }
|
||||
|
||||
local result = {
|
||||
classes = {
|
||||
void = { },
|
||||
},
|
||||
glossary = {
|
||||
[" "] = "void",
|
||||
},
|
||||
grid = {},
|
||||
map = {},
|
||||
size = { x = 0, y = 0 },
|
||||
}
|
||||
|
||||
-- iterate over lines
|
||||
local section, subsection = "none", "none"
|
||||
local from = 1
|
||||
local start, limit = string.find(f, "\n", from)
|
||||
while start do
|
||||
local line = string.sub(f, from, start - 1)
|
||||
-- skip over
|
||||
if #line == 0 or line:find("^%-%-%s*") then
|
||||
goto skip
|
||||
-- start new section
|
||||
elseif line:find("^@%g+") then
|
||||
section = line:sub(2); subsection = "none"
|
||||
-- decode map one line at a time
|
||||
elseif section == "map" then
|
||||
local l = #result.map + 1
|
||||
if result.size.x < #line then
|
||||
result.size.x = #line
|
||||
end
|
||||
result.map[l] = {}
|
||||
for i = 1, #line do
|
||||
result.map[l][i] = line:sub(i,i)
|
||||
end
|
||||
-- templates to expand
|
||||
elseif section == "classes" then
|
||||
-- properties
|
||||
if line:find("^ %g+") then
|
||||
local _, _, property, value = line:find("^ (%g+)%s?:%s?(.*)")
|
||||
result.classes[subsection][property] = value
|
||||
goto skip
|
||||
end
|
||||
local symbol, classname = line:sub(1,1), line:sub(3)
|
||||
result.classes[classname] = {
|
||||
symbol = symbol,
|
||||
}
|
||||
result.glossary[symbol] = classname
|
||||
subsection = classname
|
||||
elseif section ~= "none" then
|
||||
local _, _, property, value = line:find("^(%g+)%s?:%s?(.*)")
|
||||
if result[section] == nil then
|
||||
result[section] = {}
|
||||
end
|
||||
result[section][property] = value
|
||||
end
|
||||
::skip::
|
||||
from = limit + 1
|
||||
start, limit = string.find(f, "\n", from)
|
||||
end
|
||||
-- post process
|
||||
for y = 1, #result.map do
|
||||
result.grid[y] = {}
|
||||
for x = 1, result.size.x do
|
||||
-- past defined for line
|
||||
local symbol
|
||||
if x > #result.map[y] then symbol = " "
|
||||
else symbol = result.map[y][x]
|
||||
end
|
||||
local class = result.classes[result.glossary[symbol]]
|
||||
if class["unique"] ~= nil then
|
||||
class.position = { x = x, y = y }
|
||||
end
|
||||
result.grid[y][x] = class
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
result.size.y = #result.map
|
||||
|
||||
print(result.meta.description)
|
||||
|
||||
return result
|
||||
end
|
59
apps/demos/crawl/data/scripts/render.lua
Normal file
59
apps/demos/crawl/data/scripts/render.lua
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
function render_dungeon(dungeon)
|
||||
for y = 1, dungeon.size.y do
|
||||
for x = 1, dungeon.size.x do
|
||||
if dungeon.grid[y][x].wall_texture ~= nil then
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].wall_texture,
|
||||
v3 = { x = y * 2, y = 2, z = x * 2 },
|
||||
v2 = { x = y * 2, y = 0, z = x * 2 },
|
||||
v1 = { x = y * 2 + 2, y = 0, z = x * 2 },
|
||||
v0 = { x = y * 2 + 2, y = 2, z = x * 2 },
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].wall_texture,
|
||||
v3 = { x = y * 2 + 2, y = 2, z = x * 2 },
|
||||
v2 = { x = y * 2 + 2, y = 0, z = x * 2 },
|
||||
v1 = { x = y * 2 + 2, y = 0, z = x * 2 + 2 },
|
||||
v0 = { x = y * 2 + 2, y = 2, z = x * 2 + 2 },
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].wall_texture,
|
||||
v3 = { x = y * 2 + 2, y = 2, z = x * 2 + 2 },
|
||||
v2 = { x = y * 2 + 2, y = 0, z = x * 2 + 2 },
|
||||
v1 = { x = y * 2, y = 0, z = x * 2 + 2 },
|
||||
v0 = { x = y * 2, y = 2, z = x * 2 + 2 },
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].wall_texture,
|
||||
v3 = { x = y * 2, y = 2, z = x * 2 + 2 },
|
||||
v2 = { x = y * 2, y = 0, z = x * 2 + 2 },
|
||||
v1 = { x = y * 2, y = 0, z = x * 2 },
|
||||
v0 = { x = y * 2, y = 2, z = x * 2 },
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
|
||||
elseif dungeon.grid[y][x].tile_texture ~= nil then
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].tile_texture,
|
||||
v0 = { x = y * 2 + 2, y = 0, z = x * 2 },
|
||||
v1 = { x = y * 2, y = 0, z = x * 2 },
|
||||
v2 = { x = y * 2, y = 0, z = x * 2 + 2 },
|
||||
v3 = { x = y * 2 + 2, y = 0, z = x * 2 + 2},
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
draw_quad {
|
||||
texture = dungeon.grid[y][x].tile_texture,
|
||||
v3 = { x = y * 2 + 2, y = 2, z = x * 2 },
|
||||
v2 = { x = y * 2, y = 2, z = x * 2 },
|
||||
v1 = { x = y * 2, y = 2, z = x * 2 + 2 },
|
||||
v0 = { x = y * 2 + 2, y = 2, z = x * 2 + 2},
|
||||
texture_region = { w = 128, h = 128 },
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user