Rope Class
♥0 |
Line 90 |
Modified 2011-09-06 12:42:14 |
MIT License
archived:2017-03-30 22:06:29
ActionScript3 source code
/**
* Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/fg4P
*/
package
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.MovieClip;
import flash.display.Sprite;
public class Rope extends Sprite
{
public var gravity:Number = 0;
public var elastics:Number = 0.2;
public var friction:Number = 0.1;
private var startPoint:Object;
private var endPoint:Object;
private var segments:Number = 0;
public function Rope(segments:Number, startx:Number, starty:Number, endx:Number, endy:Number)
{
this.initCord(segments, startx, starty, endx, endy);
}
/**
* ...
* Update the startPoint object. Use this if you need to update the points of the rope without creating a new rope instance
* @param x: change the startPoint.x value
* @param y: change the startPoint.y value
*/
public function setStartPoint(x:Number, y:Number):void
{
this.startPoint.x = x || 0;
this.startPoint.y = y || 0;
}
/**
* ...
* Update the endPoint object. Use this if you need to update the points of the rope without creating a new rope instance
* @param x: change the endPoint.x value
* @param y: change the endPoint.y value
*/
public function setEndPoint(x:Number, y:Number):void
{
this.endPoint.x = x || 0;
this.endPoint.y = y || 0;
}
public function get _segments():Number
{
return this.segments;
}
/**
* ...
* Redraw function. This is the function that you use to update the cord on a loop
* @param cord: the Sprite object where the rope is located
*/
public function reDraw(cord:Sprite):void
{
// this is the core of the rope functionality
// this function creates a series of steps to be drawn on the sprite with the curveTo method
var segments:Number = (this.segments*2+1);
var elastics:Number = this.elastics;
var friction:Number = 1-this.friction;
var gravity:Number = this.gravity / segments;
// the pointer is moved to the startPoint.x and startPoint.y
cord.graphics.moveTo(this.startPoint.x, this.startPoint.y);
// the current_point object is created based on the next points to draw
var current_point:Object = this.startPoint.next_point;
// a loop runs all those points
while (current_point.next_point)
{
// target variables are created. this variables assign how much length is left for the startPoint meet the endPoint
var targetx:Number = (current_point.prev_point.x+current_point.next_point.x)/2;
var targety:Number = (current_point.prev_point.y + current_point.next_point.y) / 2;
// the step values are increased based on how much length is needed. here also the elastic multiplier is applied for the X and Y axis and the gravity is applied to the Y axis
current_point.x_step += (targetx-current_point.x)*elastics;
current_point.y_step += (targety - current_point.y) * elastics + gravity;
// the step vales are multiplied by the friction (easing)
current_point.x_step *= friction;
current_point.y_step *= friction;
// the current point object increases with the finalized step values. all done to be drawn on the sprite
current_point.x += current_point.x_step;
current_point.y += current_point.y_step;
// the current point refreshes to start a new point
current_point = current_point.next_point;
}
if (cord)
{
var control_point:Object = this.startPoint.next_point;
// a loop runs all points
while (control_point.next_point)
{
// draws a quadratic curve based on the next points to go
cord.graphics.curveTo(control_point.x, control_point.y, (control_point.next_point.x+control_point.x)/2, (control_point.next_point.y+control_point.y)/2);
control_point = control_point.next_point;
}
// when the curve is finished, a line is drawn to reach the control points
cord.graphics.lineTo(control_point.x, control_point.y);
}
}
/**
* ...
* @private
* This initializes the cord engine. Creates the segments, start and end point objects
*/
private function initCord(segments:Number, startx:Number, starty:Number, endx:Number, endy:Number):void
{
if (!segments || segments < 1)
{
segments = 1;
}
this.segments = segments;
this.startPoint = {x:startx || 0, y:starty || 0};
//
var x_step:Number = (endx-startx)/segments || 0;
var y_step:Number = (endy - starty) / segments || 0;
var current_point:Object = this.startPoint;
while ((--segments) > 0)
{
current_point = this.addPoint(current_point, x_step, y_step);
}
current_point = this.addPoint(current_point, x_step, y_step);
this.endPoint = {x:endx || 0, y:endy || 0, prev_point:current_point};
current_point.next_point = this.endPoint;
}
private function addPoint(prev_point:Object, x_step:Number, y_step:Number):Object
{
var new_point:Object = {y_step:0, x_step:0, prev_point:prev_point, y:prev_point.y+y_step, x:prev_point.x+x_step};
prev_point.next_point = new_point;
return new_point;
}
}
}