ryanhallcs

Spring Camera PBE Component

Jun 7th, 2011
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package  
  2. {
  3.     import com.pblabs.engine.components.TickedComponent;
  4.     import com.pblabs.engine.entity.IEntity;
  5.     import com.pblabs.engine.entity.PropertyReference;
  6.     import com.pblabs.engine.PBE;
  7.     import flash.geom.Point;
  8.     import com.pblabs.engine.debug.Logger;
  9.    
  10.     /**
  11.      * Gives a "Springy" feel to following behavior
  12.      * @author Ryan Hall
  13.      */
  14.     public class SpringFollowComponent extends TickedComponent
  15.     {
  16.         //{ Fields and Properties
  17.         private var _dragPerSecond:Number = 0.9,
  18.                     _springStiffness:Number = 0.9,
  19.                     _springDamping:Number = 0.08,
  20.                     _assumedMass:Number = 0.05;
  21.        
  22.         // spring coeffiients precomputed
  23.         private var _f1Scale:Number = _springStiffness * _assumedMass,
  24.                     _f2Scale:Number = -_springDamping * _assumedMass;
  25.        
  26.         // need to grab position reference from entity being followed
  27.         protected var _follow:IEntity;
  28.         protected var _following:Boolean = false;
  29.         protected var _velocity:Point = new Point; // used as a vector
  30.        
  31.         /*
  32.          * Stiffness coeficient used in spring formula. Function will update scales used for you.
  33.          */
  34.         public function get springStiffness():Number { return _springStiffness; }
  35.         public function set springStiffness(value:Number):void
  36.         {
  37.             _springStiffness = value;
  38.             _f1Scale = _springStiffness * _assumedMass;
  39.         }
  40.        
  41.         /*
  42.          * Damping coeficient used in spring formula. Function will update scales used for you.
  43.          */
  44.         public function get springDamping():Number { return _springDamping; }
  45.         public function set springDamping(value:Number):void
  46.         {
  47.             _springDamping = value;
  48.             _f2Scale = -_springDamping * _assumedMass;
  49.         }
  50.        
  51.         /*
  52.          * Assumed mass coeficient used in spring formula. Function will update scales used for you.
  53.          */
  54.         public function get assumedMass():Number { return _assumedMass; }
  55.         public function set assumedMass(value:Number):void
  56.         {
  57.             _assumedMass = value;
  58.             _f1Scale = _springStiffness * _assumedMass;
  59.             _f2Scale = -_springDamping * _assumedMass;
  60.         }
  61.    
  62.         // Reference position camera is currently at
  63.         public var worldPositionReference:PropertyReference;
  64.        
  65.         // Reference position target is currently at (using _follow)
  66.         public var followPositionReference:PropertyReference;
  67.        
  68.         // true if coordinate system needs to be negated
  69.         public var isCoordReverse:Boolean = true;
  70.        
  71.         /*
  72.          * Set entity to follow. Which position to follow is left up to user. All that is assumed is that it is a point.
  73.          * Defaults to spatial position.
  74.          */
  75.         public function set follow(value:IEntity):void
  76.         {
  77.             _follow = value;
  78.            
  79.             if (_follow && _follow.getProperty(followPositionReference) is Point)
  80.             {
  81.                 _following = true;
  82.             }
  83.             else
  84.             {
  85.                 Logger.warn(this, "follow", "Failed to get follow entity or property reference for following object");
  86.                 _following = false;
  87.             }
  88.         }
  89.        
  90.         public function set followName(value:String):void
  91.         {
  92.             _follow = PBE.lookupEntity(value);
  93.            
  94.             if (!_follow)
  95.                 Logger.warn(this, "followName", "Failed to retrieve entity named: " + value);
  96.             else if (!_follow.getProperty(followPositionReference) is Point)
  97.                 Logger.warn(this, "follow", "Failed to get follow entity or property reference for following object");
  98.             else
  99.                 _following = true;
  100.         }
  101.         //}
  102.        
  103.         override protected function onAdd():void
  104.         {
  105.             super.onAdd();
  106.            
  107.             // Set world position and follow position to sensible defaults if they are not set already
  108.             if (!worldPositionReference)
  109.                 Logger.warn(this, "onAdd", "This component requires a world position to function correctlty.");
  110.         }
  111.        
  112.         // Temp reusable Point objects
  113.         private var _F1:Point = new Point(),
  114.                     _F2:Point = new Point(),
  115.                     _crntPos:Point = new Point();
  116.        
  117.         override public function onTick(deltaTime:Number):void
  118.         {
  119.             super.onTick(deltaTime);
  120.            
  121.             // Grab the current world position
  122.             _crntPos = owner.getProperty(worldPositionReference);
  123.            
  124.             if (!_crntPos)
  125.                 return;
  126.            
  127.             // reverse coords if neccessary
  128.             if (isCoordReverse)
  129.             {
  130.                 _crntPos.x *= -1.0;
  131.                 _crntPos.y *= -1.0;
  132.             }
  133.            
  134.             // Use follow or noFollow functions, respectively
  135.             if (_following)
  136.                 followTarget(deltaTime);
  137.             else
  138.                 noFollowTarget(deltaTime);
  139.            
  140.             // add modified velocity
  141.             _crntPos.x += _velocity.x;
  142.             _crntPos.y += _velocity.y;
  143.            
  144.             if (isCoordReverse)
  145.             {
  146.                 _crntPos.x *= -1.0;
  147.                 _crntPos.y *= -1.0;
  148.             }
  149.            
  150.             // apply changes
  151.             owner.setProperty(worldPositionReference, _crntPos);
  152.         }
  153.        
  154.         /*
  155.          * Called each tick while there is a target to follow
  156.          */
  157.         protected function followTarget(deltaTime:Number):void
  158.         {
  159.             // Spring action towards target
  160.             _F1 = _follow.getProperty(followPositionReference) as Point;
  161.             _F1.x = (_F1.x - _crntPos.x) * _f1Scale;
  162.             _F1.y = (_F1.y - _crntPos.y) * _f1Scale;
  163.            
  164.             _F2.x = _velocity.x * _f2Scale;
  165.             _F2.y = _velocity.y * _f2Scale;
  166.            
  167.             _velocity.x = _F1.x + _F2.x;
  168.             _velocity.y = _F1.y + _F2.y;
  169.         }
  170.        
  171.         /*
  172.          * Called each tick there is no target to follow
  173.          */
  174.         protected function noFollowTarget(deltaTime:Number):void
  175.         {
  176.             // If velocity is zero or less, set to zero
  177.             if (_velocity.x * _velocity.x + _velocity.y * _velocity.y <= 0.0)
  178.             {
  179.                 _velocity.x = 0.0;
  180.                 _velocity.y = 0.0;
  181.                 return;
  182.             }
  183.            
  184.             // Apply drag to camera if it is moving
  185.             _F1.x = _velocity.x * (deltaTime * _dragPerSecond);
  186.             _F1.y = _velocity.y * (deltaTime * _dragPerSecond);
  187.             _velocity.x -= _F1.x;
  188.             _velocity.y -= _F1.y;
  189.         }
  190.     }
  191.  
  192. }
Advertisement
Add Comment
Please, Sign In to add comment