From a1bf842cefe0d46692fa075c0e623c8ded181db8 Mon Sep 17 00:00:00 2001 From: lustlion Date: Sat, 29 Jan 2022 08:49:45 +0100 Subject: [PATCH] editor progress, generic keybinds, player coyote value, cursed book entity, level changes, camera adjustments --- assets/entities/cursed_book/attack_loop1.png | Bin 0 -> 118 bytes .../cursed_book/attack_transition1.png | Bin 0 -> 98 bytes .../cursed_book/attack_transition2.png | Bin 0 -> 117 bytes .../cursed_book/attack_transition3.png | Bin 0 -> 111 bytes .../cursed_book/attack_transition4.png | Bin 0 -> 124 bytes .../cursed_book/attack_transition5.png | Bin 0 -> 119 bytes assets/entities/cursed_book/flying1.png | Bin 0 -> 140 bytes assets/entities/cursed_book/flying10.png | Bin 0 -> 146 bytes assets/entities/cursed_book/flying11.png | Bin 0 -> 146 bytes assets/entities/cursed_book/flying2.png | Bin 0 -> 140 bytes assets/entities/cursed_book/flying3.png | Bin 0 -> 146 bytes assets/entities/cursed_book/flying4.png | Bin 0 -> 146 bytes assets/entities/cursed_book/flying5.png | Bin 0 -> 120 bytes assets/entities/cursed_book/flying6.png | Bin 0 -> 143 bytes assets/entities/cursed_book/flying7.png | Bin 0 -> 137 bytes assets/entities/cursed_book/flying8.png | Bin 0 -> 143 bytes assets/entities/cursed_book/flying9.png | Bin 0 -> 120 bytes assets/entities/cursed_book/spawn1.png | Bin 0 -> 99 bytes assets/entities/cursed_book/spawn2.png | Bin 0 -> 120 bytes assets/entities/cursed_book/spawn3.png | Bin 0 -> 123 bytes assets/entities/cursed_book/spawn4.png | Bin 0 -> 126 bytes assets/entities/cursed_book/spawn5.png | Bin 0 -> 134 bytes assets/entities/particle/player_dash1.png | Bin 114 -> 0 bytes .../particle/{fairy1.png => simple1.png} | Bin .../particle/{fairy2.png => simple2.png} | Bin .../particle/{fairy3.png => simple3.png} | Bin .../particle/{fairy4.png => simple4.png} | Bin data/scripts/camera.lua | 4 +- data/scripts/debug.lua | 24 ++-- data/scripts/editor.lua | 77 ++++++------ data/scripts/entities/cursed_book.lua | 118 ++++++++++++++++++ data/scripts/entities/fairy.lua | 43 ++++--- data/scripts/entities/particle.lua | 39 ++++-- data/scripts/entities/player.lua | 62 +++++---- data/scripts/entity.lua | 28 ++++- data/scripts/enums.lua | 31 +++-- data/scripts/game.lua | 2 +- data/scripts/keybind.lua | 5 + data/scripts/level.lua | 93 ++++++++------ data/scripts/lights.lua | 6 +- main.lua | 9 +- 41 files changed, 387 insertions(+), 154 deletions(-) create mode 100644 assets/entities/cursed_book/attack_loop1.png create mode 100644 assets/entities/cursed_book/attack_transition1.png create mode 100644 assets/entities/cursed_book/attack_transition2.png create mode 100644 assets/entities/cursed_book/attack_transition3.png create mode 100644 assets/entities/cursed_book/attack_transition4.png create mode 100644 assets/entities/cursed_book/attack_transition5.png create mode 100644 assets/entities/cursed_book/flying1.png create mode 100644 assets/entities/cursed_book/flying10.png create mode 100644 assets/entities/cursed_book/flying11.png create mode 100644 assets/entities/cursed_book/flying2.png create mode 100644 assets/entities/cursed_book/flying3.png create mode 100644 assets/entities/cursed_book/flying4.png create mode 100644 assets/entities/cursed_book/flying5.png create mode 100644 assets/entities/cursed_book/flying6.png create mode 100644 assets/entities/cursed_book/flying7.png create mode 100644 assets/entities/cursed_book/flying8.png create mode 100644 assets/entities/cursed_book/flying9.png create mode 100644 assets/entities/cursed_book/spawn1.png create mode 100644 assets/entities/cursed_book/spawn2.png create mode 100644 assets/entities/cursed_book/spawn3.png create mode 100644 assets/entities/cursed_book/spawn4.png create mode 100644 assets/entities/cursed_book/spawn5.png delete mode 100644 assets/entities/particle/player_dash1.png rename assets/entities/particle/{fairy1.png => simple1.png} (100%) rename assets/entities/particle/{fairy2.png => simple2.png} (100%) rename assets/entities/particle/{fairy3.png => simple3.png} (100%) rename assets/entities/particle/{fairy4.png => simple4.png} (100%) create mode 100644 data/scripts/entities/cursed_book.lua diff --git a/assets/entities/cursed_book/attack_loop1.png b/assets/entities/cursed_book/attack_loop1.png new file mode 100644 index 0000000000000000000000000000000000000000..048ac719b43d3975eae68bb69be7c920752a646c GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^96-#@!3HEvBYEP06k~CayA#8@b22Z190N}m#}JO0 z$tev@_2QEM4&U(k#nWS8ro2mKmy%n~q!V2qv<_smb}`kwOK=f8@JyKDUyI0+>Wj0c Q0`)R@y85}Sb4q9e0H$9f*Z=?k literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/attack_transition1.png b/assets/entities/cursed_book/attack_transition1.png new file mode 100644 index 0000000000000000000000000000000000000000..9facd06d04ee586a65896cbcbe233a92cc0aacaa GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ;0V1_0*t`W&jKx9jP7LeL$-D$|WISCQLpWw8 uCp0wGi%b6dzx%`o`D5ux2N>Bxm>8ydv95ewW*!Dq$KdJe=d#Wzp$PyzcN(Yw literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/attack_transition2.png b/assets/entities/cursed_book/attack_transition2.png new file mode 100644 index 0000000000000000000000000000000000000000..905367cc003d34b9e3ae56551967f03edadf14b6 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ;0V1_0*t`W&jKx9jP7LeL$-D$|^gUf1LpWw8 zCp0wGi%b6dzx%`o`D5ux4$KCgJe+f^W_*#9cqnut?eUdHCC1BrJPfxUaIbvzLm&&N OmBG{1&t;ucLK6Ve&m=kk literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/attack_transition3.png b/assets/entities/cursed_book/attack_transition3.png new file mode 100644 index 0000000000000000000000000000000000000000..a48d879d42fd519662c701d22300753e3675bec8 GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ;0V1_0*t`W&jKx9jP7LeL$-D$|G(BA$LpWw8 zCp0wGi%b6dzx%`o`D5uVoJI7 UQBqyaKob}|UHx3vIVCg!0IE|Zb^rhX literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/attack_transition5.png b/assets/entities/cursed_book/attack_transition5.png new file mode 100644 index 0000000000000000000000000000000000000000..d0a9e87708902d2fb1aebabe4e883e9b52e9b2ba GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ;0V1_0*t`W&jKx9jP7LeL$-D$|3_V>OLpWw8 zCjh~Z@`(@s@9*aMFFAoh*@r1|g6I6kiGr~LdY!%k>skD)140yc^D)G272$i_`uQkO OGlQqApUXO@geCyh_##;V literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/flying1.png b/assets/entities/cursed_book/flying1.png new file mode 100644 index 0000000000000000000000000000000000000000..2d924b4281e3a7c3809a97ac0f6302a943e35060 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CN!3HF~3v%Lt6k~CayA#8@b22Z195+uF#}JK) z$te!Z|MiUixIZ&~X>71)wPW}nc{T|NiGPcw8QA~pzx71)wPW}nc{T|NiGPcw8QA~pzxd}!|}B_Uy8`sY8tU{XrTkqZZyuC^>>Kj|QHz@@AB#o|N(CWaq8?6(ic SwORmmGkCiCxvXM6N{>etpppS|4vSd2l? rzkSL4{5itK8#Io*5-k74{5MDaFz+2fwS8}ahBA1%`njxgN@xNAbp|mU literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/flying7.png b/assets/entities/cursed_book/flying7.png new file mode 100644 index 0000000000000000000000000000000000000000..ad457995d88b9adbca55e8ad0230d258955168b0 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CN!3HF~3v%Lt6k~CayA#8@b22Z19A{4##}JK) z$q5p39^7|r`~P3h=#RSFJVC8*@>&NEfWQ)d!FJ80OYN^yQ&JpQUr0UV`e^mhUL;|1 h@}bqm4kiM6N{>etpppS|4vSd2l? rzkSL4{5itK8#Io*5-k74{5MDaFz+2fwS8}ahBA1%`njxgN@xNAbp|mU literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/flying9.png b/assets/entities/cursed_book/flying9.png new file mode 100644 index 0000000000000000000000000000000000000000..c9dcb7f00d1728538fddf69b471d01ed11b2a9e9 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CN!3HF~3v%Lt6k~CayA#8@b22Z193xK`#}JK) z$q5Tg6aJJ>d}!|}B_Uy8`sY8tU{XrTkqZZyuC^>>Kj|QHz@@AB#o|N(CWaq8?6(ic SwORmmGkCiCxvXvHwD7n7ai^or8y_Zpnag3Xka1AgV(%e+-5(S5&$G8}+uN?9zS_I;3)9C( W;#ReacCJ7J7(8A5T-G@yGywn@ASYu0 literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/spawn4.png b/assets/entities/cursed_book/spawn4.png new file mode 100644 index 0000000000000000000000000000000000000000..e5e28eaa2eed1db93f409cbe90fe1e6f4113a494 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^96-#*!3HG%vEKg;q!^2X+?^QKos)S9td2YQ~buN5%6+!Z@@^2@|L Z=5u^H2NR{YUIm)L;OXk;vd$@?2>^>ODUkpG literal 0 HcmV?d00001 diff --git a/assets/entities/cursed_book/spawn5.png b/assets/entities/cursed_book/spawn5.png new file mode 100644 index 0000000000000000000000000000000000000000..e71d7a052524cd05d9941625c9740bda5a57c79a GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^96-#*!3HG%vEKg;q!^2X+?^QKos)S9x50sj`Jg9P)4$UVO?oyB!6hDV^gkWr<9{3=wUgUBLVv~2fahU%+=WXr!}OU# hE^XWA@~`CqQ^y~jpbM2exj?fRJYD@<);T3K0RZe*EPen0 literal 0 HcmV?d00001 diff --git a/assets/entities/particle/player_dash1.png b/assets/entities/particle/player_dash1.png deleted file mode 100644 index 659fa23b0265ed2671ee6150b276dbfc30451511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^%s|Y^!3HG1Z=QA&NHG=%xjQkeJ16rJ$kFk1aSY*@ znVfLp|M&Tgjg5?c#(%8&6aOS%_}}ki{Ac%xhEoRw4qRb2=e;S%aD0W5Ve;p#lYsgd NJYD@<);T3K0RTB#CY%5O diff --git a/assets/entities/particle/fairy1.png b/assets/entities/particle/simple1.png similarity index 100% rename from assets/entities/particle/fairy1.png rename to assets/entities/particle/simple1.png diff --git a/assets/entities/particle/fairy2.png b/assets/entities/particle/simple2.png similarity index 100% rename from assets/entities/particle/fairy2.png rename to assets/entities/particle/simple2.png diff --git a/assets/entities/particle/fairy3.png b/assets/entities/particle/simple3.png similarity index 100% rename from assets/entities/particle/fairy3.png rename to assets/entities/particle/simple3.png diff --git a/assets/entities/particle/fairy4.png b/assets/entities/particle/simple4.png similarity index 100% rename from assets/entities/particle/fairy4.png rename to assets/entities/particle/simple4.png diff --git a/data/scripts/camera.lua b/data/scripts/camera.lua index c0cf5d0..4062cd2 100644 --- a/data/scripts/camera.lua +++ b/data/scripts/camera.lua @@ -20,6 +20,6 @@ function Camera:positionCenterAt(x,y,cx,cy) end function Camera:positionAt(x,y) - self.pos.x = math.floor(x/self.width)*self.width - self.pos.y = math.floor(y/self.height)*self.height + self.pos.x = math.floor((x/self.width)*self.width) + self.pos.y = math.floor((y/self.height)*self.height) end diff --git a/data/scripts/debug.lua b/data/scripts/debug.lua index 0ba7348..60a30e0 100644 --- a/data/scripts/debug.lua +++ b/data/scripts/debug.lua @@ -1,5 +1,7 @@ function DebugUI() +local mouse_x, mouse_y = love.mouse.getPosition() + for _, light in pairs(Lights) do love.graphics.print(light.pos.x,light.pos.x,light.pos.y) love.graphics.print(light.pos.y,light.pos.x,light.pos.y+20) @@ -15,11 +17,15 @@ end love.graphics.print("velocity: {"..main_Player.vel.x..", "..main_Player.vel.y.."}",10*textScale,80*textScale, 0, textScale) love.graphics.print("scale: {"..main_Player.sprite_scale.x..", "..main_Player.sprite_scale.y.."}",10*textScale,100*textScale, 0, textScale) love.graphics.print("states: \"isOnGround\": "..tostring(main_Player.isOnGround),10*textScale,120*textScale, 0, textScale) + love.graphics.print("\"coyoteValue\": "..tostring(main_Player.coyoteValue),10*textScale,140*textScale, 0, textScale) love.graphics.print("[Camera]",10*textScale,160*textScale, 0, textScale) love.graphics.print("position: {"..Camera.pos.x..", "..Camera.pos.y.."}",10*textScale,180*textScale, 0, textScale) love.graphics.print("size: {"..Camera.width..", "..Camera.height.."}",10*textScale,200*textScale, 0, textScale) + love.graphics.print("[Cursor]",10*textScale,220*textScale, 0, textScale) + love.graphics.print("position: {"..mouse_x+Camera.pos.x..", "..mouse_y+Camera.pos.y.."}",10*textScale,240*textScale, 0, textScale) + love.graphics.print(textScale,10*textScale,240*textScale, 0, textScale) love.graphics.print("Level: "..levelNum.." / "..#levelList.." \""..currLevel.."\"",10*textScale,260*textScale, 0, textScale) @@ -33,23 +39,9 @@ end function DebugEntities() for _, particle in pairs(LoadedParticles) do - -- draw center CYAN - love.graphics.setColor(0,1,1) - love.graphics.circle("fill", -Camera.pos.x + particle.pos.x, -Camera.pos.y + particle.pos.y, 1) - + particle:Debug() end for _, enty in pairs(LoadedEntities) do - -- draw center GREEN - love.graphics.setColor(0,1,0) - love.graphics.circle("fill", -Camera.pos.x + enty.pos.x, -Camera.pos.y + enty.pos.y, 1) - -- draw collision box PURPLE - love.graphics.setColor(1,0,1) - love.graphics.rectangle( - "line", - -Camera.pos.x + enty.pos.x + enty.boxCollision.from.x, - -Camera.pos.y + enty.pos.y + enty.boxCollision.from.y, - -Camera.pos.x + enty.pos.x + enty.boxCollision.to.x -(-Camera.pos.x + enty.pos.x + enty.boxCollision.from.x), - -Camera.pos.y + enty.pos.y + enty.boxCollision.to.y -(-Camera.pos.y + enty.pos.y + enty.boxCollision.from.y) - ) + enty:Debug() end end diff --git a/data/scripts/editor.lua b/data/scripts/editor.lua index ddf7cb4..eebd94b 100644 --- a/data/scripts/editor.lua +++ b/data/scripts/editor.lua @@ -46,6 +46,7 @@ function EditorDraw() GridDisplay() GameworldDrawForeground() GameworldDrawEnd() + EditorDoEdit() DrawSelectingPaletteTile() if palette then @@ -54,35 +55,39 @@ function EditorDraw() end function EditorDoEdit() - if love.mouse.isDown(1) then - local vertical = 1+math.floor((mouse.pos.y+Camera.pos.y)/(tileProperties.scale*tileProperties.height)) - local horizontal = 1+math.floor((mouse.pos.x+Camera.pos.x)/(tileProperties.scale*tileProperties.width)) - local h, v = GetCanvasSize() + local mouse_x = love.mouse.getX() + local mouse_y = love.mouse.getY() + local horizontal = 1 + math.floor(((mouse_x/game.scale) / tileProperties.width) + (Camera.pos.x / tileProperties.width)) + local vertical = 1 + math.floor(((mouse_y/game.scale) / tileProperties.height) + (Camera.pos.y / tileProperties.height)) + local expand_h = 0 + local expand_v = 0 + local LevelWidth = LevelGetTileWidth() + local LevelHeight = LevelGetTileHeight() - local expand_h = 0 - local expand_v = 0 + if horizontal > LevelWidth then + expand_h = horizontal-LevelWidth + elseif horizontal < 0 then + expand_h = horizontal + end + if vertical > LevelHeight then + expand_v = vertical-LevelHeight + elseif vertical < 0 then + expand_v = vertical + end + love.graphics.print("> " .. horizontal .. ", " .. vertical) + love.graphics.print("> " .. LevelWidth .. "(" .. expand_h .. "), " .. LevelHeight .. "(".. expand_v .. ")", 0, 10) - if horizontal > h then - expand_h = horizontal-h - elseif horizontal <= 0 then - expand_h = horizontal-1 - end - - if vertical > v then - expand_v = math.sign(vertical-v) - elseif vertical <= 0 then - expand_v = math.sign(vertical-1) - end - - if Level[vertical] ~= nil - and Level[vertical][horizontal] ~= nil + if Keybind:HasPressed(Keybind.generic.lclick) and not palette then + if LevelTiles[vertical] ~= nil + and LevelTiles[vertical][horizontal] ~= nil and love.keyboard.isDown("lshift") ~= true and love.keyboard.isDown("lctrl") ~= true + and selecting_tile ~= nil then - Level[vertical][horizontal] = tile_carrying - elseif love.keyboard.isDown("lshift") and not expanded then - expanded = true - ExpandCanvas(math.sign(expand_h),math.sign(expand_v)) + InstanceTile(vertical,horizontal,selecting_tile) + --[[ + elseif love.keyboard.isDown("lshift") then + --ExpandCanvas(math.sign(expand_h),math.sign(expand_v)) if expand_h < 0 then Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width @@ -91,24 +96,22 @@ function EditorDoEdit() Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height end - elseif love.keyboard.isDown("lctrl") and not expanded then - expanded = true - ReduceCanvas(math.sign(expand_h),math.sign(expand_v)) + elseif love.keyboard.isDown("lctrl") then + --ReduceCanvas(math.sign(expand_h),math.sign(expand_v)) if expand_h < 0 then Camera.pos.x = Camera.pos.x - expand_h*tileProperties.scale*tileProperties.width end if expand_v < 0 then Camera.pos.y = Camera.pos.y - expand_v*tileProperties.scale*tileProperties.height - end + end]] end - elseif love.mouse.isDown(1) ~= true then - expanded = false + LevelReloadTiles() end end function DrawSelectingPaletteTile() - if selecting_tile ~= nil then + if selecting_tile ~= nil and selecting_tile ~= 0 then local mouse_x = tileProperties.width * math.floor((love.mouse.getX()/game.scale) / tileProperties.width) - Camera.pos.x % tileProperties.width local mouse_y = tileProperties.height * math.floor((love.mouse.getY()/game.scale) / tileProperties.height) - Camera.pos.y % tileProperties.height @@ -154,7 +157,7 @@ function EditorDoPalette() 1, 1 ) - if love.mouse.isDown(1) then + if Keybind:CheckDown(Keybind.generic.lclick) then local mouse_x = love.mouse.getX() local mouse_y = love.mouse.getY() @@ -165,13 +168,15 @@ function EditorDoPalette() then selecting_tile = position_x + ((position_y-1) * width) - love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y) - else - --selecting_tile = nil + love.graphics.print(selecting_tile .. " | " .. tile_x .. ", " .. tile_y, 0, 20) end end - if selecting_tile ~= nil and i == selecting_tile then + if Keybind:CheckDown(Keybind.generic.rclick) then + selecting_tile = 0 + end + + if selecting_tile ~= nil and selecting_tile ~= 0 and i == selecting_tile then love.graphics.setColor(1,0,1,1) love.graphics.rectangle( "line", diff --git a/data/scripts/entities/cursed_book.lua b/data/scripts/entities/cursed_book.lua new file mode 100644 index 0000000..40d527a --- /dev/null +++ b/data/scripts/entities/cursed_book.lua @@ -0,0 +1,118 @@ +CursedBook = Entity:New(x,y) + + function CursedBook:New(x,y) + local o = Entity:New(x,y) + + -- behaviour + o.pos = {x = x, y = y} + o.speed = 0.01 + o.range = 20 + o.target = {x = x, y = y} + + o.status = 0 + -- 0 - sleep + -- 1 - getting up + -- 2 - flying + -- 3 - attack windup + -- 4 - attack + o.spawn_range = 100 + o.attack_range = 50 + + -- animations + o.body = Animation:New(animation.cursed_book.spawn) + o.sprite_tint = {0.7,0.7,0.7} + o:centerOffset(o.body) + o:getBoundingBox(o.body) + + -- light + o.light_range = 500 + o.light = CreateLight(o.pos.x,o.pos.y,o.light_range,2,HEX2RGB("#fe00d1")) + + table.insert(LoadedEntities,o) + o.id = #LoadedEntities + + setmetatable(o, self) + self.__index = self + return o + end + +function CursedBook:Smart() + self.target.x = main_Player.pos.x - main_Player.target_offset.x + self.target.y = main_Player.pos.y - main_Player.target_offset.y + local distance_x = self.target.x - self.pos.x + local distance_y = self.target.y - self.pos.y + local angle = GetAngleFromVector(distance_x,distance_y) + local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) + + if self.status == 0 then + if distance < self.spawn_range then + self.status = 1 + end + elseif self.status == -1 then + if distance < self.range then + self.vel.x = 0 + self.vel.y = 0 + else + self.vel.x = math.cos(angle)*self.speed*distance + self.vel.y = math.sin(angle)*self.speed*distance + end + elseif self.status == 2 then + if distance < self.attack_range then + self.status = 3 + end + elseif self.status == 4 then + + end +end + +function CursedBook:HandleAnimation() + if self.status == 1 then + if self.body.path == "assets/entities/cursed_book/spawn" then + self.body.speed = 1/3 + local tint = 0.7 + 0.3 * (self.body.frame-1)/self.body.frames + self.sprite_tint = {tint,tint,tint} + if self.body.frame == self.body.frames then + self.status = 2 + self.body = self.body:ChangeTo(animation.cursed_book.flying) + self.sprite_tint = {1,1,1} + --self:getBoundingBox(self.body,2,2,-2,-2) + self:centerOffset(self.body) + end + end + elseif self.status == 3 then + if self.body.path == "assets/entities/cursed_book/flying" then + self.body = self.body:ChangeTo(animation.cursed_book.attack_transition) + self.body.speed = 1/3 + self:centerOffset(self.body) + if self.body.frame == self.body.frames then + self.status = 4 + self.body = self.body:ChangeTo(animation.cursed_book.attack_loop) + self:centerOffset(self.body) + end + end + end + self.body:Animate() + self:Draw(self.body) +end + +function CursedBook:DoPhysics() + if self.isFlying then + local random_x = math.random(-4, 4)/100 + local random_y = math.random(-4, 4)/100 + self.vel.x = self.vel.x + random_x + self.vel.y = self.vel.y + random_y + end + -- move + + self:CollisionMove() + self:LightAdjust() +end + +function CursedBook:Debug() + -- draw center GREEN + love.graphics.setColor(0,1,0) + love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.spawn_range) + love.graphics.setColor(1,0,0) + love.graphics.circle("line", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, self.attack_range) + Entity.Debug(self) +end diff --git a/data/scripts/entities/fairy.lua b/data/scripts/entities/fairy.lua index 39a36b9..d886baf 100644 --- a/data/scripts/entities/fairy.lua +++ b/data/scripts/entities/fairy.lua @@ -3,6 +3,7 @@ Fairy = Entity:New(x,y) function Fairy:New(x,y) local o = Entity:New(x,y) + -- behaviour o.pos = {x = x, y = y} o.speed = 0.23 o.range = 20 @@ -13,9 +14,13 @@ Fairy = Entity:New(x,y) o:centerOffset(o.body) o:getBoundingBox(o.body) + -- light + o.light_range = 80 + o.light = CreateLight(o.pos.x,o.pos.y,o.light_range,nil,HEX2RGB("#fed100")) - o.lightRange = 0 - o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) + -- timer + o.particle_timer = 0 + o.particle_time = 5 table.insert(LoadedEntities,o) o.id = #LoadedEntities @@ -26,8 +31,6 @@ Fairy = Entity:New(x,y) end function Fairy:Smart() - self.light.pos.x = self.pos.x-self.target_offset.x - self.light.pos.y = self.pos.y-self.target_offset.y self.target.x = main_Player.pos.x - main_Player.target_offset.x self.target.y = main_Player.pos.y - main_Player.target_offset.y - 10 @@ -39,18 +42,27 @@ function Fairy:Smart() self.vel.x = 0 self.vel.y = 0 else - self.vel.x = math.cos(angle)*self.speed*distance/(8*game.scale) - self.vel.y = math.sin(angle)*self.speed*distance/(8*game.scale) + self.vel.x = math.cos(angle)*self.speed*distance/8 + self.vel.y = math.sin(angle)*self.speed*distance/8 + end + self.particle_timer = self.particle_timer + 1 + if self.particle_timer >= self.particle_time then + self.particle_timer = 0 - local particle_data = { - animation = animation.particle.fairy, - direction = angle-math.rad(180), - speed = self.speed*distance/(16*game.scale), - light = 85 - } - - Particle:New(self.pos.x,self.pos.y,particle_data) + local particle_data = { + animation = animation.particle.simple, + sprite_tint = HEX2RGB("#fe00d1"), + direction = angle-math.rad(180+math.random(60)-30), + speed = 0.8*(distance/50), + speed_increase = -0.01, + } + Particle:New( + self.pos.x, + self.pos.y, + particle_data + ) + end end function Fairy:HandleAnimation() @@ -60,11 +72,12 @@ function Fairy:HandleAnimation() end function Fairy:DoPhysics() - local random_x = math.random(-4, 4)/100 local random_y = math.random(-4, 4)/100 self.vel.x = self.vel.x + random_x self.vel.y = self.vel.y + random_y -- move + self:CollisionMove() + self:LightAdjust() end diff --git a/data/scripts/entities/particle.lua b/data/scripts/entities/particle.lua index efc3e59..4784417 100644 --- a/data/scripts/entities/particle.lua +++ b/data/scripts/entities/particle.lua @@ -26,16 +26,23 @@ Particle = Entity:New(x,y) y = o.speed * math.sin(o.direction) } + o.speed_increase = particle_data.speed_increase or 0 + if particle_data.light ~= nil then o.lightRange = particle_data.light - o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) + local flicker = particle_data.light_flicker or nil + local color = particle_data.light_color or nil + o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange,flicker,color) end -- animations - o.body = Animation:New(particle_data.animation) - o:centerOffset(o.body) - if not o.animation_active then - o.body.speed = 0 + if particle_data.animation ~= nil then + o.body = Animation:New(particle_data.animation) + o:centerOffset(o.body) + o:getBoundingBox(o.body) + if not o.animation_active then + o.body.speed = 0 + end end table.insert(LoadedParticles,o) @@ -62,16 +69,32 @@ function Particle:Kill() end function Particle:HandleAnimation() - self.body:Animate() self.timer = self.timer + current_dt self.sprite_alpha = self.sprite_alpha_base*(self.time-self.timer)/self.time if self.light ~= nil then + self:LightAdjust() self.light.range = self.lightRange * self.sprite_alpha/2 end if self.sprite_alpha < 0 then self:Kill() end - self:Draw(self.body) + if self.body ~= nil then + self.body:Animate() + self:Draw(self.body) + end end function Particle:DoPhysics() - self:Move() + -- adjust speed + if self.speed_increase ~= 0 then + self.speed = self.speed + self.speed_increase + self.vel.x = self.speed * math.cos(self.direction) + self.vel.y = self.speed * math.sin(self.direction) + end + -- move + self:CollisionMove() +end + +function Particle:Debug() + -- draw center CYAN + love.graphics.setColor(0,1,1) + love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1) end diff --git a/data/scripts/entities/player.lua b/data/scripts/entities/player.lua index b6e129f..aa07b2c 100644 --- a/data/scripts/entities/player.lua +++ b/data/scripts/entities/player.lua @@ -7,37 +7,40 @@ Player.coins = 0 -- physics - o.moveSpeed = 1.3 - o.zeroSpeed = 0.01 - o.move_x = 0 + o.moveSpeed = 1.3 -- gameworld pixels + o.zeroSpeed = 0.01 -- gameworld pixels + o.move_x = 0 -- gameworld pixels - o.airFriction = 0.01 - o.groundFriction = 0.3 + o.airFriction = 0.01 -- gameworld pixels + o.groundFriction = 0.3 -- gameworld pixels - o.jumpImpulse = 3.5 + o.jumpImpulse = 3.5 -- gameworld pixels - o.dashCooldownTime = 0.1 - o.dashCooldownTimer = 0 + o.coyoteAmount = 5 -- int + o.coyoteValue = 5 -- frames - o.dashTimer = 0 - o.dashTime = 0.15 - o.dashDistance = 40 - o.dashSpeed = o.dashDistance / (o.dashTime*60) - o.dashCount = 1 + o.dashCooldownTime = 0.1 -- seconds + o.dashCooldownTimer = 0 -- seconds + + o.dashTimer = 0 -- seconds + o.dashTime = 0.15 -- seconds + o.dashDistance = 40 -- gameworld pixels + o.dashSpeed = o.dashDistance / (o.dashTime*60) -- pixels + o.dashCount = 1 -- int + o.dashAmount = 0 -- int o.boxCollision = { - from = {x = -8, y = -16}, - to = {x = 8, y = 0} + from = {x = -8, y = -16}, --gameworld pixels + to = {x = 8, y = 0} -- gameworld pixels } - o.lightRange = 0--32 + o.lightRange = 344 -- screen pixels -- status o.isDashing = false o.isJumping = false - o.isOnGround = 0 - o.coyoteValue = 5 - o.isOnLadder = false + o.isOnGround = true + o.isOnLadder = false o.canJump = true o.canFall = true o.canFriction = true @@ -48,7 +51,7 @@ o.body = Animation:New(animation.nancy.idle) o.mask = Animation:New(animation.moth_mask.idle) o:centerOffset(o.body) - o:getBoundingBox(o.body, 3,-3,0,-1) + o:getBoundingBox(o.body,0,3,-1,-3) -- lights o.light = CreateLight(o.pos.x,o.pos.y,o.lightRange) @@ -85,12 +88,19 @@ function Player:Smart() self.vel.x = self.vel.x if Keybind:CheckDown(Keybind.move.jump) then - if self.isOnGround then + if self.coyoteValue > 0 then self.vel.y = -self.jumpImpulse + self.coyoteValue = 0 end end end + if self.isOnGround then + self.coyoteValue = self.coyoteAmount + elseif self.coyoteValue > 0 then + self.coyoteValue = self.coyoteValue - 1 + end + self.dashCooldownTimer = math.max(0,self.dashCooldownTimer - current_dt) if Keybind:CheckDown(Keybind.move.dash) then if self.dashCooldownTimer == 0 @@ -118,14 +128,14 @@ function Player:Smart() end function Player:DoPhysics() - + -- reset state self.isOnGround = false - + -- adjust timers self.dashTimer = self.dashTimer - current_dt -- DASH STATE if self.dashTimer > 0 then - + -- dash particle local particle_data = { animation = self.body, sprite_tint = HEX2RGB("#fed100"), @@ -137,9 +147,11 @@ function Player:DoPhysics() } Particle:New(self.pos.x,self.pos.y,particle_data) self.dashCooldownTimer = self.dashCooldownTime + -- dash movement self.vel.x = self.dashSpeed * math.cos(self.dashDirection) self.vel.y = self.dashSpeed * math.sin(self.dashDirection) else + -- not in dash; fall normally self.dashTimer = 0 self.vel.y = self.vel.y + gravity end @@ -155,7 +167,7 @@ function Player:DoPhysics() else if self.vel.y > 0 then self.isOnGround = true - self.dashCount = 1 + self.dashCount = self.dashAmount self.vel.y = 0 end end diff --git a/data/scripts/entity.lua b/data/scripts/entity.lua index d24c7a5..abc171b 100644 --- a/data/scripts/entity.lua +++ b/data/scripts/entity.lua @@ -39,9 +39,20 @@ end function Entity:CollisionMove() if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then self.pos.x = self.pos.x + self.vel.x + else + self.vel.x = 0 end if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then self.pos.y = self.pos.y + self.vel.y + else + self.vel.y = 0 + end +end + +function Entity:LightAdjust() + if self.light ~= nil then + self.light.pos.x = self.pos.x + self.light.pos.y = self.pos.y end end @@ -80,7 +91,7 @@ function Entity:centerOffset(animation,x,y) self.sprite_offset.y = animation.imgs[1]:getHeight()/2 + y end -function Entity:getBoundingBox(animation,left,right,top,bottom) +function Entity:getBoundingBox(animation,top,left,bottom,right) local left = left or 0 local right = right or 0 local top = top or 0 @@ -125,9 +136,24 @@ function Entity:isCollidingAtAll(x,y) return result end +function Entity:Debug() + -- draw center GREEN + love.graphics.setColor(0,1,0) + love.graphics.circle("fill", -Camera.pos.x + self.pos.x, -Camera.pos.y + self.pos.y, 1) + -- draw collision box PURPLE + love.graphics.setColor(1,0,1) + love.graphics.rectangle( + "line", + -Camera.pos.x + self.pos.x + self.boxCollision.from.x, + -Camera.pos.y + self.pos.y + self.boxCollision.from.y, + -Camera.pos.x + self.pos.x + self.boxCollision.to.x -(-Camera.pos.x + self.pos.x + self.boxCollision.from.x), + -Camera.pos.y + self.pos.y + self.boxCollision.to.y -(-Camera.pos.y + self.pos.y + self.boxCollision.from.y) + ) +end require "data/scripts/entities/kupo" require "data/scripts/entities/arrow" require "data/scripts/entities/decoration" require "data/scripts/entities/player" require "data/scripts/entities/fairy" +require "data/scripts/entities/cursed_book" require "data/scripts/entities/particle" diff --git a/data/scripts/enums.lua b/data/scripts/enums.lua index 9c6d35d..e70546d 100644 --- a/data/scripts/enums.lua +++ b/data/scripts/enums.lua @@ -1,16 +1,33 @@ -- animationsç -- all these are linear animations, maybe in the future make proper animations? animation = { + cursed_book = { + attack_loop = { + path = "assets/entities/cursed_book/attack_loop", + frames = 1, + speed = 0 + }, + attack_transition = { + path = "assets/entities/cursed_book/attack_transition", + frames = 5, + speed = 1/16 + }, + flying = { + path = "assets/entities/cursed_book/flying", + frames = 11, + speed = 1/16 + }, + spawn = { + path = "assets/entities/cursed_book/spawn", + frames = 5, + speed = 0 + } + }, particle = { - fairy = { - path = "assets/entities/particle/fairy", + simple = { + path = "assets/entities/particle/simple", frames = 4, speed = 1/4 - }, - player_dash = { - path = "assets/entities/particle/player_dash", - frames = 1, - speed = 0 } }, fairy = { diff --git a/data/scripts/game.lua b/data/scripts/game.lua index a245946..9ba6300 100644 --- a/data/scripts/game.lua +++ b/data/scripts/game.lua @@ -18,8 +18,8 @@ end function GameDraw() GameworldDrawPrepare() - GameworldDrawBackground() GameworldDrawParticles() + GameworldDrawBackground() GameworldDrawEntities() GameworldDrawForeground() GameworldDrawEnd() diff --git a/data/scripts/keybind.lua b/data/scripts/keybind.lua index 638064e..e069262 100644 --- a/data/scripts/keybind.lua +++ b/data/scripts/keybind.lua @@ -3,6 +3,7 @@ Keybind.move = {} Keybind.menu = {} Keybind.debug = {} Keybind.editor = {} +Keybind.generic = {} function Keybind:CheckDown(action) for _, keyname in pairs(action.keys) do @@ -66,6 +67,10 @@ function Keybind:Default() Keybind.debug.editor = { keys = {"f4"}} -- Editor Keybind.editor.palette = { keys = {"tab"}} + + -- Generic + Keybind.generic.lclick = { keys = {1}} + Keybind.generic.rclick = { keys = {2}} end -- Set default values at start diff --git a/data/scripts/level.lua b/data/scripts/level.lua index 34e5ca1..db16e30 100644 --- a/data/scripts/level.lua +++ b/data/scripts/level.lua @@ -1,39 +1,54 @@ function LevelLoadTiles() + + LevelData = dofile("Mothback/data/levels/"..currLevel..".lua") + + -- tiles data + TileData = dofile("Mothback/data/tileset/library.lua") + --[[ on level format: id = tile identifier depth = order in the render force = rendering other tile instead of the one in this position - overlay = render another tile id or, if multiple tiles {id, id, id,} or + overlay = render another tile id or, if multiple tiles {id, id, id,}, choose at random overlay_depth = foreground/background overlay depth type = collision type ]] - - - -- Level data - LevelData = dofile("Mothback/data/levels/"..currLevel..".lua") - - -- tiles data - TileData = dofile("Mothback/data/tileset/library.lua") - LevelTiles = LevelData.tiles - LevelData.Width = LevelGetWidth() - LevelData.Height = LevelGetHeight() + LevelUpdateDimensions() LevelIndexTiles() TileCreateObjects() end -function LevelGetHeight() - return #LevelTiles * tileProperties.height +function LevelReloadTiles() + LevelUpdateDimensions() + TileCreateObjects() end -function LevelGetWidth() +function LevelUpdateDimensions() + LevelData.Width = LevelGetWidth() + LevelData.Height = LevelGetHeight() +end + +function LevelGetTileHeight() + return #LevelTiles +end + +function LevelGetTileWidth() local width = 0 for i = 1, #LevelTiles do if width < #LevelTiles[i] then width = #LevelTiles[i] end end - return width * tileProperties.width + return width +end + +function LevelGetHeight() + return LevelGetTileHeight() * tileProperties.height +end + +function LevelGetWidth() + return LevelGetTileWidth() * tileProperties.width end function LevelIndexTiles() @@ -53,8 +68,17 @@ function LevelIndexTiles() ) end end + TileDataInitialize() - -- initialize tile data +-- instance level tiles according to the Properties + for i = 1, #LevelTiles do + for j = 1, #LevelTiles[i] do + InstanceTile(i,j,LevelTiles[i][j]) + end + end +end + +function TileDataInitialize() for _, Properties in pairs(TileData) do if Properties.animation ~= nil then Properties.tileset = love.graphics.newImage("assets/terrain/"..Properties.animation..".png") @@ -85,33 +109,28 @@ function LevelIndexTiles() Properties.image_count = image_count end end +end --- instance level tiles according to the Properties - for i = 1, #LevelTiles do - for j = 1, #LevelTiles[i] do - local id = LevelTiles[i][j] - LevelTiles[i][j] = {} - local tile = LevelTiles[i][j] - tile.id = id +function InstanceTile(i,j,id) + LevelTiles[i][j] = {} + local tile = LevelTiles[i][j] + tile.id = id - for _, Properties in pairs(TileData) do - if Properties.id == tile.id then - if type(Properties.overlay) == "table" then - tile.display_overlay = Properties.overlay[math.random(#Properties.overlay)] - else - tile.display_overlay = Properties.overlay - end + for _, Properties in pairs(TileData) do + if Properties.id == tile.id then + if type(Properties.overlay) == "table" then + tile.display_overlay = Properties.overlay[math.random(#Properties.overlay)] + else + tile.display_overlay = Properties.overlay + end - if type(Properties.force) == "table" then - tile.display = Properties.force[math.random(#Properties.force)] - else - tile.display = Properties.force - end + if type(Properties.force) == "table" then + tile.display = Properties.force[math.random(#Properties.force)] + else + tile.display = Properties.force end end - end - end end function TileGetType(tile) diff --git a/data/scripts/lights.lua b/data/scripts/lights.lua index 2c01afd..fecd7bf 100644 --- a/data/scripts/lights.lua +++ b/data/scripts/lights.lua @@ -5,7 +5,7 @@ function CreateDarkness() return love.graphics.newCanvas(game.width/game.scale, game.height/game.scale) end -function CreateLight(x,y,range,lum,flicker) +function CreateLight(x,y,range,flicker,color,lum) local o = {} o.pos = { x = x, @@ -13,11 +13,13 @@ function CreateLight(x,y,range,lum,flicker) } o.range = range o.lum = lum or 1 + o.color = color or {1,1,1} o.flicker_value = flicker or 2 o.flicker = 0 o.dim = 0 o.flicker_speed = flicker_speed or 60/12 o.flicker_time = 0 + table.insert(Lights,o) o.id = #Lights return o @@ -52,9 +54,9 @@ function DoLights() end end love.graphics.setBlendMode("replace") - love.graphics.setColor(1,1,1,1) for _, light in pairs(Lights) do if light.range ~= 0 then + love.graphics.setColor(light.color[1],light.color[2],light.color[3],1) love.graphics.circle( "fill", (light.pos.x - Camera.pos.x) / game.scale, diff --git a/main.lua b/main.lua index de0e310..c44925c 100644 --- a/main.lua +++ b/main.lua @@ -46,10 +46,11 @@ function love.load() main_Player = Player:New(75,50) - Kupo:New(100,150) - Kupo:New(300,150) - Decoration:New(200,89,animation.decoration.candelabra,80) - Fairy:New(200,88) + --Kupo:New(100,150) + --Kupo:New(300,150) + --Decoration:New(200,89,animation.decoration.candelabra,80) + --Fairy:New(200,88) + --CursedBook:New(180,68) gravity = 0.2 end