Infinite Runner Collision problem

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
FrenchAssassinX
Prole
Posts: 4
Joined: Thu Jun 27, 2019 10:10 am

Infinite Runner Collision problem

Post by FrenchAssassinX »

Hi coders !

I'm currently working on an Infinite Runner 2D game. Actually I've great problem with Love2D CheckCollision function. Let me explain :

My player has different states like isStanding, isFalling, each steps defines a different animations for the player and his velocity.

In my Update function I want to verify if my player isColliding with some tile. If that's the case, I want to change the state of my player to isStanding. This part is fine, everything works.
Also in my Update function, I want to detect when my player is not on a tile and then change his state to isFalling, but it's not works.

After few hours of tests and debugs, I have understand what is the problem but I don't now how to solve it. Here's my code for what I've explain above :

Code: Select all

    for n=1, #listTiles do
            local tile = listTiles[n]
            -- Updating tiles speed
            --tile.vx = tile.vx + tile.speed * dt
            -- Move
            --tile.x = tile.x - tile.vx * dt

            -- if tile is out of screen, delete
            if(tile.x + tile.pic:getWidth() < 0) then
                  tile.toRemove = true
            end

            SetTileCollideBoxes(tile)
            UpdateTileBox(tile)

            for i=1, #pPlayer.collideBox[pPlayer.currentAnimation] do
                  local collideBox = pPlayer.collideBox[pPlayer.currentAnimation][i]

                  -- Fixing player on the top of platform when he's falling
                  collide = CheckCollision(pPlayer.x + collideBox.x, pPlayer.y + collideBox.y, collideBox.w, collideBox.h, tile.collideBox.x, tile.collideBox.y, tile.collideBox.w, tile.collideBox.h)

                  if (collide) then
                        pPlayer.y = tile.collideBox.y - collideBox.h + 10
                        pPlayer.isFalling = false
                  else
                        pPlayer.isFalling = true
                  end
            end
      end
The problem is with collide : the function detect the collision during one second only then it going to false and I've a glitch effect because collide turn to true or false every second. How can I solve this ?

Thank you :cool:
User avatar
NotARaptor
Citizen
Posts: 59
Joined: Thu Feb 22, 2018 3:15 pm

Re: Infinite Runner Collision problem

Post by NotARaptor »

It's because you're checking every collision box of the player, and the result will be dependent on the order you check them in.

I bet if you swapped the order of the (2?) Collision boxes for the player, you'd have the opposite result.

If you want to check if they need to fall, you need to check ALL of the boxes and if at least one didn't then the player doesn't fall one. This corresponds to a boolean AND in logic, and an intersection of the two regions.

If you want to check if they need to stop falling, you need to check if ANY of the boxes collide, as soon as one does you know you can stop. This corresponds to an OR in logic, and a union of the regions.

Your code is very readable and easy to understand :)

Edit: You're also moving the player to the stop point, which further compounds the issue, as then in the same loop you're checking box 1 at time t but box 2 at time t+dt
FrenchAssassinX
Prole
Posts: 4
Joined: Thu Jun 27, 2019 10:10 am

Re: Infinite Runner Collision problem

Post by FrenchAssassinX »

Hi man !

Thanks for your help, I don't exactly understand what I have to do despite of your explanations (I'm french, my english isn't perfect).
How can I check all my Tile Collide Boxes in the same times ? I was thinking that my double FOR could doing the job ? I know the AND and OR in programmation but I don't understand the intersects explanation.

Can you develop please ?
tahoma
Prole
Posts: 22
Joined: Mon Apr 22, 2019 1:13 am

Re: Infinite Runner Collision problem

Post by tahoma »

The issue NotARaptor outlined is that whether the player falls or not essentially depends on the collision check of the very last box:

Code: Select all

if (collide) then
                        pPlayer.y = tile.collideBox.y - collideBox.h + 10
                        pPlayer.isFalling = false
                  else
                        pPlayer.isFalling = true
                  end
pPlayer.isFalling depends purely on the result of the last collision check.
What you want to try instead is to check whether at least one collision is true: you could do that using a local flag or the isFalling flag itself. Eg,

Code: Select all

 
pPlayer.isFalling = true
for ...
if (collide) then
                        pPlayer.y = tile.collideBox.y - collideBox.h + 10
                        pPlayer.isFalling = false
                  end
Note how the isFalling flag does not get overwritten with true.

Another complication might be in the way you define collision function. You might want to: (a) avoid checking for collision with tiles "above" the player; (b) avoid checking for collusion with tiles that are too much to the right/left from the player.
FrenchAssassinX
Prole
Posts: 4
Joined: Thu Jun 27, 2019 10:10 am

Re: Infinite Runner Collision problem

Post by FrenchAssassinX »

Hello tahoma, thanks for your reply. Actually I'm not overwritting the isFalling in my FOR. In your example, you set to true the isFalling outside of the FOR and set to false inside it.
In my code that's the same. I don't understand how can it solve my problem.
tahoma
Prole
Posts: 22
Joined: Mon Apr 22, 2019 1:13 am

Re: Infinite Runner Collision problem

Post by tahoma »

I'm afraid I must disagree. To get a better idea of how your code works, you could try using print() to see the evolution of the value of isFalling. Then, you can try changing the loop and seeing how isFalling evolves after the change.
FrenchAssassinX
Prole
Posts: 4
Joined: Thu Jun 27, 2019 10:10 am

Re: Infinite Runner Collision problem

Post by FrenchAssassinX »

Actually my isFalling value evolve in a different lua files named Player.lua, in this function :

Code: Select all

      
      if (player.isFalling) or (player.isSliding) or (player.doubleJumping) then
            player.isStanding = false
      else 
            player.isStanding = true
      end
I have tried your solution but the problem was the same even if I set the isFalling before my FOR.

I have create two pastebin if anyone can check my code, maybe that's can help to understand exactly what my files doing :
-map.lua : https://pastebin.com/BXUx8Jns
-player.lua : https://pastebin.com/SZkYTLHK

Thanks a lot for all your replies
tahoma
Prole
Posts: 22
Joined: Mon Apr 22, 2019 1:13 am

Re: Infinite Runner Collision problem

Post by tahoma »

The code you sent is not where isFalling evolves (=changes).
+ there are two other issues that people pointed out:
- making sure that you don't check collision with tiles above;
- (most likely suspect) not adjusting vertical position before it's decided whether a player falls or not: ie, first have a loop that checks whether a players is falling, and only then let the player fall
Post Reply

Who is online

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