Struggling with jumping function in platformer

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
MaxGamz
Party member
Posts: 107
Joined: Fri Oct 28, 2022 3:09 am

Struggling with jumping function in platformer

Post by MaxGamz »

I decided to try to make my own platformer without using any libraries. I'm doing this project so that I won't be too dependent on libraries to get the work done and I want to genuinely improve my coding skills. One problem I am facing is with jumping and checking in the character is grounded. The thing that has been confusing me is that I am able to get the character to land perfectly but not jump, but when I am able to get the character to jump, it clips through the wall. I tried using a grounded function so it stops moving when it lands, but I came accross this problem...

Code: Select all

function isGrounded(gamer, obst)
    for val, obst in ipairs(obst) do
        if collide(gamer, obst) and (obst.y > gamer.y) then
            return true
        end
    end
end

function slide(gamer, obst)
    if collide(gamer, obst) then
        local sepX = math.abs((gamer.x + gamer.w / 2)-(obst.x + obst.w / 2))
        local sepY = math.abs((gamer.y + gamer.w / 2)-(obst.y + obst.w / 2))

        --collision resolution
        if sepX > sepY then
            gamer.xVel = 0
        else
            --relavent section
            if isGrounded(gamer, obst) then
                gamer.y = obst.y - gamer.w
                gamer.yVel = 0
            end
        end
    end
end
for some reason, when I use this function in the collision resolution, the player falls through the entire map, however when I try how I did it normally like this

Code: Select all

else
            --relavent section
            if obst.y > gamer.y then
                gamer.y = obst.y - gamer.w
                gamer.yVel = 0
            end
it lands perfectly even though the grounded function has essentially the exact same conditions as the latter. I'm not sure why this is the case
PlatformerTest.love
(1.23 KiB) Downloaded 103 times
User avatar
knorke
Party member
Posts: 274
Joined: Wed Jul 14, 2010 7:06 pm
Contact:

Re: Struggling with jumping function in platformer

Post by knorke »

Code: Select all

function love.keypressed(key, scancode)
    if scancode == "w" then
        local obsts = {wall, wall2}
        if isGrounded(player, obsts) then
            print("Eagle has landed")
            player.yVel = -5
        end
    end
end
You have this code in love.keypressed(key, scancode) so collision is only checked when the "w" is pressed.
You want to always check collisions.

I moved the isGrounded() check to the end of love.update() and it worked.
(The player bounces upwards when hitting a wall)

/edit:
Ah, I see what you mean. You want collres() and slide() function to handle the collision.


1) Sometimes obst is used as a table of obstacles and sometimes it is a single object. You mix both.
In slide() obst is only a single obstacle (you use obst.x) but then you pass that single object to isGrounded()
However isGrounded() wants a table in the form of [1]=wall,[2]=wall2 etc.
(So ipairs can loop through all elements).
But the loop never executes (use a print to check) because instead a single wall/obst is passed.
This works, note the {obst} to create a table that isGrounded() can work with.

Code: Select all

function slide(gamer, obst)
            if isGrounded(gamer, {obst}) then
                gamer.y = obst.y - gamer.w
                gamer.yVel = 0
            end
For test I moved that code to the top of slide() function.
It works there. But it does not work when placed within the two if's where you originally had it.
(Not sure what is wrong there)

2)

Code: Select all

        local sepY = math.abs((gamer.y + gamer.w / 2)-(obst.y + obst.w / 2))
I think you want gamer.h and obst.h here?

3) In function collres(...) you have:

Code: Select all

        gamer.yVel = gamer.yVel + gravity*dt
So every time you check collision with a wall, gravity is applied one more time to the player.
(One wall: player falls normal. Two walls: player falls twice as fast. 3 walls = tripple fall speed. ...)
MaxGamz
Party member
Posts: 107
Joined: Fri Oct 28, 2022 3:09 am

Re: Struggling with jumping function in platformer

Post by MaxGamz »

knorke wrote: Mon May 20, 2024 8:11 pm

Code: Select all

function love.keypressed(key, scancode)
    if scancode == "w" then
        local obsts = {wall, wall2}
        if isGrounded(player, obsts) then
            print("Eagle has landed")
            player.yVel = -5
        end
    end
end
You have this code in love.keypressed(key, scancode) so collision is only checked when the "w" is pressed.
You want to always check collisions.

I moved the isGrounded() check to the end of love.update() and it worked.
(The player bounces upwards when hitting a wall)

/edit:
Ah, I see what you mean. You want collres() and slide() function to handle the collision.


1) Sometimes obst is used as a table of obstacles and sometimes it is a single object. You mix both.
In slide() obst is only a single obstacle (you use obst.x) but then you pass that single object to isGrounded()
However isGrounded() wants a table in the form of [1]=wall,[2]=wall2 etc.
(So ipairs can loop through all elements).
But the loop never executes (use a print to check) because instead a single wall/obst is passed.
This works, note the {obst} to create a table that isGrounded() can work with.

Code: Select all

function slide(gamer, obst)
            if isGrounded(gamer, {obst}) then
                gamer.y = obst.y - gamer.w
                gamer.yVel = 0
            end
For test I moved that code to the top of slide() function.
It works there. But it does not work when placed within the two if's where you originally had it.
(Not sure what is wrong there)

2)

Code: Select all

        local sepY = math.abs((gamer.y + gamer.w / 2)-(obst.y + obst.w / 2))
I think you want gamer.h and obst.h here?

3) In function collres(...) you have:

Code: Select all

        gamer.yVel = gamer.yVel + gravity*dt
So every time you check collision with a wall, gravity is applied one more time to the player.
(One wall: player falls normal. Two walls: player falls twice as fast. 3 walls = tripple fall speed. ...)
Sorry but do you suggest I try a new method? The one I was originally working on uses the seperation of both bodies and it doesn't seem to work with love. I'm trying to use a new methoed that takes in normal vectors to resolve collisions, and while I have soem success it is still having some issues.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 4 guests