Smooth Moving with Catmull-Rom splines
/**
* Copyright heart_thai ( http://wonderfl.net/user/heart_thai )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pDSy
*/
package {
import flash.text.engine.TextBlock;
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.*
import flash.events.MouseEvent;
import flash.events.Event;
public class CatmulTest extends Sprite {
private var titleText:TextField;
private var spot:Vector.<Point>;
private var moveBall:Sprite;
private var currentSpot:int = 0;
private var time:int = 0;
private var reserBtn:Sprite;
public function CatmulTest() {
// write as3 code here..
createTextTitle();
spot = new Vector.<Point>();
stage.addEventListener(MouseEvent.CLICK , putPoint );
makeResetBtn();
}
private function putPoint(e:MouseEvent):void{
if( !reserBtn.hitTestPoint(e.stageX , e.stageY) ){
spot.push(new Point(e.stageX , e.stageY));
this.graphics.clear();
for (var i:int = 0; i < spot.length; i++) {
this.graphics.beginFill(0xFF0000 , 1 );
this.graphics.drawCircle(spot[i].x , spot[i].y ,3);
this.graphics.endFill();
var p0:Point = spot [(i -1 + spot.length) % spot.length];
var p1:Point = spot[i];
var p2:Point = spot [(i +1 + spot.length) % spot.length];
var p3:Point = spot[(i +2 + spot.length) % spot.length];
this.graphics.lineStyle(1,0x00FF00 , 0.3 );
this.graphics.moveTo(p2.x , p2.y );
this.graphics.lineTo(p3.x , p3.y);
this.graphics.lineStyle (0, 0x7FFF);
this.graphics.moveTo (p1.x, p1.y);
for (var j:int = 1; j < 101; j++) {
var q:Point = spline (p0, p1, p2, p3, 0.01 * j);
this.graphics.lineTo (q.x, q.y);
}
this.graphics.lineStyle ();
this.graphics.endFill ();
}
if(spot.length == 3){
makeBall();
this.addEventListener(Event.ENTER_FRAME , animation );
}
}
}
private function makeBall():void{
moveBall = new Sprite();
addChild(moveBall);
moveBall.graphics.beginFill(0xFFCC00 , 0.5 );
moveBall.graphics.drawCircle(0,0,20);
moveBall.x = spot[0].x;
moveBall.y = spot[0].y;
}
private function animation(e:Event):void{
var p0:Point = spot [(currentSpot-1 + spot.length) % spot.length];
var p1:Point = spot[currentSpot ];
var p2:Point = spot [(currentSpot +1 + spot.length) % spot.length];
var p3:Point = spot[(currentSpot +2 + spot.length) % spot.length];
var pointSpot:Point = spline (p0, p1, p2, p3, 0.01 * time);
moveBall.x = pointSpot.x;
moveBall.y = pointSpot.y;
time+=2;
if(time == 100){
time=0;
currentSpot++;
if(currentSpot > spot.length-1){
currentSpot = 0;
}
}
}
private function createTextTitle():void{
titleText = new TextField();
addChild(titleText);
titleText.text = "Click For Draw Spot more than 3 Spot";
titleText.selectable = false;
titleText.autoSize = TextFieldAutoSize.LEFT;
var tf:TextFormat = new TextFormat();
tf.size = 20;
tf.font = "Verdana";
tf.color = 0x555555;
titleText.setTextFormat(tf);
titleText.x = (stage.stageWidth/2)-(titleText.width/2);
titleText.y = (stage.stageHeight/2)-(titleText.height/2);
}
private function spline (p0:Point, p1:Point, p2:Point, p3:Point, t:Number):Point
{
return new Point (
0.5 * (( 2*p1.x) +
t * (( -p0.x +p2.x) +
t * ((2*p0.x -5*p1.x +4*p2.x -p3.x) +
t * ( -p0.x +3*p1.x -3*p2.x +p3.x)))),
0.5 * (( 2*p1.y) +
t * (( -p0.y +p2.y) +
t * ((2*p0.y -5*p1.y +4*p2.y -p3.y) +
t * ( -p0.y +3*p1.y -3*p2.y +p3.y))))
);
}
private function makeResetBtn():void{
reserBtn = new Sprite();
var labelTxt:TextField = new TextField();
addChild(reserBtn);
reserBtn.addChild(labelTxt);
labelTxt.text ="Click Here To Reset";
labelTxt.autoSize = TextFieldAutoSize.LEFT;
reserBtn.graphics.beginFill(0x00CCFF , 0.5 );
reserBtn.graphics.drawRect( 0 , 0, labelTxt.width , labelTxt.height );
labelTxt.selectable = false;
reserBtn.addEventListener(MouseEvent.CLICK , reset );
reserBtn.buttonMode = true;
}
private function reset(e:MouseEvent):void{
this.removeEventListener(Event.ENTER_FRAME , animation );
removeChild(moveBall);
moveBall = null;
spot = new Vector.<Point>();
this.graphics.clear();
}
}
}