Vertical Movement Platform - Glue

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
brenus
Prole
Posts: 5
Joined: Sat Dec 03, 2022 4:33 pm

Vertical Movement Platform - Glue

Post 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
Image

no player
Image

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.
User avatar
BrotSagtMist
Party member
Posts: 657
Joined: Fri Aug 06, 2021 10:30 pm

Re: Vertical Movement Platform - Glue

Post by BrotSagtMist »

Id say if there is a touch simply replace the player.
obey
User avatar
darkfrei
Party member
Posts: 1197
Joined: Sat Feb 08, 2020 11:09 pm

Re: Vertical Movement Platform - Glue

Post 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)
Last edited by darkfrei on Fri Dec 09, 2022 8:05 pm, edited 1 time in total.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
brenus
Prole
Posts: 5
Joined: Sat Dec 03, 2022 4:33 pm

Re: Vertical Movement Platform - Glue

Post 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

User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Vertical Movement Platform - Glue

Post 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.
brenus
Prole
Posts: 5
Joined: Sat Dec 03, 2022 4:33 pm

Re: Vertical Movement Platform - Glue

Post 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
User avatar
pgimeno
Party member
Posts: 3656
Joined: Sun Oct 18, 2015 2:58 pm

Re: Vertical Movement Platform - Glue

Post 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
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 3 guests