Game Development Community

Patrol Behavior - TGB 1.7.4

by Drethon · 05/27/2009 (3:11 pm) · 2 comments

My first resource, be gentle... jk.

This behavior was designed in a top down 2d space scroller I've been working on. It allows for adding objects for an AI ship to patrol between. The owner class has an update function that moves the ship like shown in the second block if anyone wants to use it. Other options are just replace acceleration and turnDir setting with proper rotate and accelerate commands.

No remove function which I may add later though its easy enough to add. Also this is for a spaceship with dampening as I was spending too much time working out a proper control function for "0g" and will come back to it later.

There are probably other similar resources out there but I didn't find any and I figure too many resources isn't a bad thing...



if (!isObject(ShipPatrolBehavior))
{
   %template = new BehaviorTemplate(ShipPatrolBehavior);
   
   %template.friendlyName = "Ship Patrol Behavior";
   %template.behaviorType = "Scroller AI";
   %template.description  = "Patrolling between objects";
   
   %template.addBehaviorField(range, "Waypoint Range", float, 25);
}

function ShipPatrolBehavior::onBehaviorAdd(%this)
{
   if (!isObject(moveMap))
      return;

   %this.owner.enableUpdateCallback();

   %this.totalWaypoints  = 0 ;
   %this.currentWaypoint = -1 ;
}

  // Adds a new patrol object.  If the index points to an existing waypoint,
  // replace the existing waypoint, otherwise add a new waypoint to the existing set.
function ShipPatrolBehavior::AddPatrolObject ( %this , %NewObject , %Index )
{
   if ( ( %Index < 0 ) || ( %Index > %this.totalWaypoints ) )
   {
      %this.patrolArray[%this.totalWaypoints] = %NewObject ;
      %this.totalWaypoints = %this.totalWaypoints + 1 ;
   }
   else
   {
      %this.totalWaypoints = %this.totalWaypoints + 1 ;
      for ( %patrolIndex = %this.totalWaypoints ; %patrolIndex > %Index ; %patrolIndex-- )
      {
         %patrolArray[%patrolIndex] = %patrolArray[%patrolIndex - 1] ;
      }
   }
}

   // If the new waypoint indicates a valid index, set it as the current waypoint
function ShipPatrolBehavior::SetWaypoint ( %this , %NewWaypoint )
{
   if ( %NewWaypoint < %this.totalWaypoints )
   {
      %this.currentWaypoint = %NewWaypoint ;
   }
}

function ShipPatrolBehavior::onUpdate ( %this )
{

      // If a waypoint is active.
   if ( %this.currentWaypoint != -1 )
   {

         // Calculate the distance to the waypoint.
      %distance = t2dVectorDistance ( %this.patrolArray[%this.currentWaypoint].getPosition() , %this.owner.getPosition () ) ;

         // Time to move to the next waypoint?
      if ( %distance < %this.range )
      {
         %this.currentWaypoint = %this.currentWaypoint + 1 ;
         if ( %this.currentWaypoint >= %this.totalWaypoints )
         {
            %this.currentWaypoint = 0 ;
         }
      }

         // Calculate the angle from the ship to the waypoint.
      %directionVectorX = %this.patrolArray[%this.currentWaypoint].getpositionX() - %this.owner.getpositionX();
      %directionVectorY = %this.patrolArray[%this.currentWaypoint].getpositionY() - %this.owner.getpositionY();
      %angle = 180 - mRadtoDeg(maTan(%directionVectorX , %directionVectorY));
      %angle = RollOverBound ( %angle , 0.0 , 360.0  ) ;

        // Calculate difference between ship angle and angle to waypoint.
      %angleDiff = RollOverBound ( %angle - %this.owner.getRotation() , -180.0 , 180.0 ) ;

      %targetVel = AbsoluteBound ( 2.0 * ( %distance - %this.range * 0.5 )  ,
				                       10.0 , %this.owner.thrust * 10000.0 / %this.shipHull.Mass * 4.0 ) ;

        // Calculate max velocity for range to target.
      %velRatio = ( getWord ( %this.owner.getLinearVelocityPolar () , 1 ) ) -
	                %targetVel ;

         // Are we at the right velocity?
      if ( %velRatio < -1.0 )
      {
         %this.owner.acceleration = 1 ;
      }
      else if ( %velRatio > 1.0 )
      {
         %this.owner.acceleration = -1 ;
      }
      else
      {
         %this.owner.acceleration = 0 ;
      }

         // Are we pointing the right direction?
      if ( %angleDiff < -15 )
      {
         %this.owner.turnDir = -10 ;
      }
      else if ( %angleDiff > 15 )
      {
         %this.owner.turnDir = 10 ;
      }
      else
      {
         %this.owner.turnDir = 0 ;
      }

   }

}

if ( %this.turnDir != 0 )
   {
      %this.targetAngle = %this.getRotation() + %this.turnDir ;
      if ( %this.targetAngle < 0.0 )
      {
         %this.targetAngle = %this.targetAngle + 360.0 ;
      }
      else if ( %this.targetAngle > 360.0 )
      {
         %this.targetAngle = %this.targetAngle - 360.0 ;
      }

      %this.rotateTo(%this.targetAngle, %this.turnSpeed );
   }

   %this.setConstantForcePolar(%this.getRotation(), %this.acceleration );

About the author

Recent Blogs

• Drethon's first blog

#1
05/29/2009 (12:02 pm)
Thanks man, this will help out!
#2
05/29/2009 (1:14 pm)
Glad you like it, any questions, don't hesitate. I find I often think differently that other people so some of they way I do things may not make sense :)