Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package
- {
- import com.pblabs.engine.components.TickedComponent;
- import com.pblabs.engine.entity.IEntity;
- import com.pblabs.engine.entity.PropertyReference;
- import com.pblabs.engine.PBE;
- import flash.geom.Point;
- import com.pblabs.engine.debug.Logger;
- /**
- * Gives a "Springy" feel to following behavior
- * @author Ryan Hall
- */
- public class SpringFollowComponent extends TickedComponent
- {
- //{ Fields and Properties
- private var _dragPerSecond:Number = 0.9,
- _springStiffness:Number = 0.9,
- _springDamping:Number = 0.08,
- _assumedMass:Number = 0.05;
- // spring coeffiients precomputed
- private var _f1Scale:Number = _springStiffness * _assumedMass,
- _f2Scale:Number = -_springDamping * _assumedMass;
- // need to grab position reference from entity being followed
- protected var _follow:IEntity;
- protected var _following:Boolean = false;
- protected var _velocity:Point = new Point; // used as a vector
- /*
- * Stiffness coeficient used in spring formula. Function will update scales used for you.
- */
- public function get springStiffness():Number { return _springStiffness; }
- public function set springStiffness(value:Number):void
- {
- _springStiffness = value;
- _f1Scale = _springStiffness * _assumedMass;
- }
- /*
- * Damping coeficient used in spring formula. Function will update scales used for you.
- */
- public function get springDamping():Number { return _springDamping; }
- public function set springDamping(value:Number):void
- {
- _springDamping = value;
- _f2Scale = -_springDamping * _assumedMass;
- }
- /*
- * Assumed mass coeficient used in spring formula. Function will update scales used for you.
- */
- public function get assumedMass():Number { return _assumedMass; }
- public function set assumedMass(value:Number):void
- {
- _assumedMass = value;
- _f1Scale = _springStiffness * _assumedMass;
- _f2Scale = -_springDamping * _assumedMass;
- }
- // Reference position camera is currently at
- public var worldPositionReference:PropertyReference;
- // Reference position target is currently at (using _follow)
- public var followPositionReference:PropertyReference;
- // true if coordinate system needs to be negated
- public var isCoordReverse:Boolean = true;
- /*
- * Set entity to follow. Which position to follow is left up to user. All that is assumed is that it is a point.
- * Defaults to spatial position.
- */
- public function set follow(value:IEntity):void
- {
- _follow = value;
- if (_follow && _follow.getProperty(followPositionReference) is Point)
- {
- _following = true;
- }
- else
- {
- Logger.warn(this, "follow", "Failed to get follow entity or property reference for following object");
- _following = false;
- }
- }
- public function set followName(value:String):void
- {
- _follow = PBE.lookupEntity(value);
- if (!_follow)
- Logger.warn(this, "followName", "Failed to retrieve entity named: " + value);
- else if (!_follow.getProperty(followPositionReference) is Point)
- Logger.warn(this, "follow", "Failed to get follow entity or property reference for following object");
- else
- _following = true;
- }
- //}
- override protected function onAdd():void
- {
- super.onAdd();
- // Set world position and follow position to sensible defaults if they are not set already
- if (!worldPositionReference)
- Logger.warn(this, "onAdd", "This component requires a world position to function correctlty.");
- }
- // Temp reusable Point objects
- private var _F1:Point = new Point(),
- _F2:Point = new Point(),
- _crntPos:Point = new Point();
- override public function onTick(deltaTime:Number):void
- {
- super.onTick(deltaTime);
- // Grab the current world position
- _crntPos = owner.getProperty(worldPositionReference);
- if (!_crntPos)
- return;
- // reverse coords if neccessary
- if (isCoordReverse)
- {
- _crntPos.x *= -1.0;
- _crntPos.y *= -1.0;
- }
- // Use follow or noFollow functions, respectively
- if (_following)
- followTarget(deltaTime);
- else
- noFollowTarget(deltaTime);
- // add modified velocity
- _crntPos.x += _velocity.x;
- _crntPos.y += _velocity.y;
- if (isCoordReverse)
- {
- _crntPos.x *= -1.0;
- _crntPos.y *= -1.0;
- }
- // apply changes
- owner.setProperty(worldPositionReference, _crntPos);
- }
- /*
- * Called each tick while there is a target to follow
- */
- protected function followTarget(deltaTime:Number):void
- {
- // Spring action towards target
- _F1 = _follow.getProperty(followPositionReference) as Point;
- _F1.x = (_F1.x - _crntPos.x) * _f1Scale;
- _F1.y = (_F1.y - _crntPos.y) * _f1Scale;
- _F2.x = _velocity.x * _f2Scale;
- _F2.y = _velocity.y * _f2Scale;
- _velocity.x = _F1.x + _F2.x;
- _velocity.y = _F1.y + _F2.y;
- }
- /*
- * Called each tick there is no target to follow
- */
- protected function noFollowTarget(deltaTime:Number):void
- {
- // If velocity is zero or less, set to zero
- if (_velocity.x * _velocity.x + _velocity.y * _velocity.y <= 0.0)
- {
- _velocity.x = 0.0;
- _velocity.y = 0.0;
- return;
- }
- // Apply drag to camera if it is moving
- _F1.x = _velocity.x * (deltaTime * _dragPerSecond);
- _F1.y = _velocity.y * (deltaTime * _dragPerSecond);
- _velocity.x -= _F1.x;
- _velocity.y -= _F1.y;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment