[NOT SOLVED YET...] Platformer Collisions
by Zilla · in Torque Game Builder · 12/04/2009 (4:17 pm) · 27 replies
I am currently working on a game where the player has to jump from platform to platform.
The platforms are moving from the bottom to the top of the screen.

I think you get the picture ;)
The game is based on the mini platformer demo from TDN. At the beginning of the game when the platforms move quite slowly, everything is o.k.

But when I increase the vertical velocity of the moving platforms, the player sinks into the ground, as if the collision polygon was smaller now.

What could I do to correct this?
The platforms are moving from the bottom to the top of the screen.

I think you get the picture ;)
The game is based on the mini platformer demo from TDN. At the beginning of the game when the platforms move quite slowly, everything is o.k.

But when I increase the vertical velocity of the moving platforms, the player sinks into the ground, as if the collision polygon was smaller now.

What could I do to correct this?
#2
Do I understand this correctly? You think that I should throw my applied clamp collision physics over board and develop a custom physics/movement?
12/05/2009 (4:08 am)
Quote:Then when you move the platform upward, you apply the same upward movement to the objects in the set too.
Do I understand this correctly? You think that I should throw my applied clamp collision physics over board and develop a custom physics/movement?
#3
-or even better:
What does cause this strange behaviour? If I could solve this problem it would spare me a little hard work to write a custom physics "engine" for this little game because the built-in physics works perfectly for this project...
12/05/2009 (11:34 am)
Is there a resource, tutorial or example of a similar game out there that I could study?-or even better:
What does cause this strange behaviour? If I could solve this problem it would spare me a little hard work to write a custom physics "engine" for this little game because the built-in physics works perfectly for this project...
#4
www.youtube.com/watch?v=Sz4JK8S88Nk
12/08/2009 (9:42 am)
Here is a video that illustrates this problem:www.youtube.com/watch?v=Sz4JK8S88Nk
#5
A possible solution would be to reposition the player to sit on top of the platform after the collision had occurred.
Try looking at the castCollision() method in the mini-platformer code from t2dSceneObject, which gives the X and Y position of the collision. An alternative would be to use a ray cast from the player's position to the platform top using the pickLine() method found in t2dSceneGraph.
Using object mounting from inside the code might also be able to do it. Altough I can't be sure as I'm trying to fix a similar problem while using the same mini-platformer code. I'm also new to using TGB.
12/08/2009 (1:26 pm)
I think it is an over-stepping effect. I've had this effect before in another engine. By the time the collision between the player and platform is checked the player has already moved below the platform top. It's at this point that the system updates the player to stop falling. The faster the velocity the bigger the overstep, basically because velocity is an ever increasing number and not fixed.A possible solution would be to reposition the player to sit on top of the platform after the collision had occurred.
Try looking at the castCollision() method in the mini-platformer code from t2dSceneObject, which gives the X and Y position of the collision. An alternative would be to use a ray cast from the player's position to the platform top using the pickLine() method found in t2dSceneGraph.
Using object mounting from inside the code might also be able to do it. Altough I can't be sure as I'm trying to fix a similar problem while using the same mini-platformer code. I'm also new to using TGB.
#6
12/08/2009 (7:45 pm)
I think the first idea thinks, and sounds good to me, tho I am a rookie programmer but from an engineering standpoint it sounds pretty good. Platform somehow calls any object (including your player) when on it. So when it moves, or does something, those same "things" (forces) can be applied to your player thus preventing him from sinking. It basically negates the problem as they will always be in the same position relative to each other.
#7
Thank you! That was it :)))
I was able to solve it like this in
function playerClass::onUpdate(%this)
My only problem now is that this is done in every onUpdate call and therefore you can see that the player is shaking a little bit from time to time.
What I'd like to do is that this setPosition is executed only once, when the player hits the platform for the first time.
Is there a clever way to solve this?
12/10/2009 (10:07 am)
@DavidQuote:A possible solution would be to reposition the player to sit on top of the platform after the collision had occurred.
Thank you! That was it :)))
I was able to solve it like this in
function playerClass::onUpdate(%this)
//Check for a collision %collision = %this.castCollision(0.005); //Get the collision object %collisionObject = getWord(%collision, 0); //Set the player's new position in relation to the collided object %positionY = %collisionObject.getPositionY()-36; %this.setPositionY(%positionY);
My only problem now is that this is done in every onUpdate call and therefore you can see that the player is shaking a little bit from time to time.
What I'd like to do is that this setPosition is executed only once, when the player hits the platform for the first time.
Is there a clever way to solve this?
#8
I never dug deep enough to figure out what the differences were but the PSK on works much better. The vanilla TGB also had problem where when the platforms really started moving, the player would sink into them.
Here is the a link to the straight TGB prototype. If you're interested in the PSK one, I can't give you the code but I can give you a compiled version. Although that won't be much help. Maybe Phil could shed some light though.
Either way, feel free to use some of that code if you see fit.
12/10/2009 (5:56 pm)
I created two prototypes of a concept that is very similar to this. The first one using TGB's built in collision system and the second using the Platformer Starter Kit.I never dug deep enough to figure out what the differences were but the PSK on works much better. The vanilla TGB also had problem where when the platforms really started moving, the player would sink into them.
Here is the a link to the straight TGB prototype. If you're interested in the PSK one, I can't give you the code but I can give you a compiled version. Although that won't be much help. Maybe Phil could shed some light though.
Either way, feel free to use some of that code if you see fit.
#9
12/10/2009 (6:26 pm)
One of the things you need to ensure is that the Player is updated *after* the Platform. You will need to do this in source but all you do is let TGB know what gets updated when:// Call this from the Player when it lands on a Platform. processLinkAfter( myPlatformObject );The Platformer Kit then introduces the notion of "inherited velocity". That is, force which is being applied to the player from an outside source. In this case, when the player is standing on a platform it "inherites" its velocity. The equation for the player's own speed becomes:
linearVelocity = ( movementSpeed + inheritedVelocity )There really is no need for the castCollision call when you use this approach and it is far more efficient to deal with, especially on a device like the iPhone.
#10
so, assuming this is your onUpdate function...
This is only my guess, and it may contain HEAVY logical errors. Gice it a try and let me know :)
12/10/2009 (6:56 pm)
Try adding a flag "isFirstCollision"so, assuming this is your onUpdate function...
//if I'm moving down...
if(%this.getLinearVelocityY()<0){
//Then I will be hitting the floor for the first time
$isFirstCollision=true;
}
//if it's my first collision
if($isfirstCollision){
//Check for a collision
%collision = %this.castCollision(0.005);
//Get the collision object
%collisionObject = getWord(%collision, 0);
//Set the player's new position in relation to the collided object
%positionY = %collisionObject.getPositionY()-36;
%this.setPositionY(%positionY);
//It's no longer my first collision. This block of code won't execute until after I've resumed "falling" again.
$isFirstCollision=false;}This is only my guess, and it may contain HEAVY logical errors. Gice it a try and let me know :)
#11
Thank you very much for your version of a RapidRoll clone :)
As far as I could see in the source, you didn't have the same problems as me, because your platforms do not move as fast as mine and you more or less adapted the code from the mini platformer tutorial. But I will have another, closer look att your game.
12/11/2009 (4:36 am)
@PatrickThank you very much for your version of a RapidRoll clone :)
As far as I could see in the source, you didn't have the same problems as me, because your platforms do not move as fast as mine and you more or less adapted the code from the mini platformer tutorial. But I will have another, closer look att your game.
#12
I was trying to implement your ideas but either this is not the solution for my fast moving platforms or maybe I made some mistakes...
12/11/2009 (4:51 am)
@PhillipI was trying to implement your ideas but either this is not the solution for my fast moving platforms or maybe I made some mistakes...
#13
I was also experimenting with a "firstContact" flag, but the problem is that onUpdate will be called very often and the flag will be reset to TRUE quite all the time...
I was also trying to create a platformClass and implement the flag there, but it does not seem to work...
12/11/2009 (4:54 am)
@DanielI was also experimenting with a "firstContact" flag, but the problem is that onUpdate will be called very often and the flag will be reset to TRUE quite all the time...
I was also trying to create a platformClass and implement the flag there, but it does not seem to work...
function platformClass::onLevelLoaded(%this, %scenegraph)
{
$firstContact = true;
}
function platformClass::onUpdate(%this)
{
%collision = %this.castCollision(0.005);
%collisionObject = getWord(%collision, 0);
if ($firstContact && %collisionObject == "player")
{
$firstContact = false;
%positionY = %this.getPositionY()-36;
$player.setPositionY(%positionY);
}
}
#14
I wouldn't consider it 100% finished yet, but you're welcome to try it out and see if it fixes the collision issue. I got rid of onUpdate and the script turns on gravity only if the player is airborne or walks off a platform. If you still see an over-stepping effect at fast platform speeds, the onCollision callback gives you the ability to execute a one off setPosition, if you add it in.
The behavior is found towards the bottom of the page.
tdn.garagegames.com/wiki/TGB/Tutorials/Platformer/Player
12/11/2009 (7:05 pm)
I've been working on an update to the Creating a Player section of the Platformer tutorial, mainly to get rid of the shaking issue and the animation problems it was causing. The player control functions are now encapsulated in a behavior instead of using the playerClass field.I wouldn't consider it 100% finished yet, but you're welcome to try it out and see if it fixes the collision issue. I got rid of onUpdate and the script turns on gravity only if the player is airborne or walks off a platform. If you still see an over-stepping effect at fast platform speeds, the onCollision callback gives you the ability to execute a one off setPosition, if you add it in.
The behavior is found towards the bottom of the page.
tdn.garagegames.com/wiki/TGB/Tutorials/Platformer/Player
#15
Thank you very much! I downloaded your behaviour and I am currently modifying it for my needs :) I will inform you if am successful :)
12/12/2009 (3:47 pm)
@MikeThank you very much! I downloaded your behaviour and I am currently modifying it for my needs :) I will inform you if am successful :)
#16
Unfortunately, I have to make another post because I did NOT succeed ;)
The original playerClass from the mini platformer tutorial works better for my moving platforms but I still could not solve the flickering player or that he sinks into the platform.
If you want to try this for yourself, you can download and test the project here.
The game logic for the player is in playerClass.cs in gameScripts.
I was trying to compensate the sinking of the player into the platform here:
...but then the player will "flicker"...
Do you have an idea how I could avoid this?
12/13/2009 (3:36 pm)
@Mike and everyone else :)Unfortunately, I have to make another post because I did NOT succeed ;)
The original playerClass from the mini platformer tutorial works better for my moving platforms but I still could not solve the flickering player or that he sinks into the platform.
If you want to try this for yourself, you can download and test the project here.
The game logic for the player is in playerClass.cs in gameScripts.
I was trying to compensate the sinking of the player into the platform here:
// on ground with no wall collisions
if (%normalX == 0 && %normalY == -1)
{
// If you uncomment the following lines, the player
// will not sink into the platform, but it will "flicker"...
/*
%collisionObject = getWord(%collision, 0);
%positionY = %collisionObject.getPositionY()-36.5;
%this.setPositionY(%positionY);
*/
%this.airborne = false;
%this.againstLeftWall = false;
%this.againstRightWall = false;
%this.setConstantForceY(0);
%this.setLinearVelocityY(%yVelocity);
return;
}...but then the player will "flicker"...
Do you have an idea how I could avoid this?
#17
Just turning gravity off doesn't stop the flickering as the player and platform continue to collide as the platform pushes up on the player. So I took Phillip's idea of inherited velocity and added that to the script as well. It seems to work well now, regardless of the speed of the platform. The only thing that needs fixing now is the animation function, since it interprets any Y velocity as a jump animation.
12/13/2009 (6:50 pm)
I think I solved it. I believe you will always see the flicker or shake issue with the default TGB clamp physics, but you can work around it. In your project, I got rid of the playerClass and platformClass scripts and went back to the platform controls behavior I worked on. I changed the onCollision callback to this:function PlatformerControlsBehavior::onCollision(%srcObject, %dstObject, %srcRef, %dstRef, %time, %normal, %contacts, %points)
{
// Only turn off gravity if the player's "feet" collide with the ground
%normalY = getWord(%normal, 1);
if (%normalY == -1)
{
// turn gravity off
%srcObject.owner.setConstantForceY(0);
// get the location of the top surface of the platform
%platformPosY = %dstObject.getPositionY();
%platformSizeY = %dstObject.getSizeY() / 2;
%topSurface = %platformPosY - %platformSizeY;
// get the size of the player to place the feet on the top surface of the platform properly
%sizeY = %srcObject.owner.getSizeY() / 2;
%srcObject.owner.setPositionY(%topSurface - %sizeY);
// have the player inherit the velocity of the platform
%platformVelocity = %dstObject.getLinearVelocityY();
%srcObject.owner.setLinearVelocityY(%platformVelocity);
}
%srcObject.updateAnimation();
}Just turning gravity off doesn't stop the flickering as the player and platform continue to collide as the platform pushes up on the player. So I took Phillip's idea of inherited velocity and added that to the script as well. It seems to work well now, regardless of the speed of the platform. The only thing that needs fixing now is the animation function, since it interprets any Y velocity as a jump animation.
#18
The Platformer Kit was designed to tackle most of the problems that developers face while trying to develop a Platform game in TGB. Many hours of work has gone into it so that you don't need to fight TGB to get the simple aspects of your game working.
I'm not just saying this because I developed the kit, I think that all indie developers need to look to time/money saving solutions.
12/13/2009 (7:30 pm)
If you're looking to make money out of this project, you would really be better off purchasing the Platformer Kit. If you view the hours you spent solving this one issue as a cost, then the time taken would probably cost you more than the price of the kit.The Platformer Kit was designed to tackle most of the problems that developers face while trying to develop a Platform game in TGB. Many hours of work has gone into it so that you don't need to fight TGB to get the simple aspects of your game working.
I'm not just saying this because I developed the kit, I think that all indie developers need to look to time/money saving solutions.
#19
Yes, you are right. I used the Torque X Platformer Kit in a similar project for the XNA Dream Build Play 2008 Contest:
www.youtube.com/watch?v=4OFrOoYCbw0
As we all know, my entry did not win but the Platformer Kit was worth every dime :)
By the way you can download this Xbox 360 demo game from my blog:
www.swisskgb.com/blog/
If I encounter more big problems with my little platformer, I will surely buy the TGB version of this kit also :)
12/14/2009 (6:23 am)
@PhillipYes, you are right. I used the Torque X Platformer Kit in a similar project for the XNA Dream Build Play 2008 Contest:
www.youtube.com/watch?v=4OFrOoYCbw0
As we all know, my entry did not win but the Platformer Kit was worth every dime :)
By the way you can download this Xbox 360 demo game from my blog:
www.swisskgb.com/blog/
If I encounter more big problems with my little platformer, I will surely buy the TGB version of this kit also :)
#20
I implemented your platformerControls.cs (works o.k. - and of course needs some adjustments for my game) and I added your onCollision method but the player still sinks into the platform (the faster the platform moves, the deeper he dives...)
I must have overlooked something but I cannot find it :(
If you want to have a look at it, you can download and test the project with your controls here.
12/14/2009 (4:24 pm)
@MikeI implemented your platformerControls.cs (works o.k. - and of course needs some adjustments for my game) and I added your onCollision method but the player still sinks into the platform (the faster the platform moves, the deeper he dives...)
I must have overlooked something but I cannot find it :(
If you want to have a look at it, you can download and test the project with your controls here.
Torque 3D Owner Marc Dreamora Schaerer
Gayasoft
Then when you move the platform upward, you apply the same upward movement to the objects in the set too.
adding / removing to the set could be handled either through the collision callbacks, alternatively through an additional trigger on top of the platform