TGB/MiniTutorials/SimplePhysicsDemo

From TDN

Back

Simple Physics Demo
Description:

This idea just popped into my head, so I decided to make a quick prototype to see how it would play. It actually turned out pretty fun, but more so it's not a bad example of how to get basic physics to work for you.


This sample script will demonstrate how to set up collision in datablocks and implement some simple game mechanics.


This demo uses the left and right keys to rotate certain platforms. All the brown platforms will deflect the balls and all the red objects are bumpers. Try to get all the GG Logo balls into the slot in the middle!

Image:SimplePhysicsDemo.JPG


 Download Files :

Simple Physics Demo Project




Extract the zip file into your "../Games" directory and load the PhysicsDemo project, then just hit play!

// falling balls datablock
/* several things to note about the balls:
-RIGID physics mode...
-damping, density, friction, and restitution affect behavior
-balls send/recieve phys and coll so they can collide with each other
-collision groups set to 2 means "only collide with graph group 1" */
datablock t2dSceneObjectDatablock(BallDatablock) {
   CollisionActiveSend = "1";
   CollisionActiveReceive = "1";
   CollisionPhysicsSend = "1";
   CollisionPhysicsReceive = "1";
   CollisionCircleSuperscribed = "0";
   CollisionDetectionMode = "CIRCLE";
   CollisionResponseMode = "RIGID";
   CollisionGroups = "2";
   CollisionMaxIterations = "4";
   ConstantForce = "0 120";
   ConstantForceGravitic = "1";
   Damping = "0.2";
   Density = "0.01";
   Friction = "0.3";
   Restitution = "1";
   GraphGroup = "1";
   WorldLimitCallback = "1";
   WorldLimitMax = "100 300";
   WorldLimitMin = "-100 -100";
   WorldLimitMode = "KILL";
};

// anything that deflects balls
/* several things to note about the deflectors:
-CLAMP physics mode...
-deflectors *only* recieve phys and coll
-deflectors are put graph group 1 (default is 0) so our balls will collide with them
-immovable set to true - otherwise balls would slowly move them */
datablock t2dSceneObjectDatablock(DeflectorDatablock) {
   CollisionActiveSend = "0";
   CollisionActiveReceive = "1";
   CollisionPhysicsSend = "0";
   CollisionPhysicsReceive = "1";
   CollisionDetectionMode = "POLYGON";
   CollisionResponseMode = "CLAMP";
   CollisionMaxIterations = "4";
   Friction = "0.7";
   GraphGroup = "1";
   Immovable = "1";
};

// create a named script object to hold all 
// our control objects
%control = new scriptObject(controlObj)
{
   left = "0"; // left key input flag
   right = "0"; // right key input flag
   speed = "150"; // control rotation speed
};

// create a set on our script object that will hold 
// all our controls
controlObj.set = new simSet(); 

// map left and right keys to our control functions
moveMap.bindCmd(keyboard,"left","controlObj.leftOn();","controlObj.leftOff();");
moveMap.bindCmd(keyboard,"right","controlObj.rightOn();","controlObj.rightOff();");
   
// left/right keypress control functions
function controlObj::leftOn(%this)
{
   %this.left = true;
   %this.updateControlMovement();
}
function controlObj::rightOn(%this)
{
   %this.right = true;
   %this.updateControlMovement();
}
function controlObj::leftOff(%this)
{
   %this.left = false;
   %this.updateControlMovement();
}
function controlObj::rightOff(%this)
{
   %this.right = false;
   %this.updateControlMovement();
}

// update control movement
function controlObj::updateControlMovement(%this)
{
   // set rotation speed based on input flags
   if(%this.left && !%this.right)
   {
      %rotation = -%this.speed;
   }
   else if(%this.right && !%this.left)
   {
      %rotation = %this.speed;
   }
   else
   {
      %rotation = 0;
   }

   // apply rotation speed to all control objects 
   // in our control set
   for(%i=0;%i<controlObj.set.getCount();%i++)
      controlObj.set.getObject(%i).setAngularVelocity(%rotation);
}

// onLevelLoaded callback for control objects
function control::onLevelLoaded(%this, %scenegraph)
{
   // add this control object to our simset
   controlObj.set.add(%this);
}

// bumper onCollision callback
function bumper::onCollision(%srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
   // get a force vector based on the normal of the collision
   %force = t2dVectorScale(%normal,150);

   // arapply the impulse force to the object
   %dstObj.setImpulseForce(%force, false);
}

// ball stop trigger onEnter callback
function stopTrig::onEnter(%this, %obj)
{
   // if the object entering me is a 'ball'
   if(%obj.config $= "BallDatablock")
   {
      // remove the constant force and reset its collision
      // mode to clamp, then set it at rest this is done
      // because circle collision has trouble stacking
      // several objects
      %obj.setCollisionResponse("CLAMP");
      %obj.setCollisionDetection("POLYGON");
      %obj.setConstantForceY(0);
      %obj.setImmovable(true);
      %obj.setAtRest();
      
      // move the trigger up for the next object
      %this.setPositionY(%this.getPositionY() - %obj.getHeight());
   }
}


Back