Moving Physics Bodies Issue

I’m currently developing a side scrolling game and I’ve ran into a small problem and was wondering if anyone has had this issue. It happens when my character is standing on a downwards moving platform. When the platform moves down the character standing on the platform begins to hop up and down. I understand why it is happening, because the platform is falling faster than gravity. I’ve tried using a function to set the y values of both the character and platform the same until contact has ended but it is unable to translate inside a collision function. I would appreciate any ideas or feedback on this issue.

Thanks, Chris [import]uid: 53766 topic_id: 35575 reply_id: 335575[/import]

Hi Chris,
How did you try to move the character directly along with the falling platform? Did you use a Runtime listener that runs when the two objects are in contact? I would think this should work: just update the y position of the character dependent on the platform y position… no translate or transition kind of stuff.

Brent [import]uid: 200026 topic_id: 35575 reply_id: 141383[/import]

Sorry translate wasn’t the correct word, more like update. I setup my character to listen for collision events instead of setting up individual events for each platform. Here was my attempt…

[lua]function martian:collision(event)

local phase = event.phase
local other = event.other

if(phase == “began” and other.type == “lift”) then

martian.y = other.y

elseif(phase == “ended” or phase == “cancelled”) then

end

return true

end

martian:addEventListener(“collision”, martian)[/lua]

I removed all my other logic so we can focus on what I’m trying to do. I receive an error message: cannot translate an object before collision is resolved. As I’m looking at this right now I see my problem. “martian.y = other.y” needs to be in a runtime so it is updated as the platform moves. So I guess my question is how can I pass “other or event.other” from this collision to my main runtime function? Like…

[lua]function martian:collision(event)

local phase = event.phase
local other = event.other

if(phase == “began” and other.type == “lift”) then

liftContact = true

elseif(phase == “ended” or phase == “cancelled”) then

end

return true

end

function main()

if(liftContact == true) then

martian.y = other.y – Need to pass this other because I have multiple lifts and platforms I need to use this on.

end

end

Runtime:addEventListener(“enterFrame”, main)
martian:addEventListener(“collision”, martian)[/lua]

Hope I’ve explained it well enough, I would greatly appreciate your feedback on this.

Thanks, Chris [import]uid: 53766 topic_id: 35575 reply_id: 141434[/import]

Hi Chris,
This makes better sense now, thanks for the code. A few comments:

  1. I would suggest you only run the enterFrame listener when the player is on a lift platform. You can just turn it on and off depending on whether the player is on a lift.

  2. It appears that the player won’t know what “other” is, in your code. You should set “other” as a property of the player in the began collision, as something like “martian.platformOn = (its ID)”. Then on the ended phase, you turn off the listener and nil out the property since the martian isn’t on any platform at that point.

  3. The reason you’re getting that warning/error is because physics needs one game cycle to “resolve” certain physical aspects before it can perform actions like re-positioning. The simple solution is to trigger the action after a 10-20 millisecond delay, using “timer.performWithDelay()”. This will ensure the translate (or whatever) happens on the next game cycle.

Hope this helps,
Brent [import]uid: 200026 topic_id: 35575 reply_id: 141478[/import]

Thanks for your ideas Brent, using your “martian.platformOn = platformId” I was able to get the function running without an error message. Unfortunately when the lift platform begins its descent via my transition function my character still lifts off the platform and bounces about three times before coming to rest on the still platform. I used print() to verify that my code was firing and everything appeared to be working great. But I did notice that when the platform is moving my character.y (BottomCenterReferencePoint) and platform.y (TopCenterReferencePoint) weren’t exactly the same, only when the platform isn’t moving. I’ve tried just about everything I can think about, any ideas on how I can achieve my desired result?

Thanks, Chris [import]uid: 53766 topic_id: 35575 reply_id: 141640[/import]

Hi Chris,
How did you try to move the character directly along with the falling platform? Did you use a Runtime listener that runs when the two objects are in contact? I would think this should work: just update the y position of the character dependent on the platform y position… no translate or transition kind of stuff.

Brent [import]uid: 200026 topic_id: 35575 reply_id: 141383[/import]

Sorry translate wasn’t the correct word, more like update. I setup my character to listen for collision events instead of setting up individual events for each platform. Here was my attempt…

[lua]function martian:collision(event)

local phase = event.phase
local other = event.other

if(phase == “began” and other.type == “lift”) then

martian.y = other.y

elseif(phase == “ended” or phase == “cancelled”) then

end

return true

end

martian:addEventListener(“collision”, martian)[/lua]

I removed all my other logic so we can focus on what I’m trying to do. I receive an error message: cannot translate an object before collision is resolved. As I’m looking at this right now I see my problem. “martian.y = other.y” needs to be in a runtime so it is updated as the platform moves. So I guess my question is how can I pass “other or event.other” from this collision to my main runtime function? Like…

[lua]function martian:collision(event)

local phase = event.phase
local other = event.other

if(phase == “began” and other.type == “lift”) then

liftContact = true

elseif(phase == “ended” or phase == “cancelled”) then

end

return true

end

function main()

if(liftContact == true) then

martian.y = other.y – Need to pass this other because I have multiple lifts and platforms I need to use this on.

end

end

Runtime:addEventListener(“enterFrame”, main)
martian:addEventListener(“collision”, martian)[/lua]

Hope I’ve explained it well enough, I would greatly appreciate your feedback on this.

Thanks, Chris [import]uid: 53766 topic_id: 35575 reply_id: 141434[/import]

Hi Chris,
This makes better sense now, thanks for the code. A few comments:

  1. I would suggest you only run the enterFrame listener when the player is on a lift platform. You can just turn it on and off depending on whether the player is on a lift.

  2. It appears that the player won’t know what “other” is, in your code. You should set “other” as a property of the player in the began collision, as something like “martian.platformOn = (its ID)”. Then on the ended phase, you turn off the listener and nil out the property since the martian isn’t on any platform at that point.

  3. The reason you’re getting that warning/error is because physics needs one game cycle to “resolve” certain physical aspects before it can perform actions like re-positioning. The simple solution is to trigger the action after a 10-20 millisecond delay, using “timer.performWithDelay()”. This will ensure the translate (or whatever) happens on the next game cycle.

Hope this helps,
Brent [import]uid: 200026 topic_id: 35575 reply_id: 141478[/import]

Thanks for your ideas Brent, using your “martian.platformOn = platformId” I was able to get the function running without an error message. Unfortunately when the lift platform begins its descent via my transition function my character still lifts off the platform and bounces about three times before coming to rest on the still platform. I used print() to verify that my code was firing and everything appeared to be working great. But I did notice that when the platform is moving my character.y (BottomCenterReferencePoint) and platform.y (TopCenterReferencePoint) weren’t exactly the same, only when the platform isn’t moving. I’ve tried just about everything I can think about, any ideas on how I can achieve my desired result?

Thanks, Chris [import]uid: 53766 topic_id: 35575 reply_id: 141640[/import]

Hi Chris,
I have a feeling that the martian still “bounces” a bit because, by the collision logic, he collides but then immediately “exits” the platform then, collides again, then exits, etc… this occurs a few times as the martian comes to a rest on the platform. When it comes to side-scroller platforms, it’s tricky to determine when something is “on the ground” if you use just the platform itself. Some developers solve this by adding a thin sensor region below the “feet” of the character, and when that region overlaps the ground, they know the character is approximately on the ground. You might want to try this and see if that solves the bouncing issue.

As for updating position, instead of accessing reference points, I would just say the martian’s updated Y position should be the platform’s Y position minus half its height, minus half the martian’s height. This deals with center reference on both objects.

Brent [import]uid: 200026 topic_id: 35575 reply_id: 142389[/import]

Hi Chris,
I have a feeling that the martian still “bounces” a bit because, by the collision logic, he collides but then immediately “exits” the platform then, collides again, then exits, etc… this occurs a few times as the martian comes to a rest on the platform. When it comes to side-scroller platforms, it’s tricky to determine when something is “on the ground” if you use just the platform itself. Some developers solve this by adding a thin sensor region below the “feet” of the character, and when that region overlaps the ground, they know the character is approximately on the ground. You might want to try this and see if that solves the bouncing issue.

As for updating position, instead of accessing reference points, I would just say the martian’s updated Y position should be the platform’s Y position minus half its height, minus half the martian’s height. This deals with center reference on both objects.

Brent [import]uid: 200026 topic_id: 35575 reply_id: 142389[/import]