diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/color.moon | 26 | ||||
| -rw-r--r-- | src/ecs.moon | 88 | ||||
| -rw-r--r-- | src/js_bridge.js | 70 | ||||
| -rw-r--r-- | src/log.moon | 66 | ||||
| -rw-r--r-- | src/main.lua | 29 | ||||
| -rw-r--r-- | src/net.moon | 148 | ||||
| -rw-r--r-- | src/net_test.moon | 64 | ||||
| m--------- | src/party/hardoncollider | 0 | ||||
| -rw-r--r-- | src/preload.lua | 71 | ||||
| -rw-r--r-- | src/shader_shim.moon | 20 | ||||
| -rw-r--r-- | src/shaders/stars.lua | 76 | ||||
| -rw-r--r-- | src/shaders/world.frag | 19 | ||||
| -rw-r--r-- | src/shaders/world.moon | 125 | ||||
| -rw-r--r-- | src/shaders/world.vert | 22 | ||||
| -rw-r--r-- | src/stars_test.moon | 25 | ||||
| -rw-r--r-- | src/state_machine.moon | 2 | ||||
| -rw-r--r-- | src/ui.moon | 127 | ||||
| -rw-r--r-- | src/ui/button.moon | 131 | ||||
| -rw-r--r-- | src/ui/joystick.moon | 98 | ||||
| -rw-r--r-- | src/ui/textbox.moon | 119 | ||||
| -rw-r--r-- | src/ui_test.moon | 7 | ||||
| -rw-r--r-- | src/util.lua | 84 | ||||
| -rw-r--r-- | src/window.moon | 10 | ||||
| -rw-r--r-- | src/world.moon | 23 | ||||
| -rw-r--r-- | src/world_test.moon | 15 |
25 files changed, 1446 insertions, 19 deletions
diff --git a/src/color.moon b/src/color.moon new file mode 100644 index 0000000..447ae32 --- /dev/null +++ b/src/color.moon @@ -0,0 +1,26 @@ + +color = + background: {100,113,136} + shadow: {62,81,84} + midground: {139,126,168} + foreground: {186,161,196} + highlight: {191,228,230} + outline: {44,54,52} + black: {34,40,37} + +am_color = {k, vec4(v[1]/255,v[2]/255,v[3]/255,1) for k,v in pairs(color)} + +am.ascii_color_map = { + b: am_color.background + m: am_color.midground + f: am_color.foreground + s: am_color.shadow + h: am_color.highlight + x: am_color.black + o: am_color.outline +} + +{ + color: color + am_color: am_color +} diff --git a/src/ecs.moon b/src/ecs.moon new file mode 100644 index 0000000..4fdecc9 --- /dev/null +++ b/src/ecs.moon @@ -0,0 +1,88 @@ + +entities = {} + +-- Bace component class of the ECS +class Component + depends: {} + new: (name, properties) => + @name = name + @properties = properties or {} + join: (e) => + @ + leave: (e) => + @ + +-- Base entity of our ECS +class Entity + id: 1 + new: (id, components) => -- [id], [components] + id_cur = #entities + while id == nil + id_cur += 1 + if entities[id_cur] == nil + id = id_cur + assert(entities[id] == nil, "Attempted to create entity with the same id as one that already exists: " .. tostring(id)) + entities[id] = @ + @id = id + -- Bookkeeping for O(1) access for componenets + @c_by_type = {} + + --Entity is responsible for the component -> entity link + @components = componenets or {} + for name, component in pairs(components) + component.entity = @ + @c_by_type[component.__class] = @c_by_type[component.__class] or {} + @c_by_type[component.__class][name] = component + component\join(@) + add: (cid, component) => + component.entity = @ + component\join(@) + if cid == nil + cid = #@components + while @components[cid] + cid += 1 + assert(@components[cid] == nil, "Already had a component with id" .. tostring(cid)) + @components[cid] = component + @ + remove: (cid) => + component = @components[cid] + component.entity = nil + component\leave(@) + component + get: (cid) => + @components[cid] + +class NetworkedComponent extends Component + pack: () => + assert(@entity, "Tried to pack on a NetworkedComponent without an Entity") + return am.to_json({ + id: @entity.id + data: @properties + time: am.current_time! + }) + +class PredictedComponent extends Component + new: (name, properties, netc_name, calculate) => + super(name, properties) + @netc_name = netc_name + @calculate = calculate + join: (entity) => + @net = entity[@netc_name] + forward: () => + for proeprty, calculation in pairs(@calculate) + @properties[property] = calculation(@) + +class GraphicsComponent extends Component + new: (name, properties) => + assert(properties.node , "Failed to find node for graphics component") + super(name, properties) + +{ + Component: Component + Entity: Entity + NetworkedComponent: NetworkedComponent + PredictedComponent: PredictedComponent + GraphicsComponent: GraphicsComponent +} + +} diff --git a/src/js_bridge.js b/src/js_bridge.js index 46065cb..0b5ba08 100644 --- a/src/js_bridge.js +++ b/src/js_bridge.js @@ -8,15 +8,28 @@ function genRanHex(size) { } window.PEER = { - event_queue: {}, + event_queue: [], peers: {}, - message_queue: {}, - create: function(name, options) { + message_queue: [], + connections: {}, + create: function(tbl) { + var name = tbl.name; + var options = tbl.options; + console.log("[JS] Creating peer " + name); var peer = new Peer(name, options); PEER.peers[name] = peer; }, - on: function(name, e, message) { + on: function(tbl) { + var name = tbl.name; + var e = tbl.e; + var message = tbl.message; + console.log("[JS] Setting hook for " + name + "," + e + "," + message); PEER.peers[name].on(e, function(data) { + console.log("[JS] Peer " + name + " received " + e); + if(e == "connection"){ + PEER.connections[[name,data.peer]] = data; + data = [name,data.peer]; // rewrite connections + } PEER.message_queue.push({"message":message, "data":{ "call": "on", "peer": name, @@ -25,7 +38,52 @@ window.PEER = { }}); }); }, - connect: function(name, id, options) { - PEER.peers[name].connect(id, options); + connect: function(tbl) { + var name = tbl.name; + var id = tbl.id; + console.log("[JS] connecting " + name + " to " + id); + var conn = PEER.peers[name].connect(id); + PEER.connections[[name,id]] = conn; + return [name,id]; + }, + disconnect: function(tbl) { + PEER.peers[tbl.name].disconnect(); + }, + reconnect: function(tbl){ + PEER.peers[tbl.name].reconnect(); + }, + destroy: function(tbl){ + PEER.peers[tbl.name].destroy(); + }, + send: function(tbl){ + var name = tbl.name; + var id = tbl.id; + var data = tbl.data; + console.log("[JS] " + name + " is sending " + data + " to " + id); + console.log(PEER.connections[[name,id]]); + console.log(data); + PEER.connections[[name,id]].send(data); + }, + close: function(tbl){ + var name = tbl.name; + var id = tbl.id; + PEER.connections[[name,id]].close(); + }, + conn_on: function(tbl){ + var name = tbl.name; + var id = tbl.id; + var e = tbl.e; + var message = tbl.message; + console.log("[JS] Setting hook for [" + name + "," + id + "] " + e + "," + message); + PEER.connections[[name,id]].on(e, function(c) { + console.log("[JS] connection between " + name + " and " + id + " received " + e); + PEER.message_queue.push({"message":message, "data":{ + "call": "on", + "peer": name, + "id": id, + "e": e, + "data": c + }}); + }); }, }; diff --git a/src/log.moon b/src/log.moon new file mode 100644 index 0000000..3c54dc2 --- /dev/null +++ b/src/log.moon @@ -0,0 +1,66 @@ +-- Singleton object to deal with log messages +class log + log: (message, tags, level) -> + tags = tags or {} + if not level + error("Level is required") + tag_rev = {tag,true for tag in *tags} + chunk = + level: level + time: os.clock! + message: message + tags: tag_rev + stream_pos = log.messages + 1 + log.stream[stream_pos] = chunk + for tag in *tags + log.by_tags[tag] = log.by_tags[tag] or {} + table.insert(log.by_tags[tag], stream_pos) + log.by_level[level] = log.by_level[level] or {} + table.insert(log.by_level[level], stream_pos) + log.messages += 1 + for observer in *log.observers + observer(chunk) + + reset: -> + log.stream = {} + log.messages = 0 + log.by_tags = {} + log.by_level = {} + log.observers = {} + + info: (message, tags) -> + log.log(message, tags, "info") + warn: (message, tags) -> + log.log(message, tags, "warn") + error: (message, tags) -> + log.log(message, tags, "error") + panic: (message, tags) -> + log.log(message, tags, "panic") + observe: (callback) -> + table.insert(log.observers, callback) + of_level: (level, callback) -> + if not log.by_level[level] + return + for message_idx in *log.by_level[level] + callback(log.stream[message_idx]) + of_tags: (tags, callback) -> + if type(tags) ~= "table" + tags = {tags} + first_tag = tags[1] + assert(type(first_tag) == "string", "tag was not a string, was a " .. type(first_tag)) + if not first_tag + error("Must pass a tag") + if not log.by_tags[first_tag] + return + for message_idx in *log.by_tags[first_tag] + message = log.stream[message_idx] + suitable = true + for tag in *tags + if not message.tags[tag] + suitable = false + break + if suitable + callback(message) + +log.reset() +log diff --git a/src/main.lua b/src/main.lua index 8c8461a..55b7ef5 100644 --- a/src/main.lua +++ b/src/main.lua @@ -1,15 +1,18 @@ +require("preload") +local win = require("window") +--local stars = require("shaders.stars") +--win.scene:append(stars) +--world_shader = require("shaders.world") +--print("World shader:",world_shader) +--win.scene:append(world_shader.node) +local ui = require("ui") +win.scene:append(ui.node) +--require("world_test") +--require("net_test") +require("ui_test") -print("Hello, world!") - -am.eval_js("console.log('Hello, js!')") - -local win = am.window{ - title = "ggj25", - width = 1280, - height = 720, - clear_color = vec4(0.8, 0.8, 0.3, 1) -} -print("about to pcall") -am.eval_js(require("js_bridge")) +require("log").observe(function(chunk) + print(table.concat({"[",chunk.level:upper(),"]",os.date()," > ",chunk.message})) +end) +--am.eval_js(require("js_bridge")) --local a,b = pcall(am.eval_js, require("js_bridge")) -print("done with pcall", a,b) diff --git a/src/net.moon b/src/net.moon new file mode 100644 index 0000000..b22d6f2 --- /dev/null +++ b/src/net.moon @@ -0,0 +1,148 @@ +-- Handles the bridge to javascript to do peer-to-peer connections + + +log = require("log") +net = {} + +net.initalize = () -> + am.eval_js(require("js_bridge")) + +net.call = (method, args) -> + print("About to eval") + result = am.eval_js("window.PEER." .. method .. "(" .. am.to_json(args) .. ")") + print("Done evaling") + result + +net.pull = () -> + messages = am.eval_js("window.PEER.message_queue") + am.eval_js("window.PEER.message_queue = []") + messages + +callbacks = {} +peers = {} +connections = {} + +class Connection + new: (source, dest) => + @source = source + @dest = dest + on: (event, callback) => + newid = #callbacks + 1 + callbacks[newid] = callback + net.call("conn_on", {name: @source, id: @dest, e: event, message: newid}) + send: (msgname, msg) => + net.validate(msgname, msg) + net.call("send",{name: @source, id: @dest, data: msg}) + +class Peer + new: (id) => + net.call("create",{name: id}) + if id + @id = id + peers[id] = @ + on: (event, callback) => + newid = #callbacks + 1 + callbacks[newid] = callback + net.call("on",{name: @id, message:newid, e: event}) + + connect: (id, options) => + conn = net.call("connect", {name: @id, id: id}) + log.info("Got connection: " .. tostring(conn), {"net"}) + Connection(conn[1],conn[2]) + + +net.Peer = Peer + +-- A fake peer for testing +fakepeers = {} +fakeconnections = {} +fakecallbacks = {} +channel = require("channel") + +class FakePeer + new: (id) => + if id + @id = id + fakepeers[id] = @ + on: (event, callback) => + newid = #fakecallbacks + 1 + fakecallbacks[newid] = callback + + connect: (id, options) => + conn = channel.FaultyChannel({ + avg_latency: 200 + latency_std: 100 + loss: 0.1 + }) + conn + + +messages = {} +formatcache = {} +message_callbacks = {} +net.register_message = (name, format) -> + assert(type(format) == "table", "Format must be a table") + format.required = format.required or {} + format.optional = format.optional or {} + assert(next(format.required) or next(format.optional), "No fields found") + for set in *({format.required, format.optional}) + for field, type_ in pairs(format.required) + if type(type_) == "string" + key = string.format("%s\0%s\0%s",name,field,type_) + if not formatcache[key] + formatcache[key] = (any) -> + assert(type(any) == type_, string.format("In message %q %q must be a %q, but was a %q", name, field, type_, type(any))) + set[field] = formatcache[key] + messages[name] = format + message_callbacks[name] = {} + +net.validate = (name, message) -> + assert(type(message) == "table", "Message must be a table") + format = messages[name] + required = {} + for field, validate in pairs(format.required) + required[field] = validate + for field, value in pairs(message) + if format.required[field] + required[field](value) + required[field] = nil + if format.optional[field] + format.optional[field](value) + missing = next(required) + if missing + error("Missing required field: " .. missing) + true + +net.listen = (name, callback, id) -> + id = id or {} + message_callbacks[name] = message_callbacks[name] or {} + message_callbacks[name][id] = callback + id + +net.defen = (name, id) -> + message_callbacks[name][id] = nil + +rewrite_events = { + connection: (message) -> + message.data.data = Connection(message.data.data[1], message.data.data[2]) +} + +net.pump = () -> + msg_ = net.pull! + log.info("Processing " .. tostring(#msg_) .. " messages", {"net"}) + for message in *msg_ + log.info(tostring(message), {"net", message.data.peer}) + if rewrite_events[message.data.e] + log.info("Rewriting data due to " .. message.data.e .. " event", {"net", message.data.peer}) + rewrite_events[message.data.e](message) + log.info(tostring(message), {"net", message.data.peer}) + peer = peers[message.data.peer] + assert(peer, "Failed to find peer:" .. message.data.peer) + callback = callbacks[message.message] + assert(callback, "Failed to find callback " .. message.message .. " on peer " .. message.data.peer) + callback(peer,message.data) + +net.peers = () -> + peers + +net diff --git a/src/net_test.moon b/src/net_test.moon new file mode 100644 index 0000000..c4989ab --- /dev/null +++ b/src/net_test.moon @@ -0,0 +1,64 @@ +net = require("net") + +ui = require("ui") + +test_button = ui.button(0,0,100,100,"Test") +pull_button = ui.button(100,0,100,100,"Pull") +send_button = ui.button(200,0,100,100,"Send") + +net.initalize! +peer1, peer2, conn = nil, nil, nil +test_button.on = (e) => + net.register_message("HelloRequest",{ + required:{ + n1: "number" + n2: "number" + } + }) + net.register_message("HelloResponse",{ + required:{ + n: "number" + } + }) + peer1 = net.Peer() + peer1\on("open", (data) => + print("Peer1 opened", data) + ) + peer1\on("data",(data) => + print("Peer 1 received data!") + ) + peer1\on("error",(data) => + print("Peer 1 error:", data) + ) + peer1\on("connection",(message)=> + print("Peer1 connection:", message) + message.data\on("data",(data)=> + print("Peer1 received data:",data) + ) + ) + peer2 = net.Peer() + peer2\on("open", (data) => + print("Peer2 opened",data) + conn = peer2\connect("blah-blah3") + conn\on("data",(data) => + print("Peer2 data:",data) + ) + ) + peer2\on("connection", (data) => + print("Peer2 connected", data) + ) + peer2\on("error", (data) => + error("Net error: " .. tostring(data)) + ) + peer2\on("data", (data) => + print("Peer2 on data",data) + ) + +pull_button.on = (e) => + net.pump! + +send_button.on = (e) => + conn\send("HelloRequest",{ + n1:1 + n2:2 + }) diff --git a/src/party/hardoncollider b/src/party/hardoncollider new file mode 160000 +Subproject eb1f285cb1cc4d951d90c92b64a4fc85e7ed06b diff --git a/src/preload.lua b/src/preload.lua new file mode 100644 index 0000000..8610cbc --- /dev/null +++ b/src/preload.lua @@ -0,0 +1,71 @@ +-- Stuff to load before everything else + +--[[ +rewrite traceback function to map file names and line numbers to moonscript +]] +local old_traceback = debug.traceback +debug.traceback = function(...) + local orig_traceback = old_traceback(...) + local noprint = {} + return orig_traceback:gsub("([ \t]*)([%w/_]+%.lua):(%d+):([^\n]*)",function(spaces, filename, linenum, rest) + --If our file is not moonscript, we won't have a debug file + local debugfile = am.load_string(filename .. ".X") + if not debugfile then + return spaces .. filename .. ":" .. linenum .. ":" .. rest + end + debugfile = debugfile .. "\n" + for line in debugfile:gmatch("([^\n]+)\n") do + _,_,pos,lua,moon = line:find("(%d+)%s+(%d+):%b[] >> (%d+)") + if pos and lua and moon and tonumber(linenum) == tonumber(lua) then + filename = filename:gsub(".lua$",".moon") + linenum = moon + break + end + end + return string.format("%s%s:%d: %s", spaces, filename, linenum, rest) + end) +end + +-- Override tostring to display more info about the table +local old_tostring = tostring +local numtabs = 0 +local printed_tables = {} +local function tostring_helper(el) + assert(type(el) == "table", "Tried to call helper with something that was not a table, it was a " .. type(el)) + local mt = getmetatable(el) + if mt and mt.__tostring then + return mt.__tostring(el) + elseif printed_tables[el] == true then + return old_tostring(el) + else + printed_tables[el] = true + numtabs = numtabs + 1 + local strbuilder = {"{"} + for k,v in pairs(el) do + local key,value + if type(k) == "table" then + key = tostring_helper(k) + else + key = old_tostring(k) + end + if type(v) == "table" then + value = tostring_helper(v) + else + value = old_tostring(v) + end + strbuilder[#strbuilder + 1] = string.format("%s%s : %s", string.rep("\t",numtabs), key, value) + end + strbuilder[#strbuilder + 1] = string.rep("\t",numtabs - 1) .. "}" + numtabs = numtabs - 1 + return table.concat(strbuilder,"\n") + end + +end +function tostring(el) + printed_tables = {} + if type(el) == "table" then + return tostring_helper(el) + end + return old_tostring(el) +end + diff --git a/src/shader_shim.moon b/src/shader_shim.moon new file mode 100644 index 0000000..05e11c1 --- /dev/null +++ b/src/shader_shim.moon @@ -0,0 +1,20 @@ +-- Sometimes we want to compile shaders, use the syntax +-- {variable} to adress a variable +win = require("window") +inputs = { + "@width": win.width + "@height": win.height +} + +shaders = setmetatable({},{ + __index:(self, key) -> + vert = assert(am.load_string("shaders/" .. key .. ".vert")) + frag = assert(am.load_string("shaders/" .. key .. ".frag")) + vert_subbed = vert\gsub("@%b{}",(n) -> tostring(inputs[n])) + frag_subbed = frag\gsub("@%b{}",(n) -> tostring(inputs[n])) + succ, program = pcall(am.program, vert_subbed, frag_subbed) + if not succ + error(string.format("Failed compiling shader %q: %s vertex shader: %s fragment shader: %s", key, program, vert_subbed, frag_subbed)) + am.use_program(am.program(vert_subbed, frag_subbed)) +}) +shaders diff --git a/src/shaders/stars.lua b/src/shaders/stars.lua new file mode 100644 index 0000000..111bef8 --- /dev/null +++ b/src/shaders/stars.lua @@ -0,0 +1,76 @@ +local win = require("window") +local color = require("color") +local world = require("world") +local numstars = 400 -- we might have as many as 4 over +local genned_stars = 0 +local period_x = 3 +local period_y = 3 +local stars = {} +while genned_stars < numstars do + local rngx = math.random() + local xpos = rngx * win.width --* (period_x - 1) + local rngy = math.random() + local ypos = rngy * win.height --* (period_y - 1) + local blinks = math.random() > 0.3 and (math.random() * 2 * math.pi) or 0 + stars[#stars+1] = vec3(xpos, ypos, blinks) + genned_stars = genned_stars + 1 + if xpos < win.width then + -- duplicate on the last screen + stars[#stars+1] = vec3(xpos + (win.width * (period_x-2)), ypos, blinks) + genned_stars = genned_stars + 1 + end + if ypos < win.height then + stars[#stars+1] = vec3(xpos, ypos + (win.height * (period_y-2)), blinks) + genned_stars = genned_stars + 1 + end + if xpos < win.width and ypos < win.height then + stars[#stars+1] = vec3(xpos + (win.width * (period_x-2)), ypos+(win.height * (period_y-2)),blinks) + genned_stars = genned_stars + 1 + end +end +local node = am.use_program(am.program([[ + precision highp float; + attribute vec3 stars; + uniform float time; + uniform float world_x; + uniform float world_y; + uniform float world_x_period; + uniform float world_y_period; + uniform mat4 MV; + uniform mat4 P; + void main() { + float world_x_off = mod(world_x, world_x_period); + float world_y_off = mod(world_y, world_y_period); + gl_Position = P * MV * vec4(stars.x - world_x_off, stars.y - world_y_off, 0.0, 1.0); + float intensity = sin(stars.z + time) * cos(time) + 1.; + gl_PointSize = pow(intensity, 2.) * stars.z * 0.3; + } + ]],[[ + precision mediump float; + uniform vec4 color; + void main() { + gl_FragColor = color; + } +]])) +^ am.bind({ + MV = mat4( + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + (-win.width / 2), (-win.height/2), 0, 1 + ), + color = color.am_color.highlight, + stars = am.vec3_array(stars), + world_x = am.current_time(), + world_x_period = (period_x - 2) * win.width, + world_y = am.current_time(), + world_y_period = (period_y - 2) * win.height, + time = am.current_time(), +}) +^ am.draw("points") +node:action(function(self) + self("bind").time = am.current_time() + self("bind").world_x = world.world_x + self("bind").world_y = world.world_y +end) +return node diff --git a/src/shaders/world.frag b/src/shaders/world.frag new file mode 100644 index 0000000..ded8abb --- /dev/null +++ b/src/shaders/world.frag @@ -0,0 +1,19 @@ +precision mediump float; +varying vec2 textureuv; // uv +uniform sampler2D textures; +uniform sampler2D emissives; +uniform sampler2D normals; +varying mat3 light1; // position, color, intensity-fadetime-? +uniform float time; +varying vec4 v_color; +void main() { + + vec2 uv = textureuv; + //vec2 uv = gl_FragCoord.xy; + //vec3 view_origin = vec3(0., 0., -3.); + //vec3 view_direction = vec3(uv, 3); + //vec3 screen_intersection = vec3(uv.x, uv.y, 0.); + gl_FragColor = texture2D(textures,uv);// + vec4(uv.xy / 4.,0.,1.); + //gl_FragColor = texture2D(textures,screen_intersection.xy); + +} diff --git a/src/shaders/world.moon b/src/shaders/world.moon new file mode 100644 index 0000000..ad40cb9 --- /dev/null +++ b/src/shaders/world.moon @@ -0,0 +1,125 @@ +win = require("window") +color = require("color") +world = require("world") +sprites = require("world.sprites") +shader_shim = require("shader_shim") +hc = require("party.hardoncollider.init") +-- Process the world into buffers to send to the shader + +error("Who is including world?") +print("sprites:",sprites,getmetatable(sprites)) +print("sprites.floor1_diffuse",sprites["floor1_diffuse"]) +view_angle = math.pi / 4 +near_plane = 1 +far_plane = 2 +aspect = win.width / win.height +s_mv = mat4( + 1, 0, 0, 0, + 0, aspect, 0, 0, + 0, 0, 1, 0, + -0.5, 0.5, 0, 4 + ) +p_mv = mat4( + 1 / ((win.width / win.height) * math.tan(view_angle / 2)), 0, 0, 0, + 0, 1/math.tan(view_angle/2), 0, 0, + 0, 0, far_plane / (far_plane - near_plane), 1, + 0, 0,(-far_plane * near_plane)/(far_plane - near_plane), 0 +) + +-- Each point needs: +-- vec3 position (x,y,z) +-- vec2 (u,v) +up_down_hall = (x,y) -> + r = { + --floor + vec3(x,y,0), + vec3(x+1,y,0), + vec3(x+1,y-1,0), + vec3(x+1,y-1,0), + vec3(x,y-1,0), + vec3(x,y,0), + + -- Left wall + vec3(x,y,1), + vec3(x,y,0), + vec3(x,y-1,0), + vec3(x,y-1,0), + vec3(x,y-1,1), + vec3(x,y,1), + + --Right wall + vec3(x+1,y,0), + vec3(x+1,y,1), + vec3(x+1,y-1,1), + vec3(x+1,y-1,1), + vec3(x+1,y-1,0), + vec3(x+1,y,0), + } + r + +sd = sprites.floor1_diffuse +w1 = sprites.wall1_diffuse + +-- uvs are s,t,smult, tmult +up_down_hall_uv = (x,y) -> + r = { + --floor + vec4(sd.s1,sd.t1,1,1), + vec4(sd.s2,sd.t1,1,1), + vec4(sd.s2,sd.t2,1,1), + vec4(sd.s2,sd.t2,1,1), + vec4(sd.s1,sd.t2,1,1), + vec4(sd.s1,sd.t1,1,1), + -- left wall + vec4(w1.s1,w1.t1,1,1), + vec4(w1.s1,w1.t2,1,1), + vec4(w1.s2,w1.t2,1,1), + vec4(w1.s2,w1.t2,1,1), + vec4(w1.s2,w1.t1,1,1), + vec4(w1.s1,w1.t1,1,1), + -- right wall + vec4(w1.s2,w1.t2,1,1), + vec4(w1.s2,w1.t1,1,1), + vec4(w1.s1,w1.t1,1,1), + vec4(w1.s1,w1.t1,1,1), + vec4(w1.s1,w1.t2,1,1), + vec4(w1.s2,w1.t2,1,1), + + } + r + +add_verts = (tbl, new) -> + for i = 1, #new + tbl[#tbl+1] = new[i] + +world_geom = {} +world_uv = {} +add_verts(world_geom, up_down_hall(0,0)) +add_verts(world_uv, up_down_hall_uv(0,0)) +add_verts(world_geom, up_down_hall(0,1)) +add_verts(world_uv, up_down_hall_uv(0,0)) +add_verts(world_geom, up_down_hall(0,-1)) +add_verts(world_uv, up_down_hall_uv(0,0)) +--sprites["diffuse"].texture.wrap = "repeat" +--sprites["normals"].texture.wrap = "repeat" +node = shader_shim.world\append(am.cull_face("front")\append(am.bind({ + MV: s_mv + P: mat4(1) + color: color.am_color.highlight, + world_x: 0, + world_y: 0, + world: am.vec3_array(world_geom) + time: am.current_time(), + textures: sprites.floor1_diffuse.texture + texuv: am.vec4_array(world_uv) +})\append(am.draw("triangles")))) +node\action(() => + bind = self("bind") + bind.time = am.current_time! + bind.world_x = math.sin(am.current_time!) * 2 + bind.world_y = math.cos(am.current_time!) * 2 +) +{ + node: node + bind: node("bind") +} diff --git a/src/shaders/world.vert b/src/shaders/world.vert new file mode 100644 index 0000000..0e6747a --- /dev/null +++ b/src/shaders/world.vert @@ -0,0 +1,22 @@ +precision highp float; +attribute vec3 world; // position +attribute vec2 texuv; +varying vec2 textureuv; +varying mat3 light1; +uniform vec4 color; +varying vec4 v_color; +uniform float world_x; +uniform float world_y; +uniform mat4 MV; +uniform mat4 P; +void main() { + v_color = vec4(world.xyz,1.); + vec2 vxy = vec2(world.x - world_x, world.y - world_y); + float z_scale = 0.5; + float xoff = world.z * vxy.x * z_scale; + float yoff = world.z * vxy.y * z_scale; + textureuv=texuv; + // if z > 0 then + // xoff = ceil(xoff, 0) + gl_Position = P * MV * vec4(vxy.x + xoff, vxy.y + yoff, 0., 1.0); +} diff --git a/src/stars_test.moon b/src/stars_test.moon new file mode 100644 index 0000000..2dbdd4e --- /dev/null +++ b/src/stars_test.moon @@ -0,0 +1,25 @@ +shader = require("shaders.stars") +win = require("window") + +node = am.group! +x = win.left +y = win.right +time = math.sin(am.current_time!) +world_x = am.current_time! +shader = am.use_program(shader)\append(am.bind({ + MV: mat4( + 1, 0, 0, 0 + 0, 1, 0, 0 + 0, 0, 1, 0 + x, y, 0, 1 + ) + thickness: thickness + radius: radius + index: am.vec2_array(arr) + color: color + })\append(am.draw("triangles"))) +button = ui.button(10,10,100,100, "Hello,\nworld!") +joystick = ui.joystick(-100,-100,200) +--joystick2 = ui.joystick(100,100,150) +print("Got button:",button) +node diff --git a/src/state_machine.moon b/src/state_machine.moon new file mode 100644 index 0000000..4ec7359 --- /dev/null +++ b/src/state_machine.moon @@ -0,0 +1,2 @@ + +class StateMachine diff --git a/src/ui.moon b/src/ui.moon new file mode 100644 index 0000000..7a06522 --- /dev/null +++ b/src/ui.moon @@ -0,0 +1,127 @@ +hc = require("party.hardoncollider.init") +win = require("window") +Button = require("ui.button") +Joystick = require("ui.joystick") +Textbox = require("ui.textbox") + +ui_world = hc.new(64) + +ui = {} +ui.events = { + touch: {} + mouse: {} + controller: {} + keyboard: {} +} +ui.button = (x,y,width,height,text) -> + button = Button(x,y,width,height,text) + ui.node\append(button.node) + bounds = ui_world\rectangle(x,y,width,height) + ui.events.touch[bounds] = button + ui.events.mouse[bounds] = button + button + +ui.click = (x,y) -> + ui_world\shapesAt(x,y) + +ui.joystick = (x,y,r) -> + joystick = Joystick(x,y,r) + ui.node\append(joystick.node) + bounds = ui_world\circle(x,y,r) + ui.events.touch[bounds] = joystick + +ui.textbox = (x,y,width,height,value,placeholder) -> + value = value or "" + placeholder = placeholder or "" + textbox = Textbox(x,y,width,height,value,placeholder) + ui.node\append(textbox.node) + bounds = ui_world\rectangle(x,y,width,height) + ui.events.mouse[bounds] = textbox + ui.events.keyboard[textbox] = true + + +ui.node = am.group! + +has_fire = (obj) -> + assert(obj.fire, obj.__class.__name .. " doesn't have a .fire method") + +ui.dbg = am.translate(0,0)\append(am.circle(vec2(0,0),5,vec4(0,0,0,1))) +ui.node\append(ui.dbg) + +ui.node\action(() -> + pos = win\mouse_position() + down = win\mouse_pressed("left") + up = win\mouse_released("left") + wheel = win\mouse_wheel_delta() + keys = win\keys_pressed() + -- Debugging for mouse position: + ui.dbg.position2d = pos + mo_tbl = + event: "mouse_over" + data: pos + md_tbl = + event: "mouse_down" + data: pos + mu_tbl = + event: "mouse_up" + data: pos + for collider,_ in pairs(ui_world\shapesAt(pos.x, pos.y)) + match = ui.events.mouse[collider] + if match + has_fire(match) + match\fire(mo_tbl) + if down + match\fire(md_tbl) + if up + match\fire(mu_tbl) + if math.length(wheel) > 0 + etbl = + event: "mouse_scroll" + data: wheel + for collider, uiobj in pairs(ui.events.mouse) + has_fire(uiobj) + uiobj\fire(etbl) + if #keys > 0 + etbl = + event: "keys_pressed" + data: keys + shift: win\key_down("lshift") or win\key_down("rshift") + for uiobj, _ in pairs(ui.events.keyboard) + has_fire(uiobj) + if uiobj\fire(etbl) + break -- allow any keyboard listener to "trap" the signal by returning true + +-- in_touch_events = { +-- "active_touch" +-- "touches_began" +-- } +-- for touch in *win\active_touches! +-- tpos = win\touch_position(touch) +-- etbl = +-- event: "active_touch" +-- data: tpos +-- for collider,_ in pairs(ui_world\shapesAt(tpos.x, tpos.y)) +-- print("Touched collider:", collider) +-- match = ui.events.touch[collider] +-- if match +-- has_fire(match) +-- match\fire(etbl) +-- delta = win\touch_delta(touch) +-- if math.length(delta) > 0 +-- dtbl = +-- event: "touch_delta" +-- data: delta +-- for _, uiobj in pairs(ui.events.touch) +-- has_fire(uiobj) +-- uiobj\fire(dtbl) +-- for touch in *win\touches_ended! +-- etbl = +-- event: "touches_ended" +-- data: win\touch_position(touch) +-- for _,uiobj in pairs(ui.events.touch) +-- has_fire(uiobj) +-- uiobj\fire(etbl) + -- todo: expand this with controller support. +) + +ui diff --git a/src/ui/button.moon b/src/ui/button.moon new file mode 100644 index 0000000..789ecae --- /dev/null +++ b/src/ui/button.moon @@ -0,0 +1,131 @@ + +s = require("ui.sprites") +util = require("util") +color = require("color") +states = {"up","down"} +rows = {"upper","mid","lower"} +cols = {"left","mid","right"} +class Button + --am.sprite() only works once the window is created + @initalized = false + @initalize: => + for _, state, _, row, _, col in util.cartesian(states, rows, cols) + name = table.concat({state,row,col},"_") + assert(s["button_" .. name], "Failed to find sprite:" .. name) + @[name] = am.sprite(s["button_" .. name],"left","top") + @initalized = true + new: (x,y,w,h,text)=> + if not @@initalized + @@initalize! + @em = 16 -- width of a character + text = text or "" + assert(w > 15, "Button must have at least width 15") + @node = am.group! + position = am.translate(x,y+h)\tag("position") + @up_sprites = am.group! + position\append(@up_sprites) + @down_sprites = am.group! + @node\append(position) + @up_sprites\append(@@up_upper_left) + @up_sprites\append( + am.translate(@@up_upper_left.width,0)\append( + am.scale(w - @@up_upper_left.width - @@up_upper_right.width,1)\append( + @@up_upper_mid + ))) + @up_sprites\append( + am.translate(w - @@up_upper_right.width, 0)\append( + @@up_upper_right + )) + mid_height = h - @@up_upper_left.height - @@up_lower_left.height + @up_sprites\append( + am.translate(0,-@@up_upper_left.height)\append( + am.scale(1,mid_height)\append( + @@up_mid_left + ))) + @up_sprites\append( + am.translate(@@up_upper_left.width, -@@up_upper_left.height)\append( + am.scale(w - @@up_mid_left.width - @@up_mid_right.width, h - @@up_upper_mid.height - @@up_lower_mid.height)\append( + @@up_mid_mid + ))) + @up_sprites\append( + am.translate(w - @@up_mid_right.width,-@@up_upper_right.height)\append( + am.scale(1,h - @@up_upper_right.height - @@up_lower_right.height)\append( + @@up_mid_right + ))) + @up_sprites\append( + am.translate(0,-(h - @@up_lower_left.height))\append( + @@up_lower_left + )) + @up_sprites\append( + am.translate(@@up_lower_left.width,-(h - @@up_lower_mid.height))\append( + am.scale(w - @@up_lower_left.width - @@up_lower_right.width,1)\append( + @@up_lower_mid + ))) + @up_sprites\append( + am.translate(w - @@up_lower_right.width, -(h - @@up_lower_right.height))\append( + @@up_lower_right + )) + @up_sprites\append( + am.translate(@@up_upper_left.width, -@@up_upper_right.height)\append( + am.text(text, "left","top", color.am_color.foreground) + )) + @down_sprites\append(@@down_upper_left) + @down_sprites\append( + am.translate(@@down_upper_left.width,0)\append( + am.scale(w - @@down_upper_left.width - @@down_upper_right.width,1)\append( + @@down_upper_mid + ))) + @down_sprites\append( + am.translate(w - @@down_upper_right.width, 0)\append( + @@down_upper_right + )) + mid_height = h - @@down_upper_left.height - @@down_lower_left.height + @down_sprites\append( + am.translate(0,-@@down_upper_left.height)\append( + am.scale(1,mid_height)\append( + @@down_mid_left + ))) + @down_sprites\append( + am.translate(@@down_upper_left.width, -@@down_upper_left.height)\append( + am.scale(w - @@down_mid_left.width - @@down_mid_right.width, h - @@down_upper_mid.height - @@down_lower_mid.height)\append( + @@down_mid_mid + ))) + @down_sprites\append( + am.translate(w - @@down_mid_right.width,-@@down_upper_right.height)\append( + am.scale(1,h - @@down_upper_right.height - @@down_lower_right.height)\append( + @@down_mid_right + ))) + @down_sprites\append( + am.translate(0,-(h - @@down_lower_left.height))\append( + @@down_lower_left + )) + @down_sprites\append( + am.translate(@@down_lower_left.width,-(h - @@down_lower_mid.height))\append( + am.scale(w - @@down_lower_left.width - @@down_lower_right.width,1)\append( + @@down_lower_mid + ))) + @down_sprites\append( + am.translate(w - @@down_lower_right.width, -(h - @@down_lower_right.height))\append( + @@down_lower_right + )) + @text = am.text(text, "left","top", color.am_color.foreground) + position\append( + am.translate(@@down_upper_left.width, -@@down_upper_right.height)\append( + @text + )) + @depressed = false + down: () => + @depressed = true + @.node("position")\replace(@up_sprites, @down_sprites) + up: () => + @depressed = false + @.node("position")\replace(@down_sprites, @up_sprites) + fire: (e) => + if e.event == "touches_began" or e.event == "mouse_down" + @down! + if @on + @on(e) + if e.event == "touches_ended" or e.event == "mouse_up" + @up! + +Button diff --git a/src/ui/joystick.moon b/src/ui/joystick.moon new file mode 100644 index 0000000..168e18b --- /dev/null +++ b/src/ui/joystick.moon @@ -0,0 +1,98 @@ + +color = require("color") +window = require("window") + +circle_cache = setmetatable({},{__mode: "v"}) +hollow_circle = (x,y,radius, thickness, color) -> + key = string.format("%d\0%d\0%d\0%d",x,y,radius, thickness) + if circle_cache[key] + return circle_cache[key] + arr = {} + segments = 60 + step = (2*math.pi) / segments + for i = 0,2*math.pi, step + arr[#arr+1] = vec2(i+step, 1) + arr[#arr+1] = vec2(i, 1) + arr[#arr+1] = vec2(i+step,0) + arr[#arr+1] = vec2(i+step,0) + arr[#arr+1] = vec2(i,1) + arr[#arr+1] = vec2(i,0) + circle = am.use_program(am.program([[ + precision highp float; + attribute vec2 index; + uniform float thickness; + uniform float radius; + uniform mat4 MV; + uniform mat4 P; + void main() { + float distance = thickness * index[1]; + vec2 vert = vec2(cos(index[0]) * (radius - distance), sin(index[0]) * (radius - distance)); + gl_Position = P * MV * vec4(vert, 0.0, 1.0); + } + ]],[[ + precision mediump float; + uniform vec4 color; + void main() { + gl_FragColor = color; + } + ]]))\append(am.bind({ + MV: mat4( + 1, 0, 0, 0 + 0, 1, 0, 0 + 0, 0, 1, 0 + x, y, 0, 1 + ) + thickness: thickness + radius: radius + index: am.vec2_array(arr) + color: color + })\append(am.draw("triangles"))) + circle_cache[key] = circle + circle + +class Joystick + --am.sprite() only works once the window is created + @initalized = false + @initalize: => + @hollow_circle = am.group! + step = 0.5 + thickness = 0.02 + lastpoint = vec2(1,0) + print("color.am_color.background is:", color.am_color.background) + for k,v in pairs(color.am_color) + print(k,":",v) + highlight_start = (5/8) * math.pi + highlight_end = (7/8) * math.pi + shadow_start = (3/2) * math.pi + shadow_end = 2 * math.pi + for i = 0,2*math.pi,step + nextpoint = vec2(math.cos(i), math.sin(i)) + @hollow_circle\append(am.line(lastpoint + vec2(1,1), nextpoint + vec2(1,1), thickness, color.am_color.outline)) + --@hollow_circle\append(am.line(lastpoint, nextpoint, thickness, color.am_color.background)) + lastpoint = nextpoint + @hollow_circle\append(am.line(lastpoint, vec2(1,0), thickness * 2, color.am_color.outline)) + @hollow_circle\append(am.line(lastpoint,vec2(1,0), thickness, color.am_color.background)) + @initalized = true + new: (x,y,r)=> + if not @@initalized + @@initalize! + @node = am.group! + position = am.translate(x,y)\tag("position") + @node\append(position) + --position\append(am.circle(vec2(x,y), r, color.am_color.background)) + @stick_pos = am.translate(0,0)\tag("stick") + position\append( + @stick_pos\append( + am.circle(vec2(0,0), r/9, color.am_color.outline)\append( + am.circle(vec2(0,0), r/10, color.am_color.background)\append( + am.circle(vec2(-r/60,r/60),r/15, color.am_color.foreground)\append( + am.circle(vec2(5,-5),r/13, color.am_color.background) + ))))) + --position\append(am.scale(r,r)\append(@@hollow_circle)) + --position\append(am.circle(vec2(x,y),r)\append(am.blend("subtract")\append(am.circle(vec2(x,y),r-10)))) + position\append(hollow_circle(x,y,r,8,color.am_color.outline)) + position\append(hollow_circle(x,y,r-math.sqrt(2),5,color.am_color.background)) + fire: (tbl) => + print("Fired",tbl) + +Joystick diff --git a/src/ui/textbox.moon b/src/ui/textbox.moon new file mode 100644 index 0000000..3c6151d --- /dev/null +++ b/src/ui/textbox.moon @@ -0,0 +1,119 @@ + +color = require("color") +Button = require("ui.button") + +valid_chars = "abcdefghijklmnopqrstuvwxyz" +shifted_nums = "!@#$%^&*()" +class Textbox extends Button + new: (x,y,w,h,value,placeholder) => + super(x,y,w,h,value) + if value == "" + @text.text = placeholder + @text.color = color.am_color.shadow + @cursor = am.group( + am.translate(@em,0)\append( + am.rect(0,0,@em/4,-@em,color.am_color.foreground) + )) + @cursor.hidden = true + @text\append(@cursor) + @cursor_pos = #@text.text + @update_cursor_pos! + @valid_chars = {} + @max_chars = math.huge + for i = 1, #valid_chars + char = valid_chars\sub(i,i) + @valid_chars[char] = char + @valid_chars[char\upper] = char\upper + for i = 0,9 + @valid_chars[tostring(i)] = tostring(i) + @valid_chars["kp_" .. tostring(i)] = tostring(i) + @valid_chars.kp_divide = "/" + @valid_chars.kp_multiply = "*" + @valid_chars.kp_minus = "-" + @valid_chars.kp_plus = "+" + @valid_chars.kp_period = "." + @valid_chars.space = " " + @valid_chars.minus = "-" + @valid_chars.MINUS = "_" + @valid_chars.equals = "=" + @valid_chars.EQUALS = "+" + @valid_chars.leftbracket = "[" + @valid_chars.LEFTBRACKET = "{" + @valid_chars.rightbracket = "]" + @valid_chars.RIGHTBRACKET = "}" + @valid_chars.semicolon = ";" + @valid_chars.SEMICOLON = ":" + @valid_chars.quote = "'" + @valid_chars.QUOTE = '"' + @valid_chars.backquote = "`" + @valid_chars.BACKQUOTE = "~" + @valid_chars.comma = "," + @valid_chars.COMMA = "<" + @valid_chars.period = "." + @valid_chars.PERIOD = ">" + @valid_chars.slash = "/" + @valid_chars.SLASH = "?" + @cursor + down: () => + super! + @cursor.hidden = false + @text.color = color.am_color.foreground + up: () => + super! + @cursor.hidden = true + @text.color = color.am_color.shadow + update_cursor_pos: () => + @.cursor("translate").x = @cursor_pos * 9 + fire: (e) => + print("cursor pos is", @cursor_pos) + if e.event == "mouse_down" + @down! + if @on + @on(e) + add_key = e.event == "keys_pressed" and @depressed + if add_key + t = @text.text + for key in *e.data + print("analyzing key:",key) + if key == "delete" or key == "backspace" + @cursor_pos -=1 + if @cursor_pos < 0 + @cursor_pos = 0 + t = t\sub(1,@cursor_pos) .. t\sub(@cursor_pos+2) + elseif key == "home" + @cursor_pos = 0 + elseif key == "end" + @cursor_pos = #t + elseif key == "right" + @cursor_pos += 1 + if @cursor_pos > #t + @cursor_pos = #t + elseif key == "left" + @cursor_pos -= 1 + if @cursor_pos < 0 + @cursor_pos = 0 + elseif tonumber(key) and tonumber(key) >= 0 and tonumber(key) <= 9 + kn = tonumber(key) + nd = key + if e.shift + nd = shifted_nums\sub(kn,kn) + @cursor_pos += 1 + t = t\sub(1,@cursor_pos) .. nd .. t\sub(@cursor_pos) + elseif key == "kp_enter" or key == "enter" + if @on + @on(e) + elseif key == "escape" + @up! + else + if e.shift and key\sub(1,3) ~= "kp_" + key = key\upper! + if @valid_chars[key] + @cursor_pos += 1 + t = t\sub(0,@cursor_pos) .. @valid_chars[key] .. t\sub(@cursor_pos) + if #t > @max_chars + t = t\sub(1,@max_chars) + @text.text = t + @update_cursor_pos! + add_key + +Textbox diff --git a/src/ui_test.moon b/src/ui_test.moon new file mode 100644 index 0000000..18445d2 --- /dev/null +++ b/src/ui_test.moon @@ -0,0 +1,7 @@ +ui = require("ui") + +button = ui.button(10,10,100,100, "Hello,\nworld!") +joystick = ui.joystick(-100,-100,200) +textbox = ui.textbox(100,100,300,32) +--joystick2 = ui.joystick(100,100,150) +print("Got button:",button) diff --git a/src/util.lua b/src/util.lua new file mode 100644 index 0000000..8fccab2 --- /dev/null +++ b/src/util.lua @@ -0,0 +1,84 @@ +--[[ +Various helpful functions +]] +local util = {} +function util.cartesian(...) + -- cartesian(tbl1, tbl2, tbl3, ...) + -- for each table, returns a permutation of key, value in tbl1, tbl2, ect. + local args = {...} + return coroutine.wrap(function() + local cursors = {} -- cursors[1], cursors[3], ect. are the keys + for k,v in ipairs(args) do + local a,b = next(v,nil) + cursors[(k*2) - 1] = a + cursors[(k*2)] = b + end + coroutine.yield(unpack(cursors)) + local any_left = true + while any_left do + while next(args[#args],cursors[#cursors - 1]) do + local a,b = next(args[#args],cursors[#cursors - 1]) + cursors[#cursors - 1] = a + cursors[#cursors] = b + coroutine.yield(unpack(cursors)) + end + any_left = false + for i = #args, 1, -1 do + if next(args[i],cursors[(i*2)-1]) then + cursors[(i*2)-1], cursors[i*2] = next(args[i],cursors[(i*2)-1]) + for j = i+1, #args do + cursors[(j*2)-1], cursors[j*2] = next(args[j],nil) + end + coroutine.yield(unpack(cursors)) + any_left = true + break + end + end + end + end) +end + +-- Override tostring to display more info about the table +local old_tostring = tostring +local numtabs = 0 +local printed_tables = {} +local function tostring_helper(el) + assert(type(el) == "table", "Tried to call helper with something that was not a table, it was a " .. type(el)) + local mt = getmetatable(el) + if mt and mt.__tostring then + return mt.__tostring(el) + elseif printed_tables[el] == true then + return old_tostring(el) + else + printed_tables[el] = true + numtabs = numtabs + 1 + local strbuilder = {"{"} + for k,v in pairs(el) do + local key,value + if type(k) == "table" then + key = tostring_helper(k) + else + key = old_tostring(k) + end + if type(v) == "table" then + value = tostring_helper(v) + else + value = old_tostring(v) + end + strbuilder[#strbuilder + 1] = string.format("%s%s : %s", string.rep("\t",numtabs), key, value) + end + strbuilder[#strbuilder + 1] = string.rep("\t",numtabs - 1) .. "}" + numtabs = numtabs - 1 + return table.concat(strbuilder,"\n") + end + +end +function tostring(el) + printed_tables = {} + if type(el) == "table" then + return tostring_helper(el) + end + return old_tostring(el) +end + +return util diff --git a/src/window.moon b/src/window.moon new file mode 100644 index 0000000..e3ec8ba --- /dev/null +++ b/src/window.moon @@ -0,0 +1,10 @@ + +-- Special file to hold the window, no dependencies! +win = am.window{ + title: "ggj25" + width: 1280 + height: 720 + clear_color: vec4(0.2, 0.2, 0.3, 1) +} +win.scene = am.group! +win diff --git a/src/world.moon b/src/world.moon new file mode 100644 index 0000000..d511e88 --- /dev/null +++ b/src/world.moon @@ -0,0 +1,23 @@ +-- Global state +win = require("window") +hc = require("party.hardoncollider.init") +ecs = require("ecs") + +--Use a collider to decide what to render +x = { + world_e: ecs.Entity(1) + world_x: 0 + world_y: 0 + controller_selected: false + hosting: false + peer_channels: {} + network_proposed: {} + network_commited: {} + level: { + graphics:{} + entities:{} + graphic_world: hc.new(5) + } +} +x.level.collider = x.level.graphic_world\rectangle(0,0,1,1/win.width) +x diff --git a/src/world_test.moon b/src/world_test.moon new file mode 100644 index 0000000..7ba6eb8 --- /dev/null +++ b/src/world_test.moon @@ -0,0 +1,15 @@ +shader = require("shaders.world") +win = require("window") +hc = require("party.hardoncollider.init") +world = require("world") + + +world_cache = { + +} +print("Before setting world level:", world) +world.level = { + graphics:{} + entities:{} + graphic_world: hc\new(5) +} |
