From 37bf7eab28727f428cf456c61f698e0a3be55bb0 Mon Sep 17 00:00:00 2001 From: Indrajith K L Date: Sat, 5 Mar 2022 05:44:05 +0530 Subject: * Player/ Enemy Chase * Pickable Entity * Enemies --- .gitignore | 2 -- README.md | 2 -- assets/images/heart.png | Bin 0 -> 143 bytes assets/images/tileset.png | Bin 3024 -> 3011 bytes assets/maps/level1.lua | 80 +++++++++++++++++++++++++++++----------------- assets/sfx/heart.wav | Bin 0 -> 31062 bytes conf.lua | 2 +- core/map.lua | 70 ++++++++++++++++++++++++++++------------ entities/enemy.lua | 56 +++++++++++++++----------------- entities/pickable.lua | 47 +++++++++++++++++++++++++++ main.lua | 11 +++++++ raw/heart.aseprite | Bin 0 -> 329 bytes raw/heart.sfs | Bin 0 -> 105 bytes raw/level1.tmx | 30 +++++++++++------ raw/tileset.aseprite | Bin 1874 -> 1862 bytes scenes/level1_scene.lua | 2 +- scenes/menu_scene.lua | 2 +- 17 files changed, 206 insertions(+), 98 deletions(-) create mode 100644 assets/images/heart.png create mode 100644 assets/sfx/heart.wav create mode 100644 entities/pickable.lua create mode 100644 raw/heart.aseprite create mode 100644 raw/heart.sfs diff --git a/.gitignore b/.gitignore index b51d381..9f4731d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ *.mp3 *.ogg -*.tmx -*.aseprite *.log \ No newline at end of file diff --git a/README.md b/README.md index e05d912..7d2f4ab 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ lul-bot-logo -Source code of my ```LÖVE Jam 2022``` entry. - This game is written in lua and LÖVE 2D framework. You may need LÖVE 2D installed to run. ### Controls diff --git a/assets/images/heart.png b/assets/images/heart.png new file mode 100644 index 0000000..f7d9baf Binary files /dev/null and b/assets/images/heart.png differ diff --git a/assets/images/tileset.png b/assets/images/tileset.png index cd90a99..3d95459 100644 Binary files a/assets/images/tileset.png and b/assets/images/tileset.png differ diff --git a/assets/maps/level1.lua b/assets/maps/level1.lua index 3681b3e..fc68b04 100644 --- a/assets/maps/level1.lua +++ b/assets/maps/level1.lua @@ -9,7 +9,7 @@ return { tilewidth = 16, tileheight = 16, nextlayerid = 7, - nextobjectid = 33, + nextobjectid = 47, properties = {}, tilesets = { { @@ -233,9 +233,9 @@ return { 0, 0, 0, 0, 97, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 0, 0, 0, 33, 34, 0, 0, 0, 3, 132, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 34, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -306,50 +306,70 @@ return { }, { id = 27, - name = "potion", - type = "interactive", + name = "heart", + type = "pickable", shape = "rectangle", - x = 179.969, - y = 117, - width = 8.04438, - height = 11, + x = 166.333, + y = 103, + width = 8, + height = 8, rotation = 0, visible = true, properties = { ["interactive_type"] = "pickable", - ["message"] = "Acquired Potion" + ["message"] = "Health Increased", + ["value"] = "20" } }, { - id = 30, - name = "potion", - type = "interactive", + id = 44, + name = "heart", + type = "pickable", shape = "rectangle", - x = 211.917, - y = 85.0417, - width = 8.04438, - height = 11, + x = 203.038, + y = 83.6818, + width = 8, + height = 8, rotation = 0, visible = true, properties = { ["interactive_type"] = "pickable", - ["message"] = "Acquired Potion" + ["message"] = "Health Increased", + ["value"] = "20" } }, { - id = 31, - name = "potion", - type = "interactive", + id = 45, + name = "heart", + type = "pickable", + shape = "rectangle", + x = 199.288, + y = 117.932, + width = 8, + height = 8, + rotation = 0, + visible = true, + properties = { + ["interactive_type"] = "pickable", + ["message"] = "Health Increased", + ["value"] = "20" + } + }, + { + id = 46, + name = "heart", + type = "pickable", shape = "rectangle", - x = 227.943, - y = 116.965, - width = 8.04438, - height = 11, + x = 158.288, + y = 127.682, + width = 8, + height = 8, rotation = 0, visible = true, properties = { ["interactive_type"] = "pickable", - ["message"] = "Acquired Potion" + ["message"] = "Health Increased", + ["value"] = "20" } }, { @@ -357,10 +377,10 @@ return { name = "", type = "enemy", shape = "rectangle", - x = 128, - y = 48, - width = 16, - height = 16, + x = 23, + y = 18.3333, + width = 8, + height = 8, rotation = 0, visible = true, properties = {} diff --git a/assets/sfx/heart.wav b/assets/sfx/heart.wav new file mode 100644 index 0000000..6233a23 Binary files /dev/null and b/assets/sfx/heart.wav differ diff --git a/conf.lua b/conf.lua index 8fbb0e5..fea441b 100644 --- a/conf.lua +++ b/conf.lua @@ -1,7 +1,7 @@ function love.conf(t) t.window.width = 800 t.window.height = 600 - t.window.fullscreen = false + t.window.fullscreen = true t.window.title = "" t.window.usedpiscale = true t.window.icon = "assets/images/icon.png" diff --git a/core/map.lua b/core/map.lua index e4eb3b7..f64d3f7 100644 --- a/core/map.lua +++ b/core/map.lua @@ -7,6 +7,7 @@ Windfield = require("libs.windfield") require("libs.tserial") require("core.notifications") require("entities.enemy") +require("entities.pickable") local zoomFactor = 3 local player = { x=0, @@ -23,12 +24,14 @@ local _h = windowHeight/zoomFactor Map = Class { __include=Gamestate, - init = function(self, mapName) + init = function(self, mapName, debug) + self.debug = debug and debug or false _gameWorld = Windfield.newWorld(0,0) - _gameWorld:setQueryDebugDrawing(true) -- Remove when deploy - _gameWorld:addCollisionClass('player') + _gameWorld:setQueryDebugDrawing(debug and debug or false) -- Remove when deploy _gameWorld:addCollisionClass('interactive') + _gameWorld:addCollisionClass('pickable') _gameWorld:addCollisionClass('enemy') + _gameWorld:addCollisionClass('player') effect = Moonshine(windowWidth, windowHeight, Moonshine.effects.crt) .chain(Moonshine.effects.vignette) .chain(Moonshine.effects.scanlines) @@ -52,11 +55,7 @@ Map = Class { player.collider:setFixedRotation(true) player.collider:setCollisionClass('player') - player.collider:setObject({ - x = player.x, - y = player.y, - dir = player.dir - }) + player.collider:setObject(player) end if obj.type=="interactive" then @@ -72,9 +71,16 @@ Map = Class { collider:setType("static") end + if obj.type=="pickable" then + local pickable = Pickable(obj.x, obj.y, obj.width, obj.height, obj.name and obj.name or nil, _gameWorld) + pickable:setCollider(obj.properties) + table.insert(self.pickables, pickable) + end + if obj.type=="enemy" then - enemy = Enemy(obj.x, obj.y, _gameWorld) + local enemy = Enemy(obj.x, obj.y, _gameWorld) enemy:setCollider() + table.insert(self.enemies, enemy) end end end @@ -86,7 +92,10 @@ Map = Class { end end end, - entities={} + entities={}, + enemies={}, + pickables={}, + debug=false } function Map:update(dt) @@ -118,11 +127,7 @@ function Map:update(dt) _gameWorld:update(dt) player.x = player.collider:getX() - 4 player.y = player.collider:getY() - 4 - player.collider:setObject({ - x = player.x, - y = player.y, - dir = player.dir - }) + player.collider:setObject(player) camera:lookAt(player.x, player.y) currentMap:update(dt) @@ -146,8 +151,8 @@ function Map:update(dt) camera.y = (mapHeight - _h/2) end - if player.collider:enter('interactive') then - local _interColliderData = player.collider:getEnterCollisionData('interactive') + if player.collider:enter('interactive') or player.collider:enter('pickable')then + local _interColliderData = player.collider:getEnterCollisionData('interactive') or player.collider:getEnterCollisionData('pickable') local interactiveCollider = _interColliderData.collider local interactiveData = interactiveCollider:getObject() if interactiveData.message then @@ -155,7 +160,22 @@ function Map:update(dt) end end notifications:update(dt) - enemy:update(dt) + for i,enemy in pairs(self.enemies) do + if enemy.dead then + table.remove(self.enemies, i) + else + enemy:update(dt) + end + end + + for i,pickable in pairs(self.pickables) do + if pickable.acquired then + table.remove(self.pickables, i) + else + pickable:update(dt) + end + end + end function Map:draw() @@ -165,8 +185,16 @@ function Map:draw() drawMapLayer("decorations") love.graphics.draw(player.sprite, player.x, player.y) drawMapLayer("foreground") - _gameWorld:draw() -- Debug Collision Draw - enemy:draw() + if self.debug then + _gameWorld:draw() -- Debug Collision Draw + end + for i,enemy in pairs(self.enemies) do + enemy:draw() + end + + for i,pickable in pairs(self.pickables) do + pickable:draw() + end camera:detach() notifications:draw() end) @@ -197,4 +225,4 @@ function resize() notifications.calculateWindowDimensions() end -return Map \ No newline at end of file +return Map diff --git a/entities/enemy.lua b/entities/enemy.lua index 7e18e95..f8f0681 100644 --- a/entities/enemy.lua +++ b/entities/enemy.lua @@ -11,61 +11,57 @@ Enemy = Class{ speed=60, collider=nil, world=nil, - chasing=false + chasing=false, + dead=false } function Enemy:draw() love.graphics.setColor({1,0,0}) - love.graphics.rectangle('fill', self.x, self.y, 16, 16) + love.graphics.rectangle('fill', self.x, self.y, 8, 8) if self.collider then end end function Enemy:setCollider() - self.collider = self.world:newRectangleCollider(self.x, self.y, 16, 16) + self.collider = self.world:newRectangleCollider(self.x, self.y, 8, 8) self.collider:setFixedRotation(true) + self.collider:setType('static') end function Enemy:update(dt) if self.collider then - -- Do the Query - local colliders = self.world:queryCircleArea(self.x, self.y, 100,{'player'}) - local vx = 0 - local vy = 0 - if #colliders then + local playerColliders = self.world:queryCircleArea(self.x, self.y, 100,{'player'}) + local enemyColliders = self.world:queryCircleArea(self.x+4, self.y+4, 8,{'enemy'}) + if #playerColliders then self.chasing = true - for i,collider in pairs(colliders) do + for i,collider in pairs(playerColliders) do local playerObject = collider:getObject() - - if playerObject.dir=="up" then - vy = self.speed * -1 - end - - if playerObject.dir=="left" then - vx = self.speed * -1 - end - - if playerObject.dir=="down" then - vy = self.speed - end - - if playerObject.dir=="right" then - vx = self.speed - end directionX = playerObject.x - self.x directionY = playerObject.y - self.y distance = math.sqrt(directionX * directionX + directionY * directionY) - if distance >16 then - self.x = self.x + directionX / distance * self.speed * dt - self.y = self.y + directionY / distance * self.speed * dt + local angle = math.atan2(directionY, directionX) + if distance > 20 then + -- self.x = self.x + directionX / distance * self.speed * dt + -- self.y = self.y + directionY / distance * self.speed * dt + self.x = self.x + self.speed * math.cos(angle) * dt + self.y = self.y + self.speed * math.sin(angle) * dt end end - self.collider:setX(self.x+8) - self.collider:setY(self.y+8) + + if self.collider then + self.collider:setX(self.x+4) + self.collider:setY(self.y+4) + end + else self.chasing = false end + + if self.collider:enter('player') then + -- self.dead = true + self.collider:destroy() + end end end \ No newline at end of file diff --git a/entities/pickable.lua b/entities/pickable.lua new file mode 100644 index 0000000..00dc174 --- /dev/null +++ b/entities/pickable.lua @@ -0,0 +1,47 @@ +Class = require("libs.hump.class") + +Pickable = Class{ + init = function(self, x, y, w, h, name, gameWorld) + self.x = x + self.y = y + self.width = w + self.height = h + self.image = name + self.world = gameWorld + self.image = love.graphics.newImage("assets/images/"..name..".png") + self.sfx = love.audio.newSource("assets/sfx/"..name..".wav", "static") + end, + x=0, + y=0, + width=0, + height=0, + image=nil, + world=nil, + collider=nil, + acquired=false, + sfx=nil +} + +function Pickable:setCollider(colliderData) + self.collider = self.world:newRectangleCollider(self.x, self.y, self.width, self.height) + self.collider:setFixedRotation(true) + self.collider:setType('static') + self.collider:setCollisionClass('pickable') + self.collider:setObject(colliderData) +end + +function Pickable:draw() + love.graphics.draw(self.image,self.x, self.y) +end + +function Pickable:update(dt) + if self.collider then + if self.collider:enter('player') then + self.acquired = true + self.sfx:play() + self.collider:destroy() + end + end +end + +return Pickable \ No newline at end of file diff --git a/main.lua b/main.lua index 7f7c10d..d9411c2 100644 --- a/main.lua +++ b/main.lua @@ -1,8 +1,19 @@ local Gamestate = require("libs.hump.gamestate") local LoveSplash = require("libs.o-ten-one") require("scenes.menu_scene"); +require("scenes.level1_scene"); function love.load() + -- initGame() + bypassMenu() +end + +function bypassMenu() + Gamestate.switch(level1) + Gamestate.registerEvents() +end + +function initGame() splash = LoveSplash({background={0, 0, 0}}) splash.onDone = onLoveSplashDone end diff --git a/raw/heart.aseprite b/raw/heart.aseprite new file mode 100644 index 0000000..54461b5 Binary files /dev/null and b/raw/heart.aseprite differ diff --git a/raw/heart.sfs b/raw/heart.sfs new file mode 100644 index 0000000..8161472 Binary files /dev/null and b/raw/heart.sfs differ diff --git a/raw/level1.tmx b/raw/level1.tmx index 07275b8..3b69392 100644 --- a/raw/level1.tmx +++ b/raw/level1.tmx @@ -1,5 +1,5 @@ - + @@ -103,9 +103,9 @@ 0,0,0,0,97,98,0,0,0,0,0,0,0,0,0,0,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,129,130,0,0,0,0,33,34,0,0,0,3,132,133,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,65,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,0,0,0,0,0,0,0,0,0,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,33,34,0,0,0,0,0,0,0,37,0,0,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,33,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,65,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,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -140,25 +140,35 @@ - + + + + + + + + - + + - + - + + - + - + + - + diff --git a/raw/tileset.aseprite b/raw/tileset.aseprite index f329476..c5e0e49 100644 Binary files a/raw/tileset.aseprite and b/raw/tileset.aseprite differ diff --git a/scenes/level1_scene.lua b/scenes/level1_scene.lua index c7ad856..58fb639 100644 --- a/scenes/level1_scene.lua +++ b/scenes/level1_scene.lua @@ -9,7 +9,7 @@ function level1:init() constants.resetColors() screenShake = ScreenShaker() ambience = Ambience({"atmosphere1","thunder"}) - map = Map("level1") + map = Map("level1", false) end function level1:enter(previous) diff --git a/scenes/menu_scene.lua b/scenes/menu_scene.lua index 085162c..e90b805 100644 --- a/scenes/menu_scene.lua +++ b/scenes/menu_scene.lua @@ -19,7 +19,7 @@ function menu:init() titleFont2 = love.graphics.newFont('assets/fonts/Lazer84.ttf', titleFontSize2) startMsgFont = love.graphics.newFont('assets/fonts/C800.ttf', msgFontSize) music = love.audio.newSource("assets/music/Stevia Sphere - Drum machine dreams.ogg", "stream") - titleText1 = love.graphics.newText(titleFont1, "Enemy is in Another") + titleText1 = love.graphics.newText(titleFont1, "Your Enemy is in Another") titleText2 = love.graphics.newText(titleFont2, "Dungeon") msgText = love.graphics.newText(startMsgFont, "Press X to START") effect = Moonshine(windowWidth, windowHeight, Moonshine.effects.crt) -- cgit v1.2.3