Moving Platforms

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
briancomics
Prole
Posts: 2
Joined: Sun Jun 26, 2022 7:54 pm

Moving Platforms

Post by briancomics »

I am trying to make moving platforms in my game. I followed a video on making platformer physics in Pygame and ported it over to Love2D. It works great for static tiles, but when I tried to implement moving boxes, there are all sorts of odd glitches. I stripped down much of my game to showcase the bug. The goal is to get to the upper island. You can walk with A and D, jump with W or Space, and rewind time by holding Left Shift. The solution is to stand on the box and rewind time to ride it upwards. Most of it works, but there are some bugs. Here are some notable ones.
  • Rewind time, stand under the box, and let it crush you. The player will instead teleport on top.
  • Ride the box to the top and try to walk onto the platform. There seems to be a small invisible wall that stops you from leaving while time is rewinded.
  • Ride the box to the top, get off the box by jumping, and try to walk onto the box. You continuously get teleported back.
I don't know how to patch these bugs despite trying multiple times. For example, the second bug. There isn't a small step or anything stopping the player from leaving. It just can't for some reason. I think the current system I'm using isn't meant to support moving rects, but I also haven't found any other system I can use.
Attachments
mvp.love
(5.01 KiB) Downloaded 50 times
User avatar
marclurr
Party member
Posts: 101
Joined: Fri Apr 22, 2022 9:25 am

Re: Moving Platforms

Post by marclurr »

I had a look over your code and added a bit of simple debugging and here's what I found:

The first problem is because your box is not checking collision with the player. You're applying gravity every frame then calling your collision resolution. velocityY will always be positive unless the player is jumping so the first condition is handling resolution between both the tile below the player and the box above it.

Code: Select all

function player:move (velocityX, velocityY)
	self.rect.y = self.rect.y + velocityY
	overlaps = self.rect:overlaps(level.collidableRects)
	for _, overlap in pairs(overlaps) do
		self.velocity.y = 0
		if velocityY > 0 then
			self.rect.y = overlap.y - self.rect.height
		elseif velocityY < 0 then
			self.rect.y = overlap.y + overlap.height
		end
	end
	...
end
I added the below into levelManager.lua, in the player setup code and this now works roughly as expected:

Code: Select all

table.insert(level.collidableRects, player.rect)

Your second and third behaviours are because your past positions are not recorded accurately. When I ran it with some debugging the oldest position for the box I saw was usually at around (120,~80.007...), meaning it's not perfectly flush with the tile next to it. You can't see it in the rendering because it's at sub-pixel level but it has an influence on the collision overlaps. Personally I'd implement something to handle these small offsets when moving horizontally along the ground, so that the player is pushed up if the offset is below some threshold. If you want to try something quick and dirty, doing the overlap calculations in 'pixel-spaces' by rounding up or down to the nearest whole value might give a decent result (haven't tried it though).

Edit: The fix for the box landing on the player has an interesting side-effect. That position is now recorded so when you rewind, the box appears to be stuck in mid-air :)
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

Re: Moving Platforms

Post by pgimeno »

To solve the second issue:

Code: Select all

        -- change this line in Box:new:
        self.pastPositions = {}
        -- to this:
        self.pastPositions = {{self.rect.x, self.rect.y,self.velocity.x,self.velocity.y}}
That records the original position of the box, before the first timestep, so when you rewind, the box will actually be where it began. This also solves the third issue, but that one should not be happening in the first place, so it's worth investigating. These issues tend to come back to bite you in the butt if you just ignore them.
User avatar
marclurr
Party member
Posts: 101
Joined: Fri Apr 22, 2022 9:25 am

Re: Moving Platforms

Post by marclurr »

It's just occurred to me the third problem (teleporting) is probably caused because the box and the tile are box colliding with the player in the y axis, but because the box is handled last that value is being used as the 'new y' of the player, then when solving for the the x axis the player is still inside the tile and moving to the right so is pushed to the left of that tile. You can probably fix that by using the lowest y value as the true new y. The below actually fixes the third problem, but you'd probably want to tidy it up:

Code: Select all

		
if velocityY > 0 then
    self.rect.y = math.min(self.rect.y, overlap.y - self.rect.height)
elseif ...
briancomics
Prole
Posts: 2
Joined: Sun Jun 26, 2022 7:54 pm

Re: Moving Platforms

Post by briancomics »

marclurr wrote: Sun Jul 03, 2022 10:19 am Edit: The fix for the box landing on the player has an interesting side-effect. That position is now recorded so when you rewind, the box appears to be stuck in mid-air :)
The interesting side effect is actually working as needed! There are some puzzles later where the player will need to use their own body to stop a box from falling. Thank you for the fix! I am a bit embarrassed I didn't realize the issue since it was so simple, but now it's working as expected!
pgimeno wrote: Sun Jul 03, 2022 10:28 am That records the original position of the box, before the first timestep, so when you rewind, the box will actually be where it began.
This is another issue I probably should have spotted in hindsight. I just thought that since I couldn't notice any difference on the screen and the box seemed to be level with the platform, they were on the same y level. Turns out, the small deltaTime while the level is loading makes the box a bit lower by a few hundredths of a pixel. I am still not sure why the teleporting bug happens, but I'll try to look into it. Thank you for the really simple and elegant fix!
User avatar
marclurr
Party member
Posts: 101
Joined: Fri Apr 22, 2022 9:25 am

Re: Moving Platforms

Post by marclurr »

briancomics wrote: Sun Jul 03, 2022 2:18 pm I am still not sure why the teleporting bug happens, but I'll try to look into it.
My second post has a fix for the teleporting bug put it in your player:move method. It may not elegantly handle some other edge cases though so it would be worth keeping an eye on anything that looks hard to explain physics-wise.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 51 guests