From 1f7d967f77e4bfe7ff09776e04cb38fb959f3c7e Mon Sep 17 00:00:00 2001 From: lustlion Date: Tue, 8 Feb 2022 08:22:27 +0100 Subject: [PATCH] Cleaned collisions.lua, objobjects.lua. Fixed level optimization typo. Added fairy FCS (altitude hold). --- data/levels/level1.lua | 18 ++++--- data/scripts/collision.lua | 21 ++++----- data/scripts/entities/fairy.lua | 46 +++++++++++++----- data/scripts/entity.lua | 83 ++++++++++++++++++++------------- data/scripts/game.lua | 1 + data/scripts/level.lua | 7 +-- data/scripts/objects.lua | 43 +++++++++++------ 7 files changed, 134 insertions(+), 85 deletions(-) diff --git a/data/levels/level1.lua b/data/levels/level1.lua index e3236ab..b769aa7 100644 --- a/data/levels/level1.lua +++ b/data/levels/level1.lua @@ -2,13 +2,17 @@ return { name = "test", tileset = tileset.library, tiles = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - { 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, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37}, - { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37}, - { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37}, - { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} + { 1, 14, 14, 14, 14, 14, 14, 1, 14, 14, 14, 14, 14, 14, 14, 1}, + { 1, 4, 0, 0, 0, 0, 2, 14, 4, 0, 0, 0, 0, 0, 2, 1}, + { 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1}, + { 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1}, + { 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1}, + { 1, 4, 0, 0, 0, 0, 2, 13, 4, 0, 0, 0, 0, 0, 2, 1}, + { 1, 13, 13, 13, 13, 13, 13, 1, 4, 0, 0, 0, 0, 0, 2, 1}, + { 1, 1, 1, 1, 1, 1, 1, 1, 4, 0, 0, 0, 0, 0, 2, 1}, + { 1, 1, 1, 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} }, objects = {} } \ No newline at end of file diff --git a/data/scripts/collision.lua b/data/scripts/collision.lua index d925bdf..b213ba3 100644 --- a/data/scripts/collision.lua +++ b/data/scripts/collision.lua @@ -2,31 +2,28 @@ Collision = {} --[[ Collision - [bool] isDisabled + [bool flag] isDisabled > if true used for collision - [bool] isActive - > if true, this collision is active (on collision, duh) - - [bool] isColliding + [bool flag] isColliding > if true, this collision is colliding - [2d pos] from - x, y - > top right corner of collision box + [vec2 position] from - x, y + > top right corner of collision box - [2d pos] to - x, y + [vec2 position] to - x, y > bottom left corner of collision box - [int] width + [int property] width > width of collision box - [int] height + [int property] height > height of collision box --]] -- can also be called with only ox and oy, where they become the width and height instead function Collision:New(ox,oy,tx,ty) - local o = {isColliding = false, isDisabled = false, isActive = false} + local o = {isColliding = false, isDisabled = false} if tx ~= nil and ty ~= nil then o.from = {x = ox, y = oy} @@ -65,8 +62,6 @@ end function Collision:Draw(color) if self.isColliding == true then love.graphics.setColor(0,1,0,0.5) - elseif self.isActive == 1 then - love.graphics.setColor(0,1,1,0.5) elseif color == 1 then love.graphics.setColor(1,0,0,0.5) elseif color == 2 then diff --git a/data/scripts/entities/fairy.lua b/data/scripts/entities/fairy.lua index 004ba63..1778ce9 100644 --- a/data/scripts/entities/fairy.lua +++ b/data/scripts/entities/fairy.lua @@ -5,9 +5,11 @@ Fairy = Entity:New(x,y) -- behaviour o.pos = {x = x, y = y} - o.speed = 1 + o.speed = 1.4 o.range = 20 + o.vision_range = 120 o.target = {x = x, y = y} + o.hover_distance = 60 -- animations o.body = Animation:New(animation.fairy.flying) @@ -32,9 +34,30 @@ Fairy = Entity:New(x,y) function Fairy:Smart() - if self:CheckVisionLine(main_Player) then + if self:CheckVisionLine(main_Player,self.vision_range) then + 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 below = 1 + while not isThereObjectAt( + self.target.x, + self.target.y + below * game.scale, + LoadedObjects.Collisions + ) do + below = below + 1 + if below >= self.hover_distance then break end + end + local top = 1 + while not isThereObjectAt( + self.target.x, + self.target.y - top * game.scale, + LoadedObjects.Collisions + ) do + top = top + 1 + if top >= self.hover_distance then break end + end + self.target.y = self.target.y - top + below end local distance_x = self.target.x - self.pos.x @@ -55,16 +78,12 @@ function Fairy:Smart() local particle_data = { animation = animation.particle.simple, - sprite_tint = HEX2RGB("#fe00d1"), + sprite_tint = HEX2RGB("#fed100"), 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 - ) + Particle:New(self.pos.x,self.pos.y,particle_data) end end @@ -75,17 +94,20 @@ function Fairy:HandleAnimation() end function Fairy:DoPhysics() - local random_x = math.random(-2, 2)/10 - local random_y = math.random(-2, 2)/10 + local random_x = math.random(-4, 4)/10 + local random_y = math.random(-4, 4)/10 + self.vel.x = self.vel.x + random_x self.vel.y = self.vel.y + random_y - -- move self:CollisionMove() + self.vel.x = 0 + self.vel.y = 0 + self:LightAdjust() end function Fairy:Debug() Entity.Debug(self) - self:CheckVisionLineDebug(main_Player) + self:CheckVisionLineDebug(main_Player,self.vision_range) end diff --git a/data/scripts/entity.lua b/data/scripts/entity.lua index d2e59cb..b01fb4f 100644 --- a/data/scripts/entity.lua +++ b/data/scripts/entity.lua @@ -73,7 +73,7 @@ function Entity:Kill() self = nil end -function Entity:CheckVisionLine(entity) +function Entity:CheckVisionLine(entity,range) local target_x = entity.pos.x + entity.target_offset.x local target_y = entity.pos.y + entity.target_offset.y @@ -83,15 +83,18 @@ function Entity:CheckVisionLine(entity) local angle = GetAngleFromVector(distance_x,distance_y) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) - local is_colliding = false + local is_colliding = true - for i=1, distance, game.scale do - if isThereObjectAt( - self.pos.x+math.cos(angle)*i, - self.pos.y+math.sin(angle)*i, - LoadedObjects.Collisions - ) then - is_colliding = true + if distance < range then + is_colliding = false + for i=1, distance, game.scale do + if isThereObjectAt( + self.pos.x+math.cos(angle)*i, + self.pos.y+math.sin(angle)*i, + LoadedObjects.Collisions + ) then + is_colliding = true + end end end @@ -131,15 +134,19 @@ end -- returns true if theres a collision at that point. also marks collisioned tile as collision true function Entity:isCollidingAt(x,y,object) - local result = false - for _, col in pairs(object) do - result = x + self.boxCollision.from.x < col.to.x - and col.from.x < x + self.boxCollision.to.x - and y + self.boxCollision.from.y < col.to.y - and col.from.y < y + self.boxCollision.to.y - if result == true then break end + for _, collision in pairs(object) do + if collision.disable then + -- Dont calculate if disabled + elseif x + self.boxCollision.from.x < collision.to.x + and x + self.boxCollision.to.x > collision.from.x + and y + self.boxCollision.from.y < collision.to.y + and y + self.boxCollision.to.y > collision.from.y + then + collision.isColliding = true + return true + end end - return result + return false end function Entity:isCollidingWith(entity) @@ -163,7 +170,7 @@ function Entity:isCollidingAtAll(x,y) return result end -function Entity:CheckVisionLineDebug(entity) +function Entity:CheckVisionLineDebug(entity,range) local c1, c2, c3, a = love.graphics.getColor() local target_x = entity.pos.x + entity.target_offset.x @@ -175,22 +182,24 @@ function Entity:CheckVisionLineDebug(entity) local angle = GetAngleFromVector(distance_x,distance_y) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) - for i=1, distance, game.scale do - if isThereObjectAt( - self.pos.x+math.cos(angle)*i, - self.pos.y+math.sin(angle)*i, - LoadedObjects.Collisions - ) then - love.graphics.setColor(1,0,0) - else - love.graphics.setColor(0,1,0) + if distance < range then + for i=1, distance, game.scale do + if isThereObjectAt( + self.pos.x+math.cos(angle)*i, + self.pos.y+math.sin(angle)*i, + LoadedObjects.Collisions + ) then + love.graphics.setColor(1,0,0) + else + love.graphics.setColor(0,1,0) + end + love.graphics.line( + self.pos.x+math.cos(angle)*i-1 - Camera.pos.x, + self.pos.y+math.sin(angle)*i-1 - Camera.pos.y, + self.pos.x+math.cos(angle)*i - Camera.pos.x, + self.pos.y+math.sin(angle)*i - Camera.pos.y + ) end - love.graphics.line( - self.pos.x+math.cos(angle)*i-1 - Camera.pos.x, - self.pos.y+math.sin(angle)*i-1 - Camera.pos.y, - self.pos.x+math.cos(angle)*i - Camera.pos.x, - self.pos.y+math.sin(angle)*i - Camera.pos.y - ) end love.graphics.setColor(c1,c2,c3,a) @@ -209,6 +218,14 @@ function Entity:Debug() -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) ) + if self.target ~= nil then + love.graphics.line( + -Camera.pos.x + self.pos.x, + -Camera.pos.y + self.pos.y, + -Camera.pos.x + self.target.x, + -Camera.pos.y + self.target.y + ) + end end require "data/scripts/entities/kupo" require "data/scripts/entities/arrow" diff --git a/data/scripts/game.lua b/data/scripts/game.lua index 4eba465..96d71b4 100644 --- a/data/scripts/game.lua +++ b/data/scripts/game.lua @@ -1,4 +1,5 @@ function GameStep() + SetCollisionFlags() if menu_type == "no" then for _, particle in pairs(LoadedParticles) do particle:Smart() diff --git a/data/scripts/level.lua b/data/scripts/level.lua index a17e577..616e0b7 100644 --- a/data/scripts/level.lua +++ b/data/scripts/level.lua @@ -259,7 +259,6 @@ function TileOptimizeObjects() for j = 1, #LevelTiles[i] do if LevelTiles[i][j].id ~= 0 then local type = TileData[LevelTiles[i][j].id].type - local light = TileData[LevelTiles[i][j].id].light if type == "whole" and not isTileOptimized[i][j] then @@ -296,14 +295,12 @@ function TileOptimizeObjects() then local type_check = TileData[LevelTiles[i+m][j+l].id].type if type_check == "whole" - and not isTileOptimized[i+m][j+n] + and not isTileOptimized[i+m][j+l] then checkline = true else break end - else - break end end if checkline then @@ -317,7 +314,7 @@ function TileOptimizeObjects() end end - logPrint("Group size: "..m.."x"..n) + logPrint("- Group size: "..m.."x"..n) unoptimized = unoptimized + m * n local base_x = tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.height) local base_y = tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) diff --git a/data/scripts/objects.lua b/data/scripts/objects.lua index a183e16..e032316 100644 --- a/data/scripts/objects.lua +++ b/data/scripts/objects.lua @@ -22,16 +22,16 @@ function LoadedObjects.DrawCollisions() end end --- returns true if theres a collision at that point. also marks collisioned tile as collision true +-- returns true if theres a collision at that point function isThereObjectAt(x,y,objectType) for _, collision in pairs(objectType) do if collision.disable then -- Dont calculate if dissabled - elseif x >= collision.from.x + elseif x >= collision.from.x and x <= collision.to.x and y >= collision.from.y and y <= collision.to.y then - collision.collision = true + collision.isColliding = true return true end end @@ -39,24 +39,37 @@ function isThereObjectAt(x,y,objectType) end function isThereAnyCollisionAt(x,y) - return isThereObjectAt(x,y,LoadedObjects.Collisions) or isThereObjectAt(x,y,LoadedObjects.Ladders) or isThereObjectAt(x,y,LoadedObjects.Platforms) -end --- flags -function SetCollisionFlags(player) - for _, collision in pairs(LoadedObjects.Collisions) do - collision.collision = false + local Check = { + LoadedObjects.Collisions, + LoadedObjects.Ladders, + LoadedObjects.Platforms + } + for _, type in pairs(Check) do + local result = isThereObjectAt(x,y,type) + if result then + return result + end end + return false +end +-- flags +function SetCollisionFlags() + local Check = { + LoadedObjects.Collisions, + LoadedObjects.Ladders, + LoadedObjects.Platforms + } + for _, type in pairs(Check) do + for _, object in pairs(type) do + object.isColliding = false + end + end for _, platform in pairs(LoadedObjects.Platforms) do - platform.collision = false - if player.pos.y < platform.from.y then + if main_Player.pos.y < platform.from.y then platform.disable = false else platform.disable = true end end - - for _, ladder in pairs(LoadedObjects.Ladders) do - ladder.collision = false - end end