Game Development Community

Platformer Code (Almost there)

by Frank Gibson · in Torque Game Builder · 07/08/2009 (11:35 pm) · 0 replies

I have been working on a platformer, and I've almost finished the basic physics, using onCollision and completely rewriting the physics from scratch. There is one small problem though, the onCollision function is used to detect walls as well as the floor, but it's only called once per tick, so if you walk into a corner with a floor and a wall, you can force yourself down into the floor. If I could somehow get it to check the floor and walls simultaneously, I could prevent this, unfortunatley, I dont know how. Due to my custom gravity code, using castCollision garners only mixed results, so I'm unfortunaltey kind of stuck. Here is my code so far,

function player::onLevelLoaded(%this) 
{  
   	%this.start();  
}  

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

  	//-----variables-----
    %this.moveSpeed = 15;
	%this.jumpSpeed = 30;
    %this.accelGrav = 0.01;
    %this.termVel = 50;
    %this.maxWalkable = 0.3;
      
    //---don't change---  
    %this.jump = false;
    %this.moveLeft = false;  
    %this.moveRight = false; 
	%this.onGround = true; 
	%this.gravity = 0; 
   
    //-----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(false, false);  
    %this.enableUpdateCallback();  
    %this.setCollisionCallback(true);
}  
   
   
//----------key commands----------  
function player::jump(%this) 
{  
    if(%this.onGround)
    {
        %this.onGround =  false;
        %this.jump = true;
	    %this.setLinearVelocityY(-%this.jumpSpeed);
    } 
}  

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;
   	}
   
   	if (%this.moveLeft)
   	{
        %this.setLinearVelocityX(-%this.moveSpeed);
   	}

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

function player::updateVertical(%this)
{ 
    /*
    %this.setLinearVelocityY(100);
    %collision = %this.castCollision(0.005);
    %normalY =  getWord(%collision, 5);
     	
    if(%normalY > -0.3)
    {
         %this.onGround = false;
    }
    else
    {
         %this.onGround = true;
    }
    */

    if (!%this.onGround)
    {
        if (%this.gravity < %this.termVel)
        {
            %this.gravity += %this.accelGrav;
        }
    }
    else
    { 
        %this.gravity = 0;
    }
    %this.setLinearVelocityY(%this.getLinearVelocityY() + %this.gravity);
}

function player::onCollision(%this, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts) 
{  
    %flrAngle = getWord(%normal, 1);
    if (%flrAngle > 0)
    {    
        %this.jump = false;
        %this.setLinearVelocityY(0);
    }
    if (%flrAngle > -%this.maxWalkable)
    {
        if (%this.moveLeft)
   	    {
            %this.moveLeft = false; 
         	%this.setLinearVelocityX(0);
        }    
        if (%this.moveRight)
   	    {
            %this.moveRight = false;
         	%this.setLinearVelocityX(0);
        }
    }   
    if (%flrAngle <= -%this.maxWalkable)
    {
        %this.setLinearVelocityY(mTan(getWord(%normal, 0)) * %this.getLinearVelocityX());
        //%this.setLinearVelocityY(0);
        %this.onGround = true;
    }
}

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

I hope to add this as a resource if and when I get this working, if anyone has any idea on how to improve this, I'd be very grateful.