Help with Collisions...
by Philip Read · in Torque 2D Beginner · 06/23/2013 (10:41 am) · 8 replies
I need some help understanding how to make a dynamic sprite stop moving when it hits a static sprites collision polygons.
Here is my code for the static object...
And here is the code for the dynamic sprite...
I've omitted the code for the controls. My issue is that when the dynamic sprite hits the collision box it flies in the opposite direction. I've tried setting the default restitution to zero for both objects, but it didn't solve the problem. Please, how to make an object stop completely when it collides?
Here is my code for the static object...
function createSceneObject()
{
%sceneObject = new Sprite();
%sceneObject.setBodyType(static);
%sceneObject.Position = "0 0";
%sceneObject.Size = "20 20";
%sceneObject.Image = "RPGModule:test";
%sceneObject.createEdgeCollisionShape( -10, -10, -10, 10);
%sceneObject.createEdgeCollisionShape( 10, -10, 10, 10);
%sceneObject.createEdgeCollisionShape( 10, -10, -10, -10);
%sceneObject.createEdgeCollisionShape( 10, 10, -10, 10);
myScene.add( %sceneObject );
}And here is the code for the dynamic sprite...
function createCharacter()
{
%character = new Sprite(mainCharacter);
%character.SetBodyType( dynamic );
%character.Position = "20 20";
%character.Image = "RPGModule:test";
%character.createPolygonBoxCollisionShape();
%character.setFixedAngle( true );
myScene.add(%character);
}I've omitted the code for the controls. My issue is that when the dynamic sprite hits the collision box it flies in the opposite direction. I've tried setting the default restitution to zero for both objects, but it didn't solve the problem. Please, how to make an object stop completely when it collides?
#2
06/23/2013 (1:32 pm)
Thank-you. I saw the method setCollisionShapeIsSensor in the documentation for sceneObjects, but I thought that this would let the sceneObject pass right through the collision polygons. I'll give both solutions a try and let you know if they work.
#3
Here is the full code for my character script, controls included...
And here is my Input manager details...
06/23/2013 (1:41 pm)
I'm still having the same issue. I notice that the velocity that it bounces back with is exactly opposite of the velocity that it hits the collision polygon's with. I'm thinking maybe I have not included something in my controls script.Here is the full code for my character script, controls included...
function createCharacter()
{
%character = new Sprite(mainCharacter);
%character.SetBodyType( dynamic );
%character.Position = "20 20";
%character.Image = "RPGModule:test";
%character.setCollisionCallback(true);
%character.createPolygonBoxCollisionShape();
%character.setFixedAngle( true );
myScene.add(%character);
}
function mainCharacter::onCollision(%this, %sceneobject, %collisiondetails)
{
%this.setLinearVelocity("0 0");
%this.setAngularVelocity("0");
}
function mainCharacter::Left(%this)
{
%dir = Vector2Direction(270, 30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::LeftStop(%this)
{
%dir = Vector2Direction(270, -30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::Right(%this)
{
%dir = Vector2Direction(90, 30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::RightStop(%this)
{
%dir = Vector2Direction(90, -30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::Up(%this)
{
%dir = Vector2Direction(0, 30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::UpStop(%this)
{
%dir = Vector2Direction(0, -30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::Down(%this)
{
%dir = Vector2Direction(180, 30);
%this.applyLinearImpulse( %dir, "0 0");
}
function mainCharacter::DownStop(%this)
{
%dir = Vector2Direction(180, -30);
%this.applyLinearImpulse( %dir, "0 0");
}And here is my Input manager details...
function InputManager::Init_controls(%this)
{
new ActionMap(characterControls);
characterControls.bindCmd(keyboard, "a", "mainCharacter.Left();", "mainCharacter.LeftStop();");
characterControls.bindCmd(keyboard, "w", "mainCharacter.Up();", "mainCharacter.UpStop();");
characterControls.bindCmd(keyboard, "d", "mainCharacter.Right();", "mainCharacter.RightStop();");
characterControls.bindCmd(keyboard, "s", "mainCharacter.Down();", "mainCharacter.DownStop();");
characterControls.push();
}
#4
I shouldn't be stopping my sceneObject by applying a reverse linear impulse, but should just use setLinearVelocity to "0 0".
06/23/2013 (1:51 pm)
Oh, I think I just solved my problem!I shouldn't be stopping my sceneObject by applying a reverse linear impulse, but should just use setLinearVelocity to "0 0".
#5
So are your saying the object now stops when colliding with other objects?
06/23/2013 (1:55 pm)
Adding an inverse Linear Impulse is great for slowing down but won't stop the object immeditately.So are your saying the object now stops when colliding with other objects?
#6
I changed all of my button up functions to set linear velocity to zero.
This is a good temporary fix, but I need to make it so that when the button is released only that directions linear velocity is set to zero.
I'm sure I just need to specify a direction using the method setLinearVelocity. I'll check out the documentation to see how to do that.
Thanks so much for your help. I think I have a better idea of how the physics work in the engine.
06/23/2013 (2:00 pm)
Yes.I changed all of my button up functions to set linear velocity to zero.
This is a good temporary fix, but I need to make it so that when the button is released only that directions linear velocity is set to zero.
I'm sure I just need to specify a direction using the method setLinearVelocity. I'll check out the documentation to see how to do that.
Thanks so much for your help. I think I have a better idea of how the physics work in the engine.
#7
You can use LinearDamping to slow down the character.
I suggest reading the control section of the Getting Started Guide to get a real-life example of how to obtain directions from vectors.
Just scroll to the function PlayerShip::accelerate(%this).
Also, you can try setLinearVelocityPolar(, which takes an angle and speed instead of X,Y coordinates.
06/23/2013 (2:09 pm)
My pleasure!You can use LinearDamping to slow down the character.
I suggest reading the control section of the Getting Started Guide to get a real-life example of how to obtain directions from vectors.
Just scroll to the function PlayerShip::accelerate(%this).
Also, you can try setLinearVelocityPolar(, which takes an angle and speed instead of X,Y coordinates.
#8
06/23/2013 (2:10 pm)
Actually, scratch that, the methods setLinearVelocityX and setLinearVelocityY will work perfect.
Associate Simon Love
In all cases, you should call %character.setCollisionCallback(true); when creating the object.
This will tell the engine to execute function onCollisionCallback where your object is involved in a collision.
You simply need to write the function in your script and make it do whatever you want. The echo statement below is just to make sure that the function gets called properly and prints the defined string to the console.
mainCharacter.OnCollisionCallback(%this, %otherobject, %contactdetails) { echo(%this SPC "hit object" SPC %otherobject); ... }So here are the two methods
1 - Manually setting Velocity
When the collision occurs, you can call
%this.setLinearVelocity("0 0"); %this.setAngularVelocity("0");The object will stop dead in its tracks and won't be sent spinning.
2 - Using sensors
After creating your CollisionShape, call
Where 0 is your shapeindex (if you have more than one collision shape on your object).
This will completely disable physics-based reactions on your object but the collisions will still be detected!
As in example 1, you can simply set the linear and angular velocities to 0 at this point.