Game Development Community

Jitteryness when colliding with both walls and floors

by Frank Gibson · in Torque Game Builder · 07/17/2009 (1:17 pm) · 0 replies

I've been working on some basic platformer code, and I've gotten everything working perfectly except for one cosmetic problem, jumping into a corner just right causes some pretty substantial jittering, which doesnt affect gameplay, and can be fixed by pressing the move key again, but it isn't pretty to look at.

Here's my source so far.
function player::onLevelLoaded(%this) 
{  
   	%this.start();  
}  

function player::start(%this) 
{   
	$player = %this;
  
 	//-DEFAULT PROPERTIES-

  	//-----variables-----
    %this.moveSpeed = 20;
	%this.jumpSpeed = 50;
    %this.gravity = 80;
    %this.castTime = 0.0005;
      
    //---don't change---  
    %this.jump = false;
    %this.moveLeft = false;  
    %this.moveRight = false; 
	%this.airborne = true; 
   
    //-----keybinds-----  
    if(!isObject(moveMap)) 
	{
		return;
	}  
    moveMap.bindCmd(keyboard, "space", "player.jump();", "player.stopJump();");  
    moveMap.bindCmd(keyboard, "a", "player.left();", "player.stopLeft();");  
    moveMap.bindCmd(keyboard, "d", "player.right();", "player.stopRight();");  
      
      
    //-----collision-----  
    %this.setCollisionActive(true, true);  
    %this.setCollisionPhysics(true, true);  
    %this.enableUpdateCallback();  
    %this.setCollisionCallback(true);
    %this.setCollisionMaxIterations(2);
}  
   
   
//----------key commands----------  

function player::jump(%this)
{
     if(!%this.airborne)
     {
          %this.setLinearVelocityY(-%this.jumpSpeed);
          %this.airborne = true;
     }
}
function player::stopJump(%this) 
{  
    %this.jump = false; 
}  
   
function player::left(%this)
{
    %this.moveLeft = true;
}

function player::stopLeft(%this)
{
    %this.moveLeft = false;
}

function player::right(%this)
{
    %this.moveRight = true;
}

function player::stopRight(%this)
{
    %this.moveRight = false;
}

function player::updateHorizontal(%this)
{
    if (%this.moveLeft == %this.moveRight)
   	{
      	%this.setLinearVelocityX(0);
      	return;
   	}

    %collision = %this.castCollision(%this.castTime);

   	if (%this.moveLeft)
   	{
        %this.setLinearVelocityX(-%this.moveSpeed);
   	}

   	if (%this.moveRight)
   	{
        %this.setLinearVelocityX(%this.moveSpeed);
   	}
}

function player::updateVertical(%this)
{
    %yVelocity = %this.getLinearVelocityY();

    %this.setLinearVelocityY(%this.gravity);
    %collision = %this.castCollision(%this.castTime);
   
    if(%collision !$= "" && getWord(%collision, 5) == -1)
    {
        %this.airborne = false;
        %this.setConstantForceY(0);
        %yVelocity = 0;
    } 	
    else
    {
        %this.airborne = true;
        %this.setConstantForceY(%this.gravity);
    }

    %this.setLinearVelocityY(%yVelocity);
}

function player::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts) 
{      
    %tmpVelX = %this.getLinearVelocityX();                                    //the resulting y velocity   
    %tmpVelY = %this.getLinearVelocityY();                                    //the resulting y velocity  
    %angle = getWord(%normal, 1);                                             //the collision angle y (in radians)  
   
    //Ceiling collision
    if(%angle > 0) 
    {  
        %this.setPositionY(%this.getPositionY());  
        %tmpVelY = 0;  
    }

    //If the player is on a rotating block   
    if(%dstObj.getAngularVelocity() != 0 && %this.getLinearVelocityX() == 0)
    {   
        %tmpVelY = ((%this.getPositionY() - %dstObj.getPositionX()) / %dstObj.getWidth() / 2); 
    }  
 
    //If the player is on a moving block  
    if(%dstObj.getLinearVelocityX() != 0)
    {    
        %tmpVelX = %dstObj.getLinearVelocityX() + %tmpVelX;
    }  
    if(%dstObj.getLinearVelocityY() != 0)  
    {
        %tmpVelY = %dstObj.getLinearVelocityY() + %tmpVelY;  
    }
         
    //Finally, set the speeds
    %this.setLinearVelocityX(%tmpVelX);  
    %this.setLinearVelocityY(%tmpVelY);  
}

function player::setCurrentAnimation(%this)
{
    %xVelocity = %this.getLinearVelocityX();

    if (%xVelocity > 0)
    {
        %this.setFlip(false, false);
    }
    else if (%xVelocity < 0)
    {
        %this.setFlip(true, false);
    }
   
    if (%this.airborne)
    {
        %this.playAnimation(runner_jump);
        return;
    }

    if (%this.moveLeft || %this.moveRight)
    {
        if (%this.getAnimationName() $= "runner_run")
        {
            if(%this.getIsAnimationFinished())
            {
                %this.playAnimation(runner_run);
                return;
            }
        }
        else
        {
            %this.playAnimation(runner_run);
        }
    }
    else
    {
        %this.playAnimation(runner_idle);
    }
} 

function player::onUpdate(%this)
{
    //Update our position and animations 
   	%this.updateHorizontal();
   	%this.updateVertical();
   	%this.setCurrentAnimation(); 
}