- 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.
Moving Platforms
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 2
- Joined: Sun Jun 26, 2022 7:54 pm
Moving Platforms
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.
- Attachments
-
- mvp.love
- (5.01 KiB) Downloaded 63 times
Re: Moving Platforms
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.
I added the below into levelManager.lua, in the player setup code and this now works roughly as expected:
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
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
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
Re: Moving Platforms
To solve the second issue:
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.
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}}
Re: Moving Platforms
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 ...
-
- Prole
- Posts: 2
- Joined: Sun Jun 26, 2022 7:54 pm
Re: Moving Platforms
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!
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!
Re: Moving Platforms
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.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.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot] and 2 guests