diff --git a/code/entities/arrow.lua b/code/entities/arrow.lua index ac6dc36..51622e9 100644 --- a/code/entities/arrow.lua +++ b/code/entities/arrow.lua @@ -36,20 +36,30 @@ function Arrow:drawBackground() end function Arrow:doPhysics() - 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.stuck = true - 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.stuck = true + -- horizontal collision + self:moveX( + self.vel.x, + function() + self.stuck = true + end + ) + + if not self.stuck then + -- vertical collision + self:moveY( + self.vel.y, + function() + self.stuck = true + end + ) end + if self.stuck then self.pos.x = self.pos.x + self.vel.x * (2/3) self.pos.y = self.pos.y + self.vel.y * (2/3) self.vel.x = 0 self.vel.y = 0 end + + self:adjustLight() end diff --git a/code/entities/cursed_book.lua b/code/entities/cursed_book.lua index 245e755..5e7a334 100644 --- a/code/entities/cursed_book.lua +++ b/code/entities/cursed_book.lua @@ -67,6 +67,13 @@ function CursedBook:doLogic() elseif self.status == 4 then end + + 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 end function CursedBook:handleAnimation() @@ -101,15 +108,21 @@ function CursedBook:handleAnimation() 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:moveWithCollision() + -- horizontal collision + self:moveX( + self.vel.x, + function() + self.vel.x = 0 + end + ) + -- vertical collision + self:moveY( + self.vel.y, + function() + self.vel.y = 0 + end + ) + -- final position self:adjustLight() end diff --git a/code/entities/fairy.lua b/code/entities/fairy.lua index 6ccd688..7e20124 100644 --- a/code/entities/fairy.lua +++ b/code/entities/fairy.lua @@ -34,7 +34,6 @@ function Fairy:new(x,y) end function Fairy:doLogic() - if self:checkVisionLine(main_player,self.vision_range) then self.target.x = main_player.pos.x + main_player.target_offset.x @@ -63,31 +62,19 @@ function Fairy:doLogic() 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 angle = getAngleFromVector(vector(distance_x,distance_y)) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) if distance < self.range then - self.vel.x = self.vel.x * 0.9 - self.vel.y = self.vel.y * 0.9 + local random_x = math.random(-1, 1) + local random_y = math.random(-1, 1) + self.vel.x = self.vel.x * 0.9 + random_x/10 + self.vel.y = self.vel.y * 0.9 + random_y/10 else - self.vel.x = math.cos(angle)*self.speed - self.vel.y = math.sin(angle)*self.speed - 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.simple, - animation_speed = 1, - sprite_tint = hex2rgb("#fed100"), - sprite_alpha_fade = true, - direction = angle-math.rad(180+math.random(60)-30), - speed = 0.8*(distance/50), - speed_increase = -0.01, - time = 0.75 - } - Particle:new(self.pos.x,self.pos.y,particle_data) + local random_x = math.random(-6, 6) + local random_y = math.random(-6, 6) + self.vel.x = math.cos(angle)*self.speed + random_x/10 + self.vel.y = math.sin(angle)*self.speed + random_y/10 end end @@ -95,19 +82,42 @@ function Fairy:handleAnimation() self.body:animate() --if self:isCollidingWith(main_player) then self.sprite_tint = {1,0,0} else self.sprite_tint = {1,1,1} end self:draw(self.body) + + self.particle_timer = self.particle_timer + 1 + if self.particle_timer >= self.particle_time then + local vector = vector(self.vel.x,self.vel.y) + local angle = getAngleFromVector(vector) + self.particle_timer = 0 + local particle_data = { + animation = animation.particle.simple, + animation_speed = 1, + sprite_tint = hex2rgb("#fed100"), + sprite_alpha_fade = true, + direction = angle-math.rad(180+math.random(60)-30), + speed = 1, + speed_increase = -0.01, + time = 0.75 + } + Particle:new(self.pos.x,self.pos.y,particle_data) + end end function Fairy:doPhysics() - 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 - - self:moveWithCollision() - self.vel.x = 0 - self.vel.y = 0 - + -- horizontal collision + self:moveX( + self.vel.x, + function() + self.vel.x = 0 + end + ) + -- vertical collision + self:moveY( + self.vel.y, + function() + self.vel.y = 0 + end + ) + -- final position self:adjustLight() end diff --git a/code/entities/hook_anchor.lua b/code/entities/hook_anchor.lua index a5f9377..94b3447 100644 --- a/code/entities/hook_anchor.lua +++ b/code/entities/hook_anchor.lua @@ -36,10 +36,6 @@ function HookAnchor:drawBackground() ) end -function HookAnchor:doPhysics() -end - - function Fairy:debug() Entity.debug(self) end diff --git a/code/entities/kupo.lua b/code/entities/kupo.lua index 82d3da9..074802a 100644 --- a/code/entities/kupo.lua +++ b/code/entities/kupo.lua @@ -44,8 +44,9 @@ function Kupo:doLogic() 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 distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) - local angle = getAngleFromVector(distance_x,distance_y) + local angle = getAngleFromVector(vector(distance_x,distance_y)) self.draw_bow = false if distance <= self.range then if self.hostile == true then @@ -153,7 +154,3 @@ function Kupo:handleAnimation() ) end end - -function Kupo:doPhysics() - self:moveWithCollision() -end diff --git a/code/entities/particle.lua b/code/entities/particle.lua index 03428dd..2f3b48e 100644 --- a/code/entities/particle.lua +++ b/code/entities/particle.lua @@ -89,26 +89,32 @@ function Particle:handleAnimation() end end -function Particle:doPhysics() +function Particle:doLogic() -- 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:moveWithCollision() - - if self.light ~= nil then - self:adjustLight() - self.light.range = self.light_range * self.sprite_alpha/2 - end if self.time ~= nil then if self.timer >= self.time then self:kill() end end end +function Particle:doPhysics() + -- horizontal collision + self:moveX( + self.vel.x + ) + -- vertical collision + self:moveY( + self.vel.y + ) + -- final position + self:adjustLight() +end + function Particle:debug() -- draw center CYAN love.graphics.setColor(0,1,1) diff --git a/code/entities/player.lua b/code/entities/player.lua index 0b89cff..a6af756 100644 --- a/code/entities/player.lua +++ b/code/entities/player.lua @@ -155,7 +155,7 @@ function Player:doLogic() end -- set dash values - self.dashDirection = getAngleFromVector(horizontal, vertical) + self.dashDirection = getAngleFromVector(vector(horizontal, vertical)) self.dash_timer = math.floor(self.dash_time * game.framerate) end else @@ -232,10 +232,10 @@ function Player:doPhysics() -- hook state if self.is_hooked then self.move_x = 0 - local hook = vector(self.pos.x, self.pos.y, self.hook_anchor.x, self.hook_anchor.y) + local hook = vector(self.hook_anchor.x - self.pos.x, self.hook_anchor.y - self.pos.y) local dist = math.min(getVectorValue(hook), self.hook_distance) - local hook_angle = getAngleFromVector(hook[1],hook[2])-math.rad(180) + local hook_angle = getAngleFromVector(hook)-math.rad(180) if Keybind:checkDown(Keybind.move.right) then hook_angle = hook_angle - self.hook_swing_speed @@ -264,8 +264,13 @@ function Player:doPhysics() local pos_y = self.hook_anchor.y + dist * math.sin(hook_angle) self.vel.x = self.vel.x + pos_x - self.pos.x self.vel.y = self.vel.y + pos_y - self.pos.y - self.pos.x = pos_x - self.pos.y = pos_y + + self:moveX( + pos_x - self.pos.x + ) + self:moveY( + pos_y - self.pos.y + ) end @@ -276,24 +281,26 @@ function Player:doPhysics() end -- horizontal collision - 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 - self.wall_hit = 0 - else - self.wall_hit = math.sign(self.vel.x) - self.vel.x = 0 - end + self.wall_hit = 0 + self:moveX( + self.vel.x, + function() + self.wall_hit = math.sign(self.vel.x) + self.vel.x = 0 + end + ) -- vertical collision - 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 - if self.vel.y > 0 then - self.is_on_ground = true - self.dash_count = self.dash_amount + self:moveY( + self.vel.y, + function() + if self.vel.y > 0 then + self.is_on_ground = true + self.dash_count = self.dash_amount + end + self.vel.y = 0 end - self.vel.y = 0 - end + ) -- if u collision w hazard, respawn if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then diff --git a/code/entity.lua b/code/entity.lua index b4f36b6..d226639 100644 --- a/code/entity.lua +++ b/code/entity.lua @@ -5,6 +5,7 @@ function Entity:new(x,y) local o = {} o.pos = {x = x, y = y} + o.move_remainder = {x = 0, y = 0} o.vel = {x = 0, y = 0} o.direction = 0 @@ -69,24 +70,53 @@ end function Entity:doLogic() end -function Entity:move() - self.pos.x = self.pos.x + self.vel.x - self.pos.y = self.pos.y + self.vel.y +function Entity:moveX(amount, func) + self.move_remainder.x = self.move_remainder.x + amount + local move = math.round(self.move_remainder.x) + if move ~= 0 then + self.move_remainder.x = self.move_remainder.x - move + local sign = math.sign(move) + while math.round(move) ~= 0 do + if not self:isCollidingAt( + self.pos.x + sign, + self.pos.y, + LoadedObjects.Collisions + ) then + self.pos.x = self.pos.x + sign + move = move - sign + if tostring(move) == "nan" then error() end + else + if func then + func() + end + break + end + end + end end -function Entity:moveWithCollision() - -- horizontal collision - 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 - - -- vertical collision - 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 +function Entity:moveY(amount, func) + self.move_remainder.y = self.move_remainder.y + amount + local move = math.round(self.move_remainder.y) + if move ~= 0 then + self.move_remainder.y = self.move_remainder.y - move + local sign = math.sign(move) + while math.round(move) ~= 0 do + if not self:isCollidingAt( + self.pos.x, + self.pos.y + sign, + LoadedObjects.Collisions + ) then + self.pos.y = self.pos.y + sign + move = move - sign + if tostring(move) == "nan" then error() end + else + if func then + func() + end + break + end + end end end @@ -120,8 +150,9 @@ function Entity:checkVisionLine(entity,range) local distance_x = target_x - self.pos.x local distance_y = target_y - self.pos.y + local distance = vector(distance_x,distance_y) - local angle = getAngleFromVector(distance_x,distance_y) + local angle = getAngleFromVector(distance) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) local is_colliding = true @@ -227,8 +258,9 @@ function Entity:checkVisionLineDebug(entity,range) local distance_x = target_x - self.pos.x local distance_y = target_y - self.pos.y + local distance = vector(distance_x,distance_y) - local angle = getAngleFromVector(distance_x,distance_y) + local angle = getAngleFromVector(distance) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) if distance < range then @@ -277,6 +309,9 @@ function Entity:debug() end end +function Entity:doPhysics() +end + function Entity:handleAnimation() end diff --git a/code/math.lua b/code/math.lua index edbda89..ec21b40 100644 --- a/code/math.lua +++ b/code/math.lua @@ -8,20 +8,22 @@ function math.sign(x) end end -function vector(init_x, init_y, final_x, final_y) - local distance_x = final_x - init_x - local distance_y = final_y - init_y - return {distance_x, distance_y} +function math.round(x) + return math.floor(x+0.5) +end + +function vector(x, y) + return {x = x, y = y} end function getVectorValue(vector) - return math.sqrt(vector[1] ^ 2 + vector[2] ^ 2) + return math.sqrt(vector.x ^ 2 + vector.y ^ 2) end -function getAngleFromVector(x,y) +function getAngleFromVector(vector) local reduce = 0 - if x < 0 then + if vector.x < 0 then reduce = math.rad(180) end - return math.atan(y/x) - reduce + return math.atan(vector.y/vector.x) - reduce end