Game Development Community

Collision Response and Velocity causing "Bad Vibrations"

by Michael Dawson · in Torque Game Builder · 04/24/2009 (12:23 pm) · 3 replies

I have a character I can move around the screen using the keyboard. I've set up scene objects that the character can collide with. I've set the character's Collision Response to CLAMP. The character does collide with the scene objects, but as long as I hold down the key that moves the character into the collision, the character "vibrates" back and forth. I'm guessing that this is because the collision causes the character's velocity to go to 0, but then the keypress causes the velocity to go back to movement speed, many times a second. Here's the code for the character:

function playerClass::onLevelLoaded(%this, %scenegraph)
{        
   %this.walkVelocity = 15;
   %this.rightPressed = false;
   %this.leftPressed = false;  

   moveMap.bindCmd(keyboard, 
                   "right", 
                   %this @ ".rightPressed = true;", 
                   %this @ ".rightPressed = false;");

   moveMap.bindCmd(keyboard, 
                   "left", 
                   %this @ ".leftPressed = true;", 
                   %this @ ".leftPressed = false;");
   
   %this.enableUpdateCallback();
}

function playerClass::onUpdate(%this)
{   
   if (%this.rightPressed == %this.leftPressed)
   {
      %this.setLinearVelocityX(0);
   }
   else if (%this.rightPressed)
   {
      %this.setLinearVelocityX(%this.walkVelocity);
   }
   else if (%this.leftPressed)
   {
      %this.setLinearVelocityX(-%this.walkVelocity);
   }
}

Is there a simple way to get rid of this "vibration" effect?

--Mike

#1
04/27/2009 (3:04 pm)
Anybody? I've tried a few solutions, including enabling the onCollision() callback for my player and setting its LinearVelocityX to 0 upon collision, but nothing changed. (I assume that's what CLAMP does and so didn't expect a big change)

To make it easier to check out what I'm talking about, here's a link to the complete TGB project:

collisionTest

Feel free download, check it out, and offer any advice :)

Thanks,

--Mike
#2
04/27/2009 (3:12 pm)
In general, don't use "onUpdate" unless you really need to. In this case, you don't need to:

function onLeftPressed()
{
   $player.leftPressed = true;
   $player.updateVelocity();
}

function onLeftReleased()
{
   $player.leftPressed = false;
   $player.updateVelocity();
}

function onRightPressed()
{
   $player.rightPressed = true;
   $player.updateVelocity();
}

function onRightReleased()
{
   $player.rightPressed = false;
   $player.updateVelocity();
}

function playerClass::updateVelocity(%this)
{   
   if (%this.rightPressed == %this.leftPressed)
   {
      %this.setLinearVelocityX(0);
   }
   else if (%this.rightPressed)
   {
      %this.setLinearVelocityX(%this.walkVelocity);
   }
   else if (%this.leftPressed)
   {
      %this.setLinearVelocityX(-%this.walkVelocity);
   }
}
#3
04/27/2009 (5:26 pm)
Thanks for the code, Philip. It definitely does what I was asking for. However, the ultimate behavior I want is a bit more complex -- and the code doesn't currently work for that. To back up for a second, I'm trying to create a simple platformer (I've tried the code for this platforming tutorial, but had all the problems that others described, so I'd decided to make my own). Here’s an example of the issue with the above code:

The player presses and holds down the right key -- as a result, the main character moves to the right, hits a block, and stops. Great. However, when the block moves up and out of the character’s way, the character stands still, even though the player has continued to hold down the right key the entire time. What I’d like to happen is for the character to move to the right once the block is out of the way (again, because the player has continued to hold down the right key). I achieved this behavior with my original code because I set the LinearVelocityX every tick based on the keypress -- but this also resulted in the “vibrating” on the constant collisions.

Any ideas?