From 0066f8ba0a308437f3f0d05029739c4d6cce62e0 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Sun, 21 Aug 2022 22:53:40 +0000 Subject: [PATCH] improve main menu --- .luarc.json | 3 + src/data/init.lua | 38 ++++-- src/data/maps/main-menu.lua | 179 ++++++++++++++++++++++++++ src/data/maps/main-menu.tmx | 49 +++++++ src/data/sprites/title.aseprite | Bin 0 -> 1661 bytes src/data/ui/prompts/dark/a.png | Bin 0 -> 177 bytes src/data/ui/prompts/dark/d.png | Bin 0 -> 173 bytes src/data/ui/prompts/dark/s.png | Bin 0 -> 181 bytes src/data/ui/prompts/dark/spacebar.png | Bin 0 -> 657 bytes src/data/ui/prompts/dark/w.png | Bin 0 -> 175 bytes src/groups.lua | 1 + src/lib/ase-loader.lua | 7 +- src/lib/sti/init.lua | 6 +- src/main.lua | 1 + src/states/main-menu.lua | 72 ++++++++--- src/states/main.lua | 13 +- src/systems/map.lua | 41 +++++- src/systems/sprite.lua | 44 ++++++- 18 files changed, 403 insertions(+), 51 deletions(-) create mode 100644 src/data/maps/main-menu.lua create mode 100644 src/data/maps/main-menu.tmx create mode 100644 src/data/sprites/title.aseprite create mode 100644 src/data/ui/prompts/dark/a.png create mode 100644 src/data/ui/prompts/dark/d.png create mode 100644 src/data/ui/prompts/dark/s.png create mode 100644 src/data/ui/prompts/dark/spacebar.png create mode 100644 src/data/ui/prompts/dark/w.png diff --git a/.luarc.json b/.luarc.json index fc3c669..d5e5e33 100644 --- a/.luarc.json +++ b/.luarc.json @@ -4,6 +4,9 @@ "param-type-mismatch", "cast-local-type" ], + "Lua.diagnostics.globals": [ + "pprint" + ], "Lua.runtime.version": "LuaJIT", "Lua.workspace.checkThirdParty": false, "Lua.workspace.library": [ diff --git a/src/data/init.lua b/src/data/init.lua index b1e4ab4..ea08293 100644 --- a/src/data/init.lua +++ b/src/data/init.lua @@ -9,26 +9,31 @@ love.graphics.setDefaultFilter("nearest", "nearest") -- TODO: Maybe add a texture atlas library for packing frame data -- TODO: For production maybe use another type of loader? (https://github.com/elloramir/packer, https://github.com/EngineerSmith/Runtime-TextureAtlas) local function loadAsepriteSprite(filename) - local sprite = {} local ase = aseLoader(filename) - sprite.width = ase.header.width - sprite.height = ase.header.height - sprite.variants = {} - local LAYER_CHUNK = 0x2004 local CEL_CHUNK = 0x2005 local TAG_CHUNK = 0x2018 + local SLICE_CHUNK = 0x2022 + local USER_CHUNK = 0x2020 local frames = {} local tags = {} local layers = {} + local slices = {} love.graphics.push("transform") love.graphics.origin() + local width = ase.header.width + local height = ase.header.height for i, ase_frame in ipairs(ase.header.frames) do - for _, chunk in ipairs(ase_frame.chunks) do + for chunk_i, chunk in ipairs(ase_frame.chunks) do + local user_data = ase_frame.chunks[chunk_i+1] + if user_data and user_data.type ~= USER_CHUNK then + user_data = nil + end + if chunk.type == CEL_CHUNK then local cel = chunk.data local buffer = love.data.decompress("data", "zlib", cel.data) @@ -37,7 +42,7 @@ local function loadAsepriteSprite(filename) local frame = frames[i] if not frame then frame = { - image = love.graphics.newCanvas(sprite.width, sprite.height), + image = love.graphics.newCanvas(width, height), duration = ase_frame.frame_duration / 1000 } frame.image:setFilter("nearest", "nearest") @@ -61,12 +66,29 @@ local function loadAsepriteSprite(filename) end elseif chunk.type == LAYER_CHUNK then table.insert(layers, chunk.data) + elseif chunk.type == SLICE_CHUNK then + local slice_key = chunk.data.keys[1] + table.insert(slices, { + name = chunk.data.name, + x = slice_key.x, + y = slice_key.y, + width = slice_key.width, + height = slice_key.height, + user_data = user_data and user_data.data.text + }) end end end love.graphics.push() + local sprite = { + width = width, + height = height, + slices = slices, + variants = {} + } + for _, tag in pairs(tags) do local variant = {} sprite.variants[tag.name] = variant @@ -76,7 +98,7 @@ local function loadAsepriteSprite(filename) end if not sprite.variants.default then - sprite.variants.default = {frames[1]} + sprite.variants.default = frames end return sprite diff --git a/src/data/maps/main-menu.lua b/src/data/maps/main-menu.lua new file mode 100644 index 0000000..5cb3547 --- /dev/null +++ b/src/data/maps/main-menu.lua @@ -0,0 +1,179 @@ +return { + version = "1.9", + luaversion = "5.1", + tiledversion = "1.9.0", + class = "", + orientation = "orthogonal", + renderorder = "right-down", + width = 16, + height = 9, + tilewidth = 16, + tileheight = 16, + nextlayerid = 5, + nextobjectid = 13, + properties = {}, + tilesets = { + { + name = "roguelike-dungeon", + firstgid = 1, + filename = "../tilesets/roguelike-dungeon.tsx", + exportfilename = "../tilesets/roguelike-dungeon.lua" + } + }, + layers = { + { + type = "tilelayer", + x = 0, + y = 0, + width = 16, + height = 9, + id = 1, + name = "ground", + class = "", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68 + } + }, + { + type = "tilelayer", + x = 0, + y = 0, + width = 16, + height = 9, + id = 3, + name = "decorations", + class = "", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + encoding = "lua", + data = { + 0, 0, 66, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 66, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 119, 119, 119, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0 + } + }, + { + type = "objectgroup", + draworder = "topdown", + id = 2, + name = "metadata", + class = "", + visible = true, + opacity = 1, + offsetx = 0, + offsety = 0, + parallaxx = 1, + parallaxy = 1, + properties = {}, + objects = { + { + id = 2, + name = "Spawnpoint", + class = "", + shape = "point", + x = 140.167, + y = 90.1667, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 6, + name = "title", + class = "", + shape = "rectangle", + x = 128, + y = 16, + width = 96, + height = 48, + rotation = 0, + visible = true, + properties = { + ["sprite"] = "title" + } + }, + { + id = 7, + name = "Host", + class = "button", + shape = "rectangle", + x = 16, + y = 16, + width = 96, + height = 32, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 8, + name = "Join", + class = "button", + shape = "rectangle", + x = 16, + y = 56, + width = 96, + height = 32, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 9, + name = "Quit", + class = "button", + shape = "rectangle", + x = 16, + y = 96, + width = 96, + height = 32, + rotation = 0, + visible = true, + properties = {} + }, + { + id = 12, + name = "controls", + class = "", + shape = "point", + x = 225, + y = 111.667, + width = 0, + height = 0, + rotation = 0, + visible = true, + properties = {} + } + } + } + } +} diff --git a/src/data/maps/main-menu.tmx b/src/data/maps/main-menu.tmx new file mode 100644 index 0000000..666792c --- /dev/null +++ b/src/data/maps/main-menu.tmx @@ -0,0 +1,49 @@ + + + + + + + + +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68, +68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68 + + + + +0,0,66,0,66,0,0,0,0,0,0,0,0,96,0,0, +0,0,66,66,66,66,0,0,0,0,0,0,0,0,0,0, +0,0,0,66,66,66,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,66,66,0, +0,0,0,0,0,0,0,0,0,0,0,0,96,0,66,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,119,119,119,0,0,0,0,0,0, +0,0,0,0,0,0,0,119,0,0,0,0,0,0,0,0 + + + + + + + + + + + + + + + + + + + diff --git a/src/data/sprites/title.aseprite b/src/data/sprites/title.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..2531528653e28c170406f18b21347ff03f1bb486 GIT binary patch literal 1661 zcmcJPdsLEV9LL|ZyljrjwzL8z^TMbjf|hbAT&HZ4I+~$olDSM!j*4mCi(RstHLbK< zQ>kUkv`|x55?+qFvI6gtQBK1WmC8aT)HL>k)3)|Uf9`qD@AE$I!}~tp&+|OzaKHpX zp8RHngd#2o7MX(}$X%#^8;t1(kp*!5AI)Sgf=sK;4XNf3uo%h|Yl!?H?h*8tV6pE< zY(MzL(A6P`9o7xF5k~{E$wXjQ02SE3*AXbczy^*s{Q`VDwgz}^&=<(9a{;>N!~hwQ z1fUL9`?G`XA*Bh9@bJ1~O0dw{Hj)e{^0#*R};11$o4a(pPvS13D;0S_X z2WsF2QeXr+dKaAzEIZ7HgUUM%lvGQ8+q(% zR(W+_jJDo%^Z5b$a!Xp`1TEDs*<08t9w={oTvFEA-|+QF(rSNlM0Ddes}*}MUlH6d zV@7L2IvPUlTXQ;Iy!M=7PPL4Ee!|Vvjlzk)9G_DZTCKHLICMH~rFNYg9-NdZ9F8}2 z+fnjE?j7(|$9j-7-Z29-OAl!;Nt~%rF=C`vBIZ2Eaff{DjMa}TF;>shtugq-H z3{y?A)tw?+i}^B!61}y)-M1=B)y0uK!w(%D3&va(708e8ni<&KA$nCeV&nKGSrz;` zYjEOWN~U?tHwTXC)>GGp&#D?dW7joEdTLM>j!r?jndx3y8{1mWez|C6kd5>OaW+Sb zA1w*h@&oG&1z-0169@W5T^-|$;q4fe`vflcWnjTBzvhxqH>Swht5dR*k4K{kw`$Pp z9hgs!oU^T5%HC9%_I43_kvd*!{@kJBDaI#1dGJYupNdjLlSC!IJe#D7&=R^hZlHZ%vE73Ii(T?XLm^+kiEAY zqgd8%R9+fjCZ*Ye6DB5xCWqgZh#ZgidU}U2dus%xXSYXZYO5N4-;``ibg2x<(iO6KAvha z$d1pBka=*Oh)F)D(;Ne)=~iN{izC@a-k;iQ_! zzeq_Hlyh2cY1y8_Lz=2bOJtb4eaET2TUz&1`f%j6Lh;l{YSS~#zI<6*VdmL2H*W+b Xj6NAEI?K}u$L=&lL=$>q&2Rq&8yt^! literal 0 HcmV?d00001 diff --git a/src/data/ui/prompts/dark/a.png b/src/data/ui/prompts/dark/a.png new file mode 100644 index 0000000000000000000000000000000000000000..3ae68cab48c28f7ac062362ae287d31a680698a4 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF>6_S*0 Sw-*GO#o+1c=d#Wzp$Py+Ycb{k literal 0 HcmV?d00001 diff --git a/src/data/ui/prompts/dark/d.png b/src/data/ui/prompts/dark/d.png new file mode 100644 index 0000000000000000000000000000000000000000..c238b13503a1f0ce90601fcd7cbe6bdf1dbf87c0 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF7 literal 0 HcmV?d00001 diff --git a/src/data/ui/prompts/dark/s.png b/src/data/ui/prompts/dark/s.png new file mode 100644 index 0000000000000000000000000000000000000000..500206c7e88372b017ca7e0ec7d40ea5aa730e2f GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFEX>4Tx04R}tkv&MmKpe$iQ>8^(9PA+CkfDl$g`y&kT7@E12(?114kp)6Xws0R zxHt-~1qVMCs}3&Cx;nTDg5U>;qmz@Oird-(Wz7vovp=l&ewe8FUZPb8jYx?vG-5KnJf zI_G`j2rJ8Z;&bA0gDyz?$aTf#H_j!81)do(GU<8Z2(eh|Vx@~&*-(k6h@*K`qkJLj za-Q=RXSG^q?R)YUh6>usGS_JiBZ);UL4pVcbyQG=g&3_GDJIgipYZSxIev*;3b`s^ zDYDGy0|+FmMa>t+~Cm_i_3FWT>mu4RCM> zjFu>S-Q(TC?%w`A)9&vFonUgfMc42Q00006VoOIv00000008+zyMF)x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru<_HZ94-7~p0+av%02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{003!8L_t(Y$75g^;(!sxaQ2G-Ka?E4ciTcnxCe%shV zf-Dde5XA8K*~>xgXjv(7hIJd(!TC(cl7rpx*xbl8)HCs@2SzVY8+Sg@6|L$(+l r?2gCgMwA#puHi--b98FV4S4_nw7nfHy!i#K00000NkvXXu0mjfxd0Oe literal 0 HcmV?d00001 diff --git a/src/data/ui/prompts/dark/w.png b/src/data/ui/prompts/dark/w.png new file mode 100644 index 0000000000000000000000000000000000000000..46ee0118474dd163808a507837c23146231c9352 GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFgTe~DWM4fJs&iM literal 0 HcmV?d00001 diff --git a/src/groups.lua b/src/groups.lua index 6069bb5..4d1c163 100644 --- a/src/groups.lua +++ b/src/groups.lua @@ -7,6 +7,7 @@ return { }}, controllable_player = {filter = {"controllable"}}, sprite = {filter = {"pos", "sprite"}}, + image = {filter = {"pos", "image"}}, bolt = {filter={"pos", "vel", "bolt"}}, collider = {filter={"collider"}}, ui_button = {filter={"pos", "size", "text"}} diff --git a/src/lib/ase-loader.lua b/src/lib/ase-loader.lua index cc32868..4eae08d 100644 --- a/src/lib/ase-loader.lua +++ b/src/lib/ase-loader.lua @@ -312,9 +312,10 @@ local function grab_user_data(data) user_data.flags = read_num(data, DWORD) - if user_data.flags == 1 then + if bit.band(user_data.flags, 1) > 0 then user_data.text = read_string(data) - elseif user_data.flags == 2 then + end + if bit.band(user_data.flags, 2) > 0 then user_data.colors = read_num(data, BYTE * 4) end @@ -342,6 +343,8 @@ local function grab_chunk(data) chunk.data = grab_slice(data) elseif chunk.type == 0x2020 then chunk.data = grab_user_data(data) + else + error(("Uknown chunk type: 0x%x"):format(chunk.type)) end return chunk diff --git a/src/lib/sti/init.lua b/src/lib/sti/init.lua index 50aec91..8ab07c1 100644 --- a/src/lib/sti/init.lua +++ b/src/lib/sti/init.lua @@ -22,6 +22,8 @@ local lg = require(cwd .. "graphics") local Map = {} Map.__index = Map +local DRAW_OBJECT_LAYERS = false + local function new(map, plugins, ox, oy) local dir = "" @@ -895,6 +897,8 @@ end --- Default draw function for Object Layers -- @param layer The Object Layer to draw function Map:drawObjectLayer(layer) + if not DRAW_OBJECT_LAYERS then return end + if type(layer) == "string" or type(layer) == "number" then layer = self.layers[layer] end @@ -954,7 +958,7 @@ function Map:drawObjectLayer(layer) elseif object.shape == "polyline" then drawShape(object.polyline, "polyline") elseif object.shape == "point" then - -- lg.points(object.x, object.y) + lg.points(object.x, object.y) end end end diff --git a/src/main.lua b/src/main.lua index 257cc57..1d2e839 100644 --- a/src/main.lua +++ b/src/main.lua @@ -1,6 +1,7 @@ local Gamestate = require("lib.hump.gamestate") local binser = require("lib.binser") local Vec = require("lib.brinevector") +pprint = require("lib.pprint") binser.registerStruct("brinevector", function(v) return v.x, v.y end, diff --git a/src/states/main-menu.lua b/src/states/main-menu.lua index 4017f8f..3a9d2ba 100644 --- a/src/states/main-menu.lua +++ b/src/states/main-menu.lua @@ -16,10 +16,19 @@ local function splitat(str, char) return str:sub(1, index-1), str:sub(index+1) end +local function findByName(list, name) + for _, o in ipairs(list) do + if o.name:lower() == name:lower() then + return o + end + end +end + function MainMenu:init() local systems = { require("systems.physics"), require("systems.bolt"), + require("systems.map"), require("systems.ui"), require("systems.player"), require("systems.sprite"), @@ -31,7 +40,10 @@ function MainMenu:init() self.ecs = nata.new{ available_groups = require("groups"), - systems = systems + systems = systems, + data = { + map = "data/maps/main-menu.lua" + } } self.host_socket = enet.host_create("*:0") @@ -40,18 +52,21 @@ function MainMenu:init() self.hosting = false self.connecting = false + local map = self.ecs:getSystem(require("systems.map")).map + local pprint = require("lib.pprint") + local metadata_layer = findByName(map.layers, "metadata") + do + local spawnpoint = findByName(metadata_layer.objects, "spawnpoint") local PlayerSystem = self.ecs:getSystem(require("systems.player")) - local player = PlayerSystem:spawnPlayer(Vec(192, 48)) + local player = PlayerSystem:spawnPlayer(Vec(spawnpoint.x, spawnpoint.y)) player.sprite.flip = true player.controllable = true end do - local tileSize = 16 - local screenW, screenH = love.graphics.getDimensions() - self.screenWidth = 16 * tileSize - self.screenHeight = 16 * screenH/screenW * tileSize + self.screenWidth = map.width * map.tilewidth + self.screenHeight = map.height * map.tileheight local border = 2.5 local w = self.screenWidth @@ -62,6 +77,38 @@ function MainMenu:init() self.ecs:queue{ collider = {0, h-border, w, h} } end + do + local controls_obj = findByName(metadata_layer.objects, "controls") + local pos = Vec(controls_obj.x, controls_obj.y) + + local prompts = data.ui.prompts.dark + self.ecs:queue{ + pos = pos + Vec(0, -16), + image = prompts["w"], + collider = {-8, -8, 8, 8} + } + self.ecs:queue{ + pos = pos, + image = prompts["a"], + collider = {-8, -8, 8, 8} + } + self.ecs:queue{ + pos = pos + Vec(-16, 0), + image = prompts["s"], + collider = {-8, -8, 8, 8} + } + self.ecs:queue{ + pos = pos + Vec(16, 0), + image = prompts["d"], + collider = {-8, -8, 8, 8} + } + self.ecs:queue{ + pos = pos + Vec(0, 16), + image = prompts["spacebar"], + collider = {-24, -8, 24, 8} + } + end + do local host_btn = self.ecs:queue{ pos = Vec(16, 16), @@ -113,19 +160,6 @@ function MainMenu:draw() ScreenScaler:start(self.screenWidth, self.screenHeight) self.ecs:emit("draw") ScreenScaler:finish() - - -- self.ui:textbox(self.addr_textbox, w/2-250, h/2-30, 280, 60) - -- if self.ui:button("Copy my address", w/2-50, h/2-100, 300, 60) then - -- local _, port = splitat(self.host_socket:get_socket_address(), ":") - -- local address = getPublicIP() .. ":" .. port - -- love.system.setClipboardText(address) - -- end - -- if self.ui:button("Connect", w/2+50, h/2-30, 200, 60) then - -- self.connecting = true - -- self.host_socket:connect(self.addr_textbox.text) - -- end - - -- self.ui:postDraw() end return MainMenu diff --git a/src/states/main.lua b/src/states/main.lua index 487b775..09c6c8d 100644 --- a/src/states/main.lua +++ b/src/states/main.lua @@ -25,14 +25,15 @@ function MainState:enter(_, host_socket) available_groups = require("groups"), systems = systems, data = { - host_socket = host_socket + host_socket = host_socket, + map = "data/maps/playground.lua" } } self.downscaled_canvas = nil - self:refreshDownscaledCanvas() + self:refreshScaler() self.ecs:on("onMapSwitch", function(map) - self:refreshDownscaledCanvas(map) + self:refreshScaler(map) end) @@ -42,14 +43,10 @@ function MainState:enter(_, host_socket) player.controllable = true end -function MainState:refreshDownscaledCanvas(map) +function MainState:refreshScaler(map) if not map then local Map = self.ecs:getSystem(require("systems.map")) map = Map.map - if not map then - self.downscaled_canvas = nil - return - end end self.screenWidth = map.width * map.tilewidth diff --git a/src/systems/map.lua b/src/systems/map.lua index 7206043..28a5fe6 100644 --- a/src/systems/map.lua +++ b/src/systems/map.lua @@ -1,27 +1,54 @@ local Map = {} local sti = require("lib.sti") -local Vector = require("lib.brinevector") +local Vec = require("lib.brinevector") function Map:init() - self.map = sti("data/maps/playground.lua", { "bump" }) - self.pool:emit("onMapSwitch", self.map) + if self.pool.data.map then + self.map = sti(self.pool.data.map, { "bump" }) + + local spriteSystem = self.pool:getSystem(require("systems.sprite")) + if spriteSystem then + for _, layer in ipairs(self.map.layers) do + if layer.type == "objectgroup" then + for _, obj in ipairs(layer.objects) do + local props = obj.properties + if props.sprite then + local x = obj.x + obj.width/2 + local y = obj.y + obj.height/2 + self.pool:queue{ + sprite = { name = props.sprite }, + pos = Vec(x, y) + } + end + end + end + end + end + + + self.pool:emit("onMapSwitch", self.map) + end end function Map:update(dt) - self.map:update(dt) + if self.map then + self.map:update(dt) + end end function Map:listSpawnpoints() local points = {} for _, object in ipairs(self.map.layers.spawnpoints.objects) do - table.insert(points, Vector(object.x, object.y)) + table.insert(points, Vec(object.x, object.y)) end return points end function Map:draw() - love.graphics.setColor(1, 1, 1) - self.map:draw() + if self.map then + love.graphics.setColor(1, 1, 1) + self.map:draw() + end end return Map diff --git a/src/systems/sprite.lua b/src/systems/sprite.lua index f49cfc9..ffa604e 100644 --- a/src/systems/sprite.lua +++ b/src/systems/sprite.lua @@ -1,14 +1,31 @@ local data = require("data") local pprint = require("lib.pprint") +local Vec = require("lib.brinevector") local Sprite = {} -Sprite.required_groups = {"sprite"} +Sprite.required_groups = {"sprite", "image"} function Sprite:addToGroup(group, e) - if group ~= "sprite" then return end + if group == "sprite" then + local sprite = data.sprites[e.sprite.name] + assert(sprite, ("Attempt to draw unknown sprite: %s"):format(e.sprite.name)) - local sprite = data.sprites[e.sprite.name] - assert(sprite, ("Attempt to draw unknown sprite: %s"):format(e.sprite.name)) + for _, slice in ipairs(sprite.slices) do + if slice.user_data and slice.user_data:find("collider") then + self.pool:queue{ + pos = e.pos - Vec(sprite.width, sprite.height)/2, + collider = { + slice.x, + slice.y, + slice.x + slice.width, + slice.y + slice.height + } + } + end + end + elseif group == "image" then + assert(e.image:typeOf("Drawable"), ("Expected sprite to be a drawable or aseprite sprite, got: %s"):format(e.image)) + end end function Sprite:update(dt) @@ -40,9 +57,10 @@ function Sprite:draw() if not e.hidden then local variant = sprite.variants[e.sprite.variant or "default"] - if variant and e.sprite.frame then + local frame_idx = e.sprite.frame or 1 + if variant and frame_idx then local rotation = nil - local frame = variant[e.sprite.frame] + local frame = variant[frame_idx] if not frame then frame = variant[1] end @@ -66,6 +84,20 @@ function Sprite:draw() end end end + + for _, e in ipairs(self.pool.groups.image.entities) do + if not e.hidden then + local width, height = e.image:getDimensions() + love.graphics.draw( + e.image, + e.pos.x, + e.pos.y, + 0, + 1, 1, + width/2, height/2 + ) + end + end end return Sprite