function to improve entities moving on collisions and fixed accordingly

made math.round()
changed vector() and fixed accordingly
This commit is contained in:
lustlion 2022-03-16 18:50:10 +01:00
parent 4d94cc805d
commit 236e23177d
9 changed files with 189 additions and 113 deletions

View File

@ -36,20 +36,30 @@ function Arrow:drawBackground()
end end
function Arrow:doPhysics() function Arrow:doPhysics()
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then -- horizontal collision
self.pos.x = self.pos.x + self.vel.x self:moveX(
else self.vel.x,
self.stuck = true function()
end self.stuck = true
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then end
self.pos.y = self.pos.y + self.vel.y )
else
self.stuck = true if not self.stuck then
-- vertical collision
self:moveY(
self.vel.y,
function()
self.stuck = true
end
)
end end
if self.stuck then if self.stuck then
self.pos.x = self.pos.x + self.vel.x * (2/3) self.pos.x = self.pos.x + self.vel.x * (2/3)
self.pos.y = self.pos.y + self.vel.y * (2/3) self.pos.y = self.pos.y + self.vel.y * (2/3)
self.vel.x = 0 self.vel.x = 0
self.vel.y = 0 self.vel.y = 0
end end
self:adjustLight()
end end

View File

@ -67,6 +67,13 @@ function CursedBook:doLogic()
elseif self.status == 4 then elseif self.status == 4 then
end 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 end
function CursedBook:handleAnimation() function CursedBook:handleAnimation()
@ -101,15 +108,21 @@ function CursedBook:handleAnimation()
end end
function CursedBook:doPhysics() function CursedBook:doPhysics()
if self.isFlying then -- horizontal collision
local random_x = math.random(-4, 4)/100 self:moveX(
local random_y = math.random(-4, 4)/100 self.vel.x,
self.vel.x = self.vel.x + random_x function()
self.vel.y = self.vel.y + random_y self.vel.x = 0
end end
-- move )
-- vertical collision
self:moveWithCollision() self:moveY(
self.vel.y,
function()
self.vel.y = 0
end
)
-- final position
self:adjustLight() self:adjustLight()
end end

View File

@ -34,7 +34,6 @@ function Fairy:new(x,y)
end end
function Fairy:doLogic() function Fairy:doLogic()
if self:checkVisionLine(main_player,self.vision_range) then if self:checkVisionLine(main_player,self.vision_range) then
self.target.x = main_player.pos.x + main_player.target_offset.x 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_x = self.target.x - self.pos.x
local distance_y = self.target.y - self.pos.y 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) local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if distance < self.range then if distance < self.range then
self.vel.x = self.vel.x * 0.9 local random_x = math.random(-1, 1)
self.vel.y = self.vel.y * 0.9 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 else
self.vel.x = math.cos(angle)*self.speed local random_x = math.random(-6, 6)
self.vel.y = math.sin(angle)*self.speed local random_y = math.random(-6, 6)
end self.vel.x = math.cos(angle)*self.speed + random_x/10
self.particle_timer = self.particle_timer + 1 self.vel.y = math.sin(angle)*self.speed + random_y/10
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)
end end
end end
@ -95,19 +82,42 @@ function Fairy:handleAnimation()
self.body:animate() self.body:animate()
--if self:isCollidingWith(main_player) then self.sprite_tint = {1,0,0} else self.sprite_tint = {1,1,1} end --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: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 end
function Fairy:doPhysics() function Fairy:doPhysics()
local random_x = math.random(-4, 4)/10 -- horizontal collision
local random_y = math.random(-4, 4)/10 self:moveX(
self.vel.x,
self.vel.x = self.vel.x + random_x function()
self.vel.y = self.vel.y + random_y self.vel.x = 0
end
self:moveWithCollision() )
self.vel.x = 0 -- vertical collision
self.vel.y = 0 self:moveY(
self.vel.y,
function()
self.vel.y = 0
end
)
-- final position
self:adjustLight() self:adjustLight()
end end

View File

@ -36,10 +36,6 @@ function HookAnchor:drawBackground()
) )
end end
function HookAnchor:doPhysics()
end
function Fairy:debug() function Fairy:debug()
Entity.debug(self) Entity.debug(self)
end end

View File

@ -44,8 +44,9 @@ function Kupo:doLogic()
self.target.y = main_player.pos.y - main_player.target_offset.y self.target.y = main_player.pos.y - main_player.target_offset.y
local distance_x = self.target.x - self.pos.x local distance_x = self.target.x - self.pos.x
local distance_y = self.target.y - self.pos.y local distance_y = self.target.y - self.pos.y
local distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2) 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 self.draw_bow = false
if distance <= self.range then if distance <= self.range then
if self.hostile == true then if self.hostile == true then
@ -153,7 +154,3 @@ function Kupo:handleAnimation()
) )
end end
end end
function Kupo:doPhysics()
self:moveWithCollision()
end

View File

@ -89,26 +89,32 @@ function Particle:handleAnimation()
end end
end end
function Particle:doPhysics() function Particle:doLogic()
-- adjust speed -- adjust speed
if self.speed_increase ~= 0 then if self.speed_increase ~= 0 then
self.speed = self.speed + self.speed_increase self.speed = self.speed + self.speed_increase
self.vel.x = self.speed * math.cos(self.direction) self.vel.x = self.speed * math.cos(self.direction)
self.vel.y = self.speed * math.sin(self.direction) self.vel.y = self.speed * math.sin(self.direction)
end 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.time ~= nil then
if self.timer >= self.time then self:kill() end if self.timer >= self.time then self:kill() end
end 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() function Particle:debug()
-- draw center CYAN -- draw center CYAN
love.graphics.setColor(0,1,1) love.graphics.setColor(0,1,1)

View File

@ -155,7 +155,7 @@ function Player:doLogic()
end end
-- set dash values -- set dash values
self.dashDirection = getAngleFromVector(horizontal, vertical) self.dashDirection = getAngleFromVector(vector(horizontal, vertical))
self.dash_timer = math.floor(self.dash_time * game.framerate) self.dash_timer = math.floor(self.dash_time * game.framerate)
end end
else else
@ -232,10 +232,10 @@ function Player:doPhysics()
-- hook state -- hook state
if self.is_hooked then if self.is_hooked then
self.move_x = 0 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 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 if Keybind:checkDown(Keybind.move.right) then
hook_angle = hook_angle - self.hook_swing_speed 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) 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.x = self.vel.x + pos_x - self.pos.x
self.vel.y = self.vel.y + pos_y - self.pos.y 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 end
@ -276,24 +281,26 @@ function Player:doPhysics()
end end
-- horizontal collision -- horizontal collision
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then self.wall_hit = 0
self.pos.x = self.pos.x + self.vel.x self:moveX(
self.wall_hit = 0 self.vel.x,
else function()
self.wall_hit = math.sign(self.vel.x) self.wall_hit = math.sign(self.vel.x)
self.vel.x = 0 self.vel.x = 0
end end
)
-- vertical collision -- vertical collision
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then self:moveY(
self.pos.y = self.pos.y + self.vel.y self.vel.y,
else function()
if self.vel.y > 0 then if self.vel.y > 0 then
self.is_on_ground = true self.is_on_ground = true
self.dash_count = self.dash_amount self.dash_count = self.dash_amount
end
self.vel.y = 0
end end
self.vel.y = 0 )
end
-- if u collision w hazard, respawn -- if u collision w hazard, respawn
if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then if self:isCollidingAt(self.pos.x, self.pos.y, LoadedObjects.Hazards) then

View File

@ -5,6 +5,7 @@ function Entity:new(x,y)
local o = {} local o = {}
o.pos = {x = x, y = y} o.pos = {x = x, y = y}
o.move_remainder = {x = 0, y = 0}
o.vel = {x = 0, y = 0} o.vel = {x = 0, y = 0}
o.direction = 0 o.direction = 0
@ -69,24 +70,53 @@ end
function Entity:doLogic() function Entity:doLogic()
end end
function Entity:move() function Entity:moveX(amount, func)
self.pos.x = self.pos.x + self.vel.x self.move_remainder.x = self.move_remainder.x + amount
self.pos.y = self.pos.y + self.vel.y 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 end
function Entity:moveWithCollision() function Entity:moveY(amount, func)
-- horizontal collision self.move_remainder.y = self.move_remainder.y + amount
if not self:isCollidingAt(self.pos.x + self.vel.x, self.pos.y, LoadedObjects.Collisions) then local move = math.round(self.move_remainder.y)
self.pos.x = self.pos.x + self.vel.x if move ~= 0 then
else self.move_remainder.y = self.move_remainder.y - move
self.vel.x = 0 local sign = math.sign(move)
end while math.round(move) ~= 0 do
if not self:isCollidingAt(
-- vertical collision self.pos.x,
if not self:isCollidingAt(self.pos.x, self.pos.y + self.vel.y, LoadedObjects.Collisions) then self.pos.y + sign,
self.pos.y = self.pos.y + self.vel.y LoadedObjects.Collisions
else ) then
self.vel.y = 0 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
end end
@ -120,8 +150,9 @@ function Entity:checkVisionLine(entity,range)
local distance_x = target_x - self.pos.x local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y 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 distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
local is_colliding = true local is_colliding = true
@ -227,8 +258,9 @@ function Entity:checkVisionLineDebug(entity,range)
local distance_x = target_x - self.pos.x local distance_x = target_x - self.pos.x
local distance_y = target_y - self.pos.y 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 distance = math.sqrt(distance_x ^ 2 + distance_y ^ 2)
if distance < range then if distance < range then
@ -277,6 +309,9 @@ function Entity:debug()
end end
end end
function Entity:doPhysics()
end
function Entity:handleAnimation() function Entity:handleAnimation()
end end

View File

@ -8,20 +8,22 @@ function math.sign(x)
end end
end end
function vector(init_x, init_y, final_x, final_y) function math.round(x)
local distance_x = final_x - init_x return math.floor(x+0.5)
local distance_y = final_y - init_y end
return {distance_x, distance_y}
function vector(x, y)
return {x = x, y = y}
end end
function getVectorValue(vector) function getVectorValue(vector)
return math.sqrt(vector[1] ^ 2 + vector[2] ^ 2) return math.sqrt(vector.x ^ 2 + vector.y ^ 2)
end end
function getAngleFromVector(x,y) function getAngleFromVector(vector)
local reduce = 0 local reduce = 0
if x < 0 then if vector.x < 0 then
reduce = math.rad(180) reduce = math.rad(180)
end end
return math.atan(y/x) - reduce return math.atan(vector.y/vector.x) - reduce
end end