Page 1 of 1
Vertical Movement Platform - Glue
Posted: Fri Dec 09, 2022 4:41 pm
by brenus
Hi, everyone.
I'm making a platform game and there's a vertical movement platform. My problem is how you guys deal with vertical movement; the player doesn't distance himself from it.
What I'm doing is on the player:
I'm summing up the DeltaPlataformMovement (speedPlataform*dt) on the player's movement when he's on the platform. For example:
Code: Select all
player.physics.body:setY(player.physics.body:getY() + platform.deltaMovementPlatform)
Result (When the platform goes down the player is suspended in the air):
with player
no player
What I tried to improve: increase the fixture of the player; increase the gravity value; add body:applyForce(0, 1000) on the player <- none of them helped me.
I'm using only physics love2d vanilla. Thanks in advance for any insights.
Re: Vertical Movement Platform - Glue
Posted: Fri Dec 09, 2022 4:59 pm
by BrotSagtMist
Id say if there is a touch simply replace the player.
Re: Vertical Movement Platform - Glue
Posted: Fri Dec 09, 2022 4:59 pm
by darkfrei
1) Be sure that you update platform before update of player.
2) Why not hard placing as player.y = platform.y - player.height? (while standing on the platform)
(Update: you are right, must be minus height)
Re: Vertical Movement Platform - Glue
Posted: Fri Dec 09, 2022 6:53 pm
by brenus
BrotSagtMist wrote: ↑Fri Dec 09, 2022 4:59 pm
Id say if there is a touch simply replace the player.
I don't understand well, what is "touch simply"? (I'm beginner)
---
darkfrei wrote: ↑Fri Dec 09, 2022 4:59 pm
1) Be sure that you update platform before update of player.
2) Why not hard placing as player.y = platform.y + player.height? (while standing on the platform)
1) I've tried to move the platform first, but I think the coordinates became from world:update(dt), not?
2) I've tried, but maybe I'm missing something (btw it's not - player.height no? because + is below the platform?). And this approach do I have to designate another collider only on the surface?
---
Maybe this code with a simple implementation from my game could be useful:
Code: Select all
local world
Player = {}
local Platform = {}
local deltaMovement = 0
WIDTH = love.graphics.getWidth()
HEIGHT = love.graphics.getHeight()
-- Player
local function jump()
Player.physics.body:applyLinearImpulse(0, -2000)
end
local function move(dt)
if Player.isMovementPlatformY then
--Player.physics.body:setY(Platform.physics.body:getY() - 80)
Player.physics.body:setY(Player.physics.body:getY() + deltaMovement)
end
end
-- Platform
local function platformMove(dt)
local _, py = Platform.physics.body:getPosition()
deltaMovement = Platform.dir * 100 * dt
Platform.physics.body:setY(py + deltaMovement)
Platform.distActual = Platform.distActual + math.abs(deltaMovement)
if Platform.distActual >= Platform.distLimit then
Platform.dir = Platform.dir * -1
Platform.distActual = 0
end
end
function love.load()
-- physics
world = love.physics.newWorld(0, 1000, false)
world:setCallbacks(beginContact, endContact, preSolve, postSolve)
-- PLAYER
Player.isJumping = false
Player.isGrounded = true
Player.isMovementPlatformY = false
-- Physics
Player.physics = {}
Player.physics.body = love.physics.newBody(world, WIDTH/2, HEIGHT/2, "dynamic")
Player.physics.body:setFixedRotation(true)
Player.physics.shape = love.physics.newRectangleShape(40, 80)
Player.physics.fixture = love.physics.newFixture(Player.physics.body,
Player.physics.shape, 1)
Player.physics.fixture:setUserData("Player")
-- PLATFORM
-- Physics
Platform.physics = {}
Platform.physics.body = love.physics.newBody(world, WIDTH/2, HEIGHT/2 + 100, "static")
Platform.physics.shape = love.physics.newRectangleShape(100, 20)
Platform.physics.fixture = love.physics.newFixture(Platform.physics.body,
Platform.physics.shape)
Platform.dir = 1
Platform.physics.fixture:setUserData("Platform")
Platform.distActual = 0
Platform.distLimit = 100
end
function love.update(dt)
world:update(dt)
platformMove(dt) -- Platform
move(dt) -- Player
end
function love.draw()
debug()
end
function beginContact(a, b, coll)
if a:getUserData() > b:getUserData() then a, b = b, a end
if (a:getUserData() == "Platform" and b:getUserData() == "Player") then
Player.isJumping = false
Player.isGrounded = true
Player.isMovementPlatformY = true
end
end
function endContact(a, b, coll)
if a:getUserData() > b:getUserData() then a, b = b, a end
if (a:getUserData() == "Platform" and b:getUserData() == "Player") then
Player.isJumping = true
Player.isGrounded = false
Player.isMovementPlatformY = false
end
end
function preSolve(a, b, coll)
if a:getUserData() > b:getUserData() then a, b = b, a end
if (a:getUserData() == "Platform" and b:getUserData() == "Player") then
Player.isJumping = false
Player.isGrounded = true
end
end
function postSolve(a, b, coll, normalimpulse, tangentimpulse)
end
-- Keyboard
function love.keypressed(key)
if key == "w" or key == "up" then
jump()
end
end
function debug()
-- Debug
for _, body in pairs(world:getBodies()) do
for _, fixture in pairs(body:getFixtures()) do
local shape = fixture:getShape()
if shape:typeOf("CircleShape") then
local cx, cy = body:getWorldPoints(shape:getPoint())
love.graphics.circle("fill", cx, cy, shape:getRadius())
elseif shape:typeOf("PolygonShape") then
love.graphics.polygon("fill", body:getWorldPoints(shape:getPoints()))
else
love.graphics.line(body:getWorldPoints(shape:getPoints()))
end
end
end
end
Re: Vertical Movement Platform - Glue
Posted: Fri Dec 09, 2022 8:41 pm
by pgimeno
A platform that accelerates faster than the player will always outrun the player's fall, that's just how the world works. If the platform's speed changes from 0 to a finite value without a transition, the acceleration is infinite, and that means the player is not supposed to catch up with the platform, i.e. the player will be suspended in air for a moment.
By the way, platforms are usually made kinematic. Static sounds like the wrong type.
Re: Vertical Movement Platform - Glue
Posted: Sun Dec 11, 2022 7:50 pm
by brenus
pgimeno wrote: ↑Fri Dec 09, 2022 8:41 pm
A platform that accelerates faster than the player will always outrun the player's fall, that's just how the world works. If the platform's speed changes from 0 to a finite value without a transition, the acceleration is infinite, and that means the player is not supposed to catch up with the platform, i.e. the player will be suspended in air for a moment.
By the way, platforms are usually made kinematic. Static sounds like the wrong type.
Thank you for your insights, and you're right I didn't know about the kinematic type.
About the vertical platform, I'm giving up for now because it's driving me crazy haha I'll think of another way to do that
Re: Vertical Movement Platform - Glue
Posted: Wed Dec 14, 2022 7:22 pm
by pgimeno
Here's an example of an object on a kinematic platform:
Code: Select all
local lp = love.physics
local lg = love.graphics
local platvel = 50
local world = lp.newWorld(0, 600)
local function newObject(body, shape)
return {body = body, shape = shape, fixture = lp.newFixture(body, shape)}
end
local player = newObject(lp.newBody(world, 400, 300, "dynamic"),
lp.newRectangleShape(40, 60))
local platform = newObject(lp.newBody(world, 400, 350, "kinematic"),
lp.newRectangleShape(100, 10))
platform.body:setLinearVelocity(0, platvel)
function love.keypressed(k)
if k == "escape" then return love.event.quit() end
end
function love.update(dt)
world:update(dt)
if platform.body:getY() > 450 then
platform.body:setPosition(400, 450)
platform.body:setLinearVelocity(0, -platvel)
elseif platform.body:getY() < 350 then
platform.body:setPosition(400, 350)
platform.body:setLinearVelocity(0, platvel)
end
end
function love.draw()
lg.polygon("fill", player.body:getWorldPoints(player.shape:getPoints()))
lg.polygon("fill", platform.body:getWorldPoints(platform.shape:getPoints()))
end