Totally rewrote my previous AS3 smooth follow and rotation script.
This version fixes all the previous issues and optimizes everything. No more “jumpy” rotation.
Click and hold to make the player smoothly rotate to and follow the mouse:
/**
* Player Movement - Follow Mouse on click with Easing and smooth rotation
* ---------------------
* VERSION: 2.0
* DATE: 1/18/2011
* AS3
* UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
**/
package
{
import flash.display .MovieClip ;
import flash.events .Event ;
import flash.events .MouseEvent ;
public class Main extends MovieClip
{
// player settings
private var _moveSpeedMax:Number = 1000 ;
private var _rotateSpeedMax:Number = 15 ;
private var _decay:Number = .98;
private var _destinationX:int = 150 ;
private var _destinationY:int = 150 ;
// player
private var _player:MovieClip ;
// global
private var _isActive:Boolean = false ;
private var _dx:Number = 0 ;
private var _dy:Number = 0 ;
private var _vx:Number = 0 ;
private var _vy:Number = 0 ;
private var _trueRotation:Number = 0 ;
/**
* Constructor
*/
public function Main( )
{
// create player object
createPlayer( ) ;
// add listeners
stage .addEventListener ( Event.ENTER_FRAME , enterFrameHandler) ;
stage .addEventListener ( MouseEvent.MOUSE_UP , onMouseUpHandler) ;
stage .addEventListener ( MouseEvent.MOUSE_DOWN , onMouseDownHandler) ;
}
/**
* Creates player
*/
private function createPlayer( ) :void
{
_player = new Player( ) ;
_player.x = stage .stageWidth / 2 ;
_player.y = stage .stageHeight / 2 ;
stage .addChild ( _player) ;
}
/**
* EnterFrame Handlers
*/
private function enterFrameHandler( event:Event) :void
{
updatePosition( ) ;
updateRotation( ) ;
}
/**
* Calculate Rotation
*/
private function updateRotation( ) :void
{
// calculate rotation
_dx = _player.x - _destinationX;
_dy = _player.y - _destinationY;
// which way to rotate
var rotateTo:Number = getDegrees( getRadians( _dx, _dy) ) ;
// keep rotation positive, between 0 and 360 degrees
if ( rotateTo & gt; _player.rotation + 180 ) rotateTo -= 360 ;
if ( rotateTo & lt; _player.rotation - 180 ) rotateTo += 360 ;
// ease rotation
_trueRotation = ( rotateTo - _player.rotation ) / _rotateSpeedMax;
// update rotation
_player.rotation += _trueRotation;
}
/**
* Calculate Position
*/
private function updatePosition( ) :void
{
// check if mouse is down
if ( _isActive)
{
// update destination
_destinationX = stage .mouseX ;
_destinationY = stage .mouseY ;
// update velocity
_vx += ( _destinationX - _player.x ) / _moveSpeedMax;
_vy += ( _destinationY - _player.y ) / _moveSpeedMax;
}
else
{
// when mouse is not down, update velocity half of normal speed
_vx += ( _destinationX - _player.x ) / _moveSpeedMax * .25;
_vy += ( _destinationY - _player.y ) / _moveSpeedMax * .25;
}
// apply decay (drag)
_vx * = _decay;
_vy * = _decay;
// if close to target, slow down turn speed
if ( getDistance( _dx, _dy) & lt; 50 )
{
_trueRotation * = .5;
}
// update position
_player.x += _vx;
_player.y += _vy;
}
/**
* Mouse DOWN handler
* @param e
*/
private function onMouseDownHandler( e :MouseEvent) :void
{
_isActive = true ;
}
/**
* Mouse UP handler
* @param e
*/
private function onMouseUpHandler( e :MouseEvent) :void
{
_isActive = false ;
}
/**
* Get distance
* @param delta_x
* @param delta_y
* @return
*/
public function getDistance( delta_x:Number , delta_y:Number ) :Number
{
return Math .sqrt ( ( delta_x* delta_x) +( delta_y* delta_y) ) ;
}
/**
* Get radians
* @param delta_x
* @param delta_y
* @return
*/
public function getRadians( delta_x:Number , delta_y:Number ) :Number
{
var r:Number = Math .atan2 ( delta_y, delta_x) ;
if ( delta_y & lt; 0 )
{
r += ( 2 * Math .PI ) ;
}
return r;
}
/**
* Get degrees
* @param radians
* @return
*/
public function getDegrees( radians:Number ) :Number
{
return Math .floor ( radians/ ( Math .PI / 180 ) ) ;
}
}
}
Download Fla Sample
No Comments »