Strange collision response to curved poligons
by Diego Santos Leao - GameBlox Studio · in Torque Game Builder · 03/26/2008 (6:22 am) · 20 replies
When I choose "CLAMP" as the collision response, I always get a strange behavior.
Let's say I'm moving my character using a constant force to the right. When it encounters a inclined poligon, it get "slided" around it (everything normal so far).
The strange thing is that even after it lost contact with the poligon, it still gets pushed diagonaly intead of just going right! As long as I keep applying the force to the sprite, it keeps going to the wrong direction. If I release the force from the sprite, and reaply it, the sprite regains its normal behavior (going only to the right).
...I hope this is understandable....
This is the 'graphical' representation of what happens is shown bellow. The asterisk is the player - there is a constant force on him to the right - and the dots are just used to get the spacing right, as this forum clips blank spaces out:
....+-------
......\
......*\____
....+-------
......\
.......\____
.......*
....+-------
......\
.......\____
.......
.........*
....+-------
......\
.......\____
.......
.........
............*
Let's say I'm moving my character using a constant force to the right. When it encounters a inclined poligon, it get "slided" around it (everything normal so far).
The strange thing is that even after it lost contact with the poligon, it still gets pushed diagonaly intead of just going right! As long as I keep applying the force to the sprite, it keeps going to the wrong direction. If I release the force from the sprite, and reaply it, the sprite regains its normal behavior (going only to the right).
...I hope this is understandable....
This is the 'graphical' representation of what happens is shown bellow. The asterisk is the player - there is a constant force on him to the right - and the dots are just used to get the spacing right, as this forum clips blank spaces out:
....+-------
......\
......*\____
....+-------
......\
.......\____
.......*
....+-------
......\
.......\____
.......
.........*
....+-------
......\
.......\____
.......
.........
............*
About the author
Creative director at Gameblox Interactive, a game studio focused on downloadable games and advergames. www.gameblox.net - contact@gameblox.net.
#2
I tried your suggestion, and it works fine for moving the character, but I have another problem: I'm using the "bindObj" method, that doesn't allow me to specify a method for the "key released" event.
So... how do I make him stop?
I can't just use the bindCmd because I want to set the binding to a specific "instance of an object".
Is there a way to use bindCmd (or to simulate it) in this situation (where I need to call a method of a particular intance of an object/namespace)?
---
EDIT:
Maybe it helps to know that I'm doing an RPG: the character is a human and the obstacles are houses, lamps, people, etc.
03/26/2008 (2:08 pm)
I'm using the "setLinearVelocityX()" method repeatedly on an animated sprite (second case).I tried your suggestion, and it works fine for moving the character, but I have another problem: I'm using the "bindObj" method, that doesn't allow me to specify a method for the "key released" event.
So... how do I make him stop?
I can't just use the bindCmd because I want to set the binding to a specific "instance of an object".
Is there a way to use bindCmd (or to simulate it) in this situation (where I need to call a method of a particular intance of an object/namespace)?
---
EDIT:
Maybe it helps to know that I'm doing an RPG: the character is a human and the obstacles are houses, lamps, people, etc.
#3
Here's an example for a very simple basic player move:
Using onupdate (or a recursive schedule) is important for this kind of controls.
Also look at the conditions in the onupdate, it garantees that there's no more moves if no controls are pressed.
03/27/2008 (7:55 am)
To avoid this, you mustn't just apply one time "setlinearvelocity" and let it go. You must regularly reapply the right velocity so your object is not deviated from the original "push".Here's an example for a very simple basic player move:
player.enableupdatecallback();
movemap.bindCmd(keyboard, "up", "player.goup();", "player.upstop();");
movemap.bindCmd(keyboard, "down", "player.godown();", "player.downstop();");
movemap.bindCmd(keyboard, "left", "player.goleft();", "player.leftstop();");
movemap.bindCmd(keyboard, "right", "player.goright();", "player.rightstop();");
function player::goup(%this)
{
%this.up = true;
}
function player::upstop(%this)
{
%this.up = false;
}
function player::godown(%this)
{
%this.down = true;
}
function player::downstop(%this)
{
%this.down = false;
}
function player::goleft(%this)
{
%this.left = true;
}
function player::leftstop(%this)
{
%this.left = false;
}
function player::goright(%this)
{
%this.right = true;
}
function player::rightstop(%this)
{
%this.right = false;
}
function player::onupdate(%this)
{
if(%this.up)
%this.setlinearvelocityy(-40);
else if(%this.down)
%this.setlinearvelocityy(40);
else
%this.setlinearvelocityy(0);
if(%this.right)
%this.setlinearvelocityx(40);
else if(%this.left)
%this.setlinearvelocityx(-40);
else
%this.setlinearvelocityx(0);
}Using onupdate (or a recursive schedule) is important for this kind of controls.
Also look at the conditions in the onupdate, it garantees that there's no more moves if no controls are pressed.
#4
03/27/2008 (7:58 am)
Thanks Benjamin. :)
#5
03/27/2008 (7:59 am)
I slightly updated the onupdate code int the post above, it wasn't good enough ^^'
#6
I'm using bindObj so I have no way of knowing when a keyboard key was released.
I tried to use the onUpdate method, but no luck there either.
This is the code I'm using (in coments is the onUpdate method).
http://tdn.garagegames.com/wiki/images/7/72/TopDownCharacterControlBehavior.zip
Please try it against a curved poligon.
PS: ignore the update animation code
03/27/2008 (10:30 am)
In my last post I said why I can't use the method you describe Benjamin (using bindCmd).I'm using bindObj so I have no way of knowing when a keyboard key was released.
I tried to use the onUpdate method, but no luck there either.
This is the code I'm using (in coments is the onUpdate method).
http://tdn.garagegames.com/wiki/images/7/72/TopDownCharacterControlBehavior.zip
Please try it against a curved poligon.
PS: ignore the update animation code
#7
03/27/2008 (11:18 am)
Why not use the shooterControls behavior found in the behavior playground project that comes with TGB? Even though you are making a RPG, this behavior should give you the movement you are looking for. Plus it shows you how to use bindObj and know when the keyboard keys are pressed or released.
#8
). But that behavior (and mine) have problems with collisions.
Benjamin and Melv told me to repeteadly reaply the linearvelocity, but that is not working..
And also, with the constantforce method, I have another problem: the character wont stop moving...
If you could read the code and point out what I'm doing wrong, it would be nice!
03/27/2008 (1:31 pm)
Actually, my code IS based on the shooterControls behavior (part of the code is pratically identical, see it here: http://tdn.garagegames.com/wiki/images/7/72/TopDownCharacterControlBehavior.zip). But that behavior (and mine) have problems with collisions.
Benjamin and Melv told me to repeteadly reaply the linearvelocity, but that is not working..
And also, with the constantforce method, I have another problem: the character wont stop moving...
If you could read the code and point out what I'm doing wrong, it would be nice!
#9
Looking at that behaviour you can see the "onUpdate()" is commented-out. I believe the intent there is to reassert the linear velocities each scene-tick. This would resolve your problem. You can read about that particular callback here.
This means you must call "%this.enableUpdateCallback()" when you want the "onUpdate" callback each scene-tick and "%this.disableUpdateCallback();" when you stop the behaviour. A good place for these calls is the "onBehaviorAdd" and "onBehaviorRemove" respectively.
Hope this helps,
Melv.
03/27/2008 (1:48 pm)
Diego,Looking at that behaviour you can see the "onUpdate()" is commented-out. I believe the intent there is to reassert the linear velocities each scene-tick. This would resolve your problem. You can read about that particular callback here.
Quote:onUpdate
This is called every tick (32 milliseconds). It should be used only when necessary as it can have pretty serious performance implications. Because of this, it must be enabled with a call to enableUpdateCallback. It can be disabled by calling disableUpdateCallback
This means you must call "%this.enableUpdateCallback()" when you want the "onUpdate" callback each scene-tick and "%this.disableUpdateCallback();" when you stop the behaviour. A good place for these calls is the "onBehaviorAdd" and "onBehaviorRemove" respectively.
Hope this helps,
Melv.
#10
function TopDownCharacterControlBehavior::onUpdate(%this)
{
%this.owner.setLinearVelocityX((%this.right - %this.left) * %this.horizontalSpeed);
%this.owner.setLinearVelocityY((%this.down - %this.up) * %this.verticalSpeed);
}
Notice that in the previous code the onUpdate method had only a call to "updateMovement". I changed that to the above two lines because the updateMovement method also updates my animations, so they got messed up (stuck in one frame). I guess is best to only update "non visual" stuff inside the onUpdate callback...
Many thanks to Melv and everyone!
PS: I would like to notice, to those of you having the same problem, that this also happens with another collision responses (like bounce and sticky). The solution is the same pointed here.
03/27/2008 (3:36 pm)
Nice! The thing that was missing was this call (%this.owner.enableUpdateCallback();) inside the "onBehaviorAdd" method and the addition of the following method:function TopDownCharacterControlBehavior::onUpdate(%this)
{
%this.owner.setLinearVelocityX((%this.right - %this.left) * %this.horizontalSpeed);
%this.owner.setLinearVelocityY((%this.down - %this.up) * %this.verticalSpeed);
}
Notice that in the previous code the onUpdate method had only a call to "updateMovement". I changed that to the above two lines because the updateMovement method also updates my animations, so they got messed up (stuck in one frame). I guess is best to only update "non visual" stuff inside the onUpdate callback...
Many thanks to Melv and everyone!
PS: I would like to notice, to those of you having the same problem, that this also happens with another collision responses (like bounce and sticky). The solution is the same pointed here.
#12
//apply impulse force to make ball jump
$pBall.setImpulseForcePolar(%angle, $pBall.jumpPower, true);
heree's a 45 second video of me getting stuck: carpetscooter.blogspot.com/2008/06/collision-problem-continued-and-new.html
06/22/2008 (1:23 am)
Hello. I'm having problems if I say.. roll a ball along a flat surface. It will undoubtedly get stuck. Any thoughts? using ://apply impulse force to make ball jump
$pBall.setImpulseForcePolar(%angle, $pBall.jumpPower, true);
heree's a 45 second video of me getting stuck: carpetscooter.blogspot.com/2008/06/collision-problem-continued-and-new.html
#13
First, I would suggest you generate your own thread from this as there are too many threads with multiple disjoint issues already. ;)
For now though, is this v1.7.3? Unfortunately, a few of my physics fixes (for reasons described elsewhere) ended-up getting missed out of the v1.7.3 build. The next one will include them though.
If however you're not using v1.7.3 then I would suggest you try it.
If you've not made any mods to the engine then if you send me a test I can run it against the latest build for you if that'd help.
Melv.
06/22/2008 (1:35 am)
Hi,First, I would suggest you generate your own thread from this as there are too many threads with multiple disjoint issues already. ;)
For now though, is this v1.7.3? Unfortunately, a few of my physics fixes (for reasons described elsewhere) ended-up getting missed out of the v1.7.3 build. The next one will include them though.
If however you're not using v1.7.3 then I would suggest you try it.
If you've not made any mods to the engine then if you send me a test I can run it against the latest build for you if that'd help.
Melv.
#14
I thought you might get to this thread which is why I posted in this one.. I have another thread out there too. Anyhow... there seems to be alot of problems associated with interpenetration still. I can put two circular collision objects next to eachother and shoot at it with a impluseforce.. and often I get stuck to the side of the other circle. I can slide accross pretty much any surface and get stuck. flat surface, curved, sloped. I was just looking at your demo and I don't see that happening in your youtube vids.
I could send you a demo but probably need to pair it down first.. lots of pictures in there might cause you some trouble.
06/22/2008 (2:24 am)
Thanks Melv, wow your up late. Yes I am using an unmodded 1.7.3 build.I thought you might get to this thread which is why I posted in this one.. I have another thread out there too. Anyhow... there seems to be alot of problems associated with interpenetration still. I can put two circular collision objects next to eachother and shoot at it with a impluseforce.. and often I get stuck to the side of the other circle. I can slide accross pretty much any surface and get stuck. flat surface, curved, sloped. I was just looking at your demo and I don't see that happening in your youtube vids.
I could send you a demo but probably need to pair it down first.. lots of pictures in there might cause you some trouble.
#15
I've not experienced issues of such magnitude that you describe so given two surfaces, could you describe what the details are for those two surfaces? Probably a bit of script for both objects that describes all the stuff being set on them.
I'm sure I can quickly resolve your issue though.
BTW: I'm on GMT+0 so it's 10:20am here so if you can send me stuff soon I can look at it immediately for you! Also, cool video. :)
Melv.
06/22/2008 (2:29 am)
If you could send me something for me to test I'd appreciate that, don't care how big it is as long as I can just swap-out your exe with mine.I've not experienced issues of such magnitude that you describe so given two surfaces, could you describe what the details are for those two surfaces? Probably a bit of script for both objects that describes all the stuff being set on them.
I'm sure I can quickly resolve your issue though.
BTW: I'm on GMT+0 so it's 10:20am here so if you can send me stuff soon I can look at it immediately for you! Also, cool video. :)
Melv.
#16
06/22/2008 (2:42 am)
Ah, I just assumed you lived in Eugene. Top of the morning to you then! I built a version for you to test if you like. just by clicking "build". anyways.. where should I send it?
#18
06/22/2008 (2:47 am)
Ah, I just assumed you lived in Eugene. Top of the morning to you then! I built a version for you to test if you like. just by clicking "build". anyways.. where should I send it?
#19
Then we can post back here if it provides useful information to others. :)
Melv.
06/22/2008 (2:54 am)
Got your email thanks! We'll continue this offline until we find out what the problem is if that's okay?Then we can post back here if it provides useful information to others. :)
Melv.
#20
06/22/2008 (2:58 am)
Ah, I just assumed you lived in Eugene. Top of the morning to you then! I built a version for you to test if you like. just by clicking "build". anyways.. where should I send it?
Associate Melv May
When you say you're "using a constant force to the right" are you applying this using:
1) "setConstantForce()" ?
2) "setLinearVelocity()" ?
The first case is applied by the engine constantly and should result in the object moving right if no collision occurs whereas the second case is a one-shot deal and the velocity you applied will be removed by the "clamp" collision resulting in what you describe above. If you reuse "setLinearVelocity()" when you press the key again all will be well.
If though this is happening with "setConstantForce()" then something very odd is happening.
In case you don't know there are different ways to deal with this during the state where the players "move" key is pressed. One is to constantly use "setLinearVelocity" on the scene-script-callback and the other is to use "setConstantForce()" once when the "move" key is pressed. I prefer the "setConstantForce" method.
Melv.