Solution for "riding up the walls" in Mini Platform Tutorial
by Vern Jensen · in Torque Game Builder · 09/11/2006 (4:53 pm) · 40 replies
After many hours experimeting, I have found a solution to the "riding up the walls" problem in the Mini Platform Tutorial. I've posted this in a new thread, so that other threads can reference this thread, and people wont' have to dig down to the 30th message to find this.
The solution is to change the custom collision poly just before doign castCollision, insetting the left/right sides somewhat, so that castCollision won't detect walls to our left or right. The restore the custom collision poly when done.
[code]
// Inset the collision poly's left/right sides a little bit before doing castCollision, so
// that castCollision truly is checking for something BELOW us.
$pGuy.setCollisionPolyCustom( 4, "-0.80 -0.358", "0.60 -0.358", "0.60 0.975", "-0.80 0.975" );
%collision = $pGuy.castCollision(0.005);
// Restore original values after castCollision
$pGuy.setCollisionPolyCustom( 4, "-0.910 -0.358", "0.678 -0.358", "0.678 0.975", "-0.910 0.975" );
[\code]
This would go in the updateMovement function() and should also probably go in the jump() function too.
The solution is to change the custom collision poly just before doign castCollision, insetting the left/right sides somewhat, so that castCollision won't detect walls to our left or right. The restore the custom collision poly when done.
[code]
// Inset the collision poly's left/right sides a little bit before doing castCollision, so
// that castCollision truly is checking for something BELOW us.
$pGuy.setCollisionPolyCustom( 4, "-0.80 -0.358", "0.60 -0.358", "0.60 0.975", "-0.80 0.975" );
%collision = $pGuy.castCollision(0.005);
// Restore original values after castCollision
$pGuy.setCollisionPolyCustom( 4, "-0.910 -0.358", "0.678 -0.358", "0.678 0.975", "-0.910 0.975" );
[\code]
This would go in the updateMovement function() and should also probably go in the jump() function too.
#2
Basically you just check for a collision to the left and right of you when moving, if you find one, set the linearVelocityX to 0. This will prevent you from repeatedly banging into the wall and "riding it up".
Best of luck with all your projects.
09/12/2006 (8:23 pm)
I've also posted an alternative solution in the other thread and updated the Player Movement section of the miniPlatformerTutorial. The change is quite simple and adds about 3 lines to the exsisting updateMovement function.Basically you just check for a collision to the left and right of you when moving, if you find one, set the linearVelocityX to 0. This will prevent you from repeatedly banging into the wall and "riding it up".
Best of luck with all your projects.
#3
09/13/2006 (5:11 am)
I tried the "change collision poly for cast collision" method for the platformer template, but it felt too hacky. We wound up going with a pickLine (or pickRect) set to only check for platform groups instead. The pick was based on the collision polygon of the actor, and was just thinner than the poly itself to avoid getting ground checks from walls. If you use this method you have to make sure that you do the pick based on the world coordinates of the collision poly at the time because flipX can drastically change your results if your image is off-center by even a little bit.
#4
Now if we can only get a proper solution for platforms the player and enemies can walk/jump up through, but can't fall through... (Including moving/falling platforms... so triggers is *not* a solution, because they need to be able to move around.) Well, see my thread for more info:
http://www.garagegames.com/mg/forums/result.thread.php?qt=50685
09/13/2006 (1:08 pm)
Good to hear there there is an "official" fix. Sounds like it's better than mine. Thanks guys. Now if we can only get a proper solution for platforms the player and enemies can walk/jump up through, but can't fall through... (Including moving/falling platforms... so triggers is *not* a solution, because they need to be able to move around.) Well, see my thread for more info:
http://www.garagegames.com/mg/forums/result.thread.php?qt=50685
#5
Is there something specific that led you to the conclusion that you can't move them? I'd like to make sure there isn't false information floating around somewhere.
09/13/2006 (2:23 pm)
Triggers can definitely be moved around. They are just scene objects like anything else.Is there something specific that led you to the conclusion that you can't move them? I'd like to make sure there isn't false information floating around somewhere.
#6
Since triggers may then end up giving me what I want, let me ask this: do they add any kind of performance penalty? Let's say you have a 1000x1000 TileMap, and half those tiles need triggers. Then let's also say we have 200 sprites in that level that also have moving triggers. These triggers, when activated, potentially cause collisions to be turned off for the sprite the triggered it.
Would the fact that there are so many triggers in the level, and perhaps hundreds of sprites that might activate them, result in a noticeable performance penalty?
Anyway, thanks for the correction... I will definitely look into using triggers to see if is solves my problem adequately... and will try to be more careful to read up on something before dismissing it. ;-)
09/13/2006 (10:07 pm)
Hmm, nope, just an assumption on my part, which apparently is wrong!Since triggers may then end up giving me what I want, let me ask this: do they add any kind of performance penalty? Let's say you have a 1000x1000 TileMap, and half those tiles need triggers. Then let's also say we have 200 sprites in that level that also have moving triggers. These triggers, when activated, potentially cause collisions to be turned off for the sprite the triggered it.
Would the fact that there are so many triggers in the level, and perhaps hundreds of sprites that might activate them, result in a noticeable performance penalty?
Anyway, thanks for the correction... I will definitely look into using triggers to see if is solves my problem adequately... and will try to be more careful to read up on something before dismissing it. ;-)
#7
Also, in messing around with the trigger method we decided to go with a slightly different usage than the one posted on TDN. Basically, all one-way platforms are in the same graphGroup and the player has active platforms and inactive platforms in its collision groups. When an actor enters a trigger the inactive group is removed from its colision groups and the platform associated with the trigger that the player entered is switched to the inactive group. We did it this way so that actors that aren't in that platform's trigger can walk across it normally while another actor passes through it.
09/14/2006 (3:39 am)
One-way platforms on tiles can be tricky. What we came to (which was a little obnoxious to write, but worked surprisingly well) was a custom tile data that we painted onto the one-way platform tiles. In onLevelLoaded for platform tileLayers we check for consecutive tiles with that custom data on it and record their individual collision polys. Then we create a scene object that encompasses those collision polys with a basic rectangular collision poly and throw the trigger on that. Once that's done, we turn collision off on those tiles, so the scene object takes care of everything. In retrospect, if anything it would be slightly faster in cases with long strings of consecutive one-way platforms. Either way, there is no noticeable performance hit that I can see.Also, in messing around with the trigger method we decided to go with a slightly different usage than the one posted on TDN. Basically, all one-way platforms are in the same graphGroup and the player has active platforms and inactive platforms in its collision groups. When an actor enters a trigger the inactive group is removed from its colision groups and the platform associated with the trigger that the player entered is switched to the inactive group. We did it this way so that actors that aren't in that platform's trigger can walk across it normally while another actor passes through it.
#8
I don't know... maybe it's due to the questionable physics simulation currently implemented in TGB (as mentioned here? I've updated to 1.1.2 myself. Have you tested it in 1.1.2?
10/04/2006 (12:15 am)
@Dan: I have implemented the changes you mentioned for the MiniPlatformerTutorial (I've been struggling with the same problem, of course) and have found the implementation to be prone to bugginess. If the player jumps onto a normal platform tile, then there's a possibility that he'll already be contacting something by the time the castCollision occurs. If that's the case then the player is indefinitely stuck to the ground. At least that's what I'm bumping into (after implementing the few lines of code offered in the update). Running around on the level is fine until you jump high and land... then you're stuck in the level. Would reversing the order of y and x collision checking change things at all?I don't know... maybe it's due to the questionable physics simulation currently implemented in TGB (as mentioned here? I've updated to 1.1.2 myself. Have you tested it in 1.1.2?
#9
There are a few things I would check right off the bat though, make sure you've set the
Also, when you call castcollision in the downward direction, right before that we set the LinearYVelocity to 100, so we are never actually using the REAL downward speed of the plalyer when checking for a collision right below us. You can play around with the Y velocity and the duration you pass to castCollision so you are 100% sure you will detect the collision before you actually get sunk into the top of a tile.
Make sure you have the part of the tutorial where you disable the
Because I know for sure you can get stuck in the tiles if you don't turn off the constantForceY right before you land on a tile.
10/04/2006 (12:32 am)
I've tried it with 1.1.1 and 1.1.2 but I havn't had any "buggyness". I just tried it again in my test level and it seems to be working fine. Do you think you could help me out and post a screenshot of the situation where you are able to get the guy stuck?There are a few things I would check right off the bat though, make sure you've set the
$pGuy.setCollisionMaxIterations(2);so that the collision tests are accurate for your player.
Also, when you call castcollision in the downward direction, right before that we set the LinearYVelocity to 100, so we are never actually using the REAL downward speed of the plalyer when checking for a collision right below us. You can play around with the Y velocity and the duration you pass to castCollision so you are 100% sure you will detect the collision before you actually get sunk into the top of a tile.
Make sure you have the part of the tutorial where you disable the
if(%collision $= "")
{
$pGuy.setConstantForceY(100);
}
else
{
$pGuy.setConstantForceY(0);
}Because I know for sure you can get stuck in the tiles if you don't turn off the constantForceY right before you land on a tile.
#10
10/04/2006 (5:53 pm)
So it might actually be a part of my level. I'll look into it. I've no idea what's going on but everything works fine until I jump back into the tiles that my character starts on (I made the level look exactly like the one in the tutorial and he starts in the same position). If I hop down and run around I'm fine and the climbing up the wall is gone. However, if I jump back up to the left my player stops dead. Jump doesn't even work... which is real odd.
#11
At times I cannot jump and at other times I cannot run. When it gets bad I can't do either. Usually a few presses of the jump button will 'free' me from that situation but that often results in a landing where I cannot run and then have to jump a few times (jumping and holding left or right still works) before the running returns - and then, not permanently.
It's extremely weird. Oh, and I have "$pGuy.setCollisionMaxIterations(2);" set properly on levelLoad.
10/04/2006 (10:27 pm)
I've done some reporting to the console to see what's going on. I used the following to check the object type returned by the two castCollision calls in the updateMovement() function:// Note that I use "%this" where the tutorial uses "$pGuy". My project only has one object in
// the playerClass namespace so I feel okay using it thusly. I tested putting "$pGuy" in to no avail.
// Begin checking for objects beneath the player
%yVelocity = %this.getLinearVelocityY();
%this.setLinearVelocityY(0);
%collision = %this.castCollision(0.005);
if(%collision !$= "")
{
echo("Collision to check for X collision: " @ getWord(%collision, 0).getClassName());
%this.setLinearVelocityX(0);
}
%this.setLinearVelocityY(100);
%collision = %this.castCollision(0.005);
%this.setLinearVelocityY(%yVelocity);
if(%collision $= "")
{
%this.setConstantForceY(100);
}
else
{
echo("Collision to check for Y collision: " @ getWord(%collision, 0).getClassName());
%this.setConstantForceY(0);
}My console fills up with "Collision to check for Y[or X] collision: t2dtileLayer".At times I cannot jump and at other times I cannot run. When it gets bad I can't do either. Usually a few presses of the jump button will 'free' me from that situation but that often results in a landing where I cannot run and then have to jump a few times (jumping and holding left or right still works) before the running returns - and then, not permanently.
It's extremely weird. Oh, and I have "$pGuy.setCollisionMaxIterations(2);" set properly on levelLoad.
#12
If I don't hold down either arrow when I land, whether it be from falling or from jumping, then I do not get stuck and stuff works as expected. If, however, I hold down left or right while in the air and land in that state then there's a chance, a very high chance, that I'll get stuck and won't move left or right. I didn't notice it before but I had an issue with jumping (sometimes I would land and the animation wouldn't switch back from jumping to standing/running and I couldn't jump properly).
Is something wrong with castCollision? I have the Mac version of the engine if that helps. Perhaps there's a problem with castCollision as mentioned here?
10/04/2006 (11:06 pm)
Okay, I've done a bit of playing around. Here's what I've found:If I don't hold down either arrow when I land, whether it be from falling or from jumping, then I do not get stuck and stuff works as expected. If, however, I hold down left or right while in the air and land in that state then there's a chance, a very high chance, that I'll get stuck and won't move left or right. I didn't notice it before but I had an issue with jumping (sometimes I would land and the animation wouldn't switch back from jumping to standing/running and I couldn't jump properly).
Is something wrong with castCollision? I have the Mac version of the engine if that helps. Perhaps there's a problem with castCollision as mentioned here?
#13
...that we might not detect there is a collision 0.005 seconds in the future. However when we restore the original yVelocity with...
we actually restore a larger Y velocity then 100. That means that in the next 0.005 collision there really would be a collision and because the ConstantForceY is still being applied we get all that annoying sticky behavior where we get stuck in a tile.
Maybe the solution is to do something like this...
Where we use the absolute value of our y velocity (to make sure it's always checking below the player), then we would always be checking with the correct speed.
Let me know if this has any effect on the problem.
10/04/2006 (11:55 pm)
So I wasn't able to reproduce the issue, one thing that seems possible to me, and I'm not sure exactly, but since we set the gravitational force on the player with ConstantForceY = 100, there may be a case if you are traveling at a velocity greater then LinearVelocityY = 100 then when you do %this.setLinearVelocityY(100); %collision = %this.castCollision(0.005);
...that we might not detect there is a collision 0.005 seconds in the future. However when we restore the original yVelocity with...
%this.setLinearVelocityY(%yVelocity);
we actually restore a larger Y velocity then 100. That means that in the next 0.005 collision there really would be a collision and because the ConstantForceY is still being applied we get all that annoying sticky behavior where we get stuck in a tile.
Maybe the solution is to do something like this...
%this.setLinearVelocityY(mabs(%yVelocity)); %collision = %this.castCollision(0.005);
Where we use the absolute value of our y velocity (to make sure it's always checking below the player), then we would always be checking with the correct speed.
Let me know if this has any effect on the problem.
#14
My character only gets stuck (or cannot jump) when I've landed while actively moving left or right. I'm not sure what's going on but if I'm holding down left or right when the avatar lands then everything stops. If I move around in the air with the keys but let go right before contacting a platform then I'm safe and can move around freely.
Any ideas?
(Oh yeah, and are you running the code on Linux, OSX, or Windows? I'm on OSX...)
10/05/2006 (9:44 pm)
I tried out the "mabs(%yVelocity)" method (required an extra if statement... things go bad when %yVelocity is zero). Turns out my %yVelocity does indeed get above 100 (at least 255 when I checked quickly). However, the change to incorporate that value in the castCollision had zero effect on my problem. In fact, the main (and awkward) symptom was still there:My character only gets stuck (or cannot jump) when I've landed while actively moving left or right. I'm not sure what's going on but if I'm holding down left or right when the avatar lands then everything stops. If I move around in the air with the keys but let go right before contacting a platform then I'm safe and can move around freely.
Any ideas?
(Oh yeah, and are you running the code on Linux, OSX, or Windows? I'm on OSX...)
#15
10/05/2006 (10:06 pm)
Looks like I'm not the only one with the issue (particularly in 1.1.2). Check out Andre Lind's comment in this thread. Similar perhaps?
#16
Once I did the castCollision test however, everything worked. I'm using the Windows version of TGB 1.1.2. It may very well be that you are having an issue specific to the OSX implementation of the physics, perhaps some of the physics tweaks did not get propigated to that build, or a new issue was introduced.
10/06/2006 (1:37 am)
When I first started the miniPlatformerProject I had the ConstantForceY at 100 at all times. What lead me to do the castCollision check to turn it off was the fact that when I tried to move left or right my player object would begin to "plow" down into the solid tiles of my level causing it to get stuck or move very slowly. This would seem to be the same effects that you are observing which was what led me to suspect the collision check that turns ConstantForceY to 0.Once I did the castCollision test however, everything worked. I'm using the Windows version of TGB 1.1.2. It may very well be that you are having an issue specific to the OSX implementation of the physics, perhaps some of the physics tweaks did not get propigated to that build, or a new issue was introduced.
#17
10/07/2006 (7:55 am)
I don't think the bugs are OSX specific as I get them on my XP machine aswell. I just arrived home after a week and will continue my testing shortly.
#18
the miniPlatformerTutorial is working greate but if you define a collision polygon in the level editor it will start to stuck
thats the real problem.
please check this:
http://www.garagegames.com/mg/forums/result.thread.php?qt=51889
10/08/2006 (11:21 pm)
I beleave that the actual problem is:the miniPlatformerTutorial is working greate but if you define a collision polygon in the level editor it will start to stuck
thats the real problem.
please check this:
http://www.garagegames.com/mg/forums/result.thread.php?qt=51889
#19
@Firas: I've set my collision to the original [square] bounds and had no change in my stickiness. I'll test it again but I doubt I'll notice a change.
10/09/2006 (5:06 pm)
@Oliver: Okay, glad to hear it isn't just us OSX folk! Err... kinda?@Firas: I've set my collision to the original [square] bounds and had no change in my stickiness. I'll test it again but I doubt I'll notice a change.
#20
This... is really odd. Definitely seems like a problem with the way the collision is handled...
10/09/2006 (5:18 pm)
@Firas: Well... I'll be darned. I imported a brand new $pGuy and the stuff just worked. I got stuck once: on top of my old $pGuy... whose collision polygon has a point at the top.This... is really odd. Definitely seems like a problem with the way the collision is handled...
Torque Owner Levi Walton
but seriously thanks for this, i dont know why it worked ( cuz im not smart in the codin area) but it did, and i thank you very much.