In my code for friction, there's is a small issue that I'm not sure how to fix efficiently.
It does what it is supposed to do, it creates a force with a given magnitude and opposite direction to the motion.
The problem is that when my player starts decelerating and the velocity is very close to zero, it never really stays at zero w it becomes negative and then positive again alternating between the two every new tick, resulting in very small movements in the player when he should be stopped.
This happens because of the way I coded the
Code: Select all
local friction = vector2.mult(player.velocity, -1)
This is my code for the player:
Code: Select all
-- everything player related
player = {
position = vector2.new(100, 800-(304+65)),
velocity = vector2.new(0, 0),
width = 30,
height = 65,
maxspeed= vector2.new(400, 800),
frictioncoefficient = 400,
--maxspeedair = vector2.new(50,800),
mass = 1,
onGround = false
}
function UpdatePlayer(dt)
print(player.velocity.x)
local acceleration = vector2.new(0, 0)
local gravity = vector2.new(0, 1000)
acceleration = vector2.applyForce(gravity, player.mass, acceleration) -- applying gravity to the player
local friction = vector2.mult(player.velocity, -1) -- The problem comes from here
friction = vector2.normalize(friction)
friction = vector2.mult(friction, player.frictioncoefficient)
acceleration = vector2.applyForce(friction, player.mass, acceleration) -- applying friction to the player
local movedirection = vector2.new(0, -1)
--Movement imput start
if love.keyboard.isDown("right") then
local move = vector2.new(1600, 0)
acceleration = vector2.applyForce(move, player.mass, acceleration)
movedirection.x = 1
end
if love.keyboard.isDown("left") then
local move = vector2.new(-1600, 0)
acceleration = vector2.applyForce(move, player.mass, acceleration)
movedirection.x= -1
end
if (player.onGround) then
if love.keyboard.isDown("up") then
local jump = vector2.new(0, -40000)
acceleration = vector2.applyForce(jump, player.mass, acceleration)
movedirection.y = 1
player.onGround = false
end
end
-- MOvement input end
local futurevelocity = vector2.add(player.velocity,vector2.mult(acceleration, dt))
futurevelocity = vector2.limit(futurevelocity, player.maxspeed.x)
local futureposition = vector2.add(player.position,vector2.mult(futurevelocity, dt))
acceleration = CheckCollision(world, futureposition, movedirection, acceleration)
player.velocity = vector2.add(player.velocity, vector2.mult(acceleration, dt))
if player.onGround == true then
player.velocity = vector2.limit(player.velocity, player.maxspeed.x)
else
--player.velocity = vector2.limit(player.velocity, vector2.magnitude(player.maxspeed))
if player.velocity.x > 400 then
player.velocity.x = 400
elseif player.velocity.x < -400 then
player.velocity.x = -400
end
end
player.position = vector2.add(player.position, vector2.mult(player.velocity, dt)) -- Player movement
-- Player collision with edges of the window start
if (player.position.x > love.graphics.getWidth() - player.width) then
player.position.x = love.graphics.getWidth() - player.width
player.velocity.x = (player.velocity.x * -1) / 2
elseif (player.position.x < 0) then
player.position.x = 0
player.velocity.x = (player.velocity.x * -1) / 2
end
if (player.position.y > love.graphics.getHeight() - player.height) then
player.position.y = love.graphics.getHeight() - player.height
player.velocity.y = 0
player.onGround = true
end
-- Player collision with edges of the window end
end
function DrawPlayer()
love.graphics.rectangle("fill", player.position.x, player.position.y, player.width, player.height)
end
-- Player collisions start
function CheckCollision(world, futureposition, movedirection, acceleration)
for i = 1, table.getn(world), 1 do
local collisiondir = GetBoxCollisionDirection(futureposition.x, futureposition.y, player.width, player.height, world[i].position.x, world[i].position.y, world[i].size.x, world[i].size.y)
--print(collisiondir.x .. " " .. collisiondir.y)
if (collisiondir.x ~= 0 or collisiondir.y ~= 0) then
if collisiondir.y == movedirection.y then --down collision
player.velocity.y = 0
acceleration.y = 0
player.onGround=true
elseif collisiondir.y == 1 then --up collision
player.velocity.y = 0
acceleration.y = 0
elseif movedirection.x ~= collisiondir.x then --side collision
player.velocity.x = 0
acceleration.x = 0
end
end
end
return acceleration
end
function Death()
if Collided_with_enemy then
love.graphics.print("GAME OVER", 700, 400)
end
end
Code: Select all
-- All vector operations I'll use
vector2 = {}
function vector2.new(px,py)
return {x = px, y = py}
end
function vector2.add(vec, inc)
local result = vector2.new(0,0)
result.x = vec.x + inc.x
result.y = vec.y + inc.y
return result
end
function vector2.sub(vec, dec)
local result = vector2.new(0,0)
result.x = vec.x - dec.x
result.y = vec.y - dec.y
return result
end
function vector2.mult(vec, n)
local result = vector2.new(0,0)
result.x = vec.x * n
result.y = vec.y * n
return result
end
function vector2.div(vec, n)
local result = vector2.new(0,0)
result.x = vec.x / n
result.y = vec.y / n
return result
end
function vector2.magnitude(vec)
local magnitude
magnitude = math.sqrt(vec.x^2 + vec.y^2)
return magnitude
end
function vector2.normalize(vec)
local mag = vector2.magnitude(vec)
if mag ~= 0 then
return vector2.div(vec,mag)
else
return vec
end
end
function vector2.limit(vec, max)
local result = vec
if vector2.magnitude(vec) > max then
result = vector2.normalize(vec)
result = vector2.mult(result, max)
end
return result
end
function vector2.applyForce(force, mass, accelaration)
local f = vector2.div(force, mass)
return vector2.add(accelaration, f)
end