Physics angular bounce as3 - actionscript-3

Below is my current code and i am trying to get my ball to bounce off with the proper angle of refraction based on the random angled walls and direction of the ball...My problem is I have only taken a basic physics class and know the equation "angle of incidence = angle of refraction" also, this is my first year in as3 so my coding is rather crude. The angle seems to be off...the problem is with the code "Bullet.hitTestObject(myblockadeHolder[t])" Thanks guys.
stage.addEventListener(Event.ENTER_FRAME,rotate);
var _trueRotation:Number;
var _dx:Number;
var _dy:Number;
function rotate (e:Event){
// calculate rotation based on mouse X & Y
_dx = Turret.x - stage.mouseX;
_dy = Turret.y - stage.mouseY;
// which way to rotate
var rotateTo:Number = getDegrees(getRadians(_dx, _dy));
// keep rotation positive, between 0 and 360 degrees
if (rotateTo > Turret.rotation + 180) rotateTo -= 360;
if (rotateTo < Turret.rotation - 180) rotateTo += 360;
// ease rotation
_trueRotation = (rotateTo - Turret.rotation - 90) / 3;
// update rotation
Turret.rotation += _trueRotation;
}
//Turret Rotation
//Create an array to hold multiple sprites
var mySpriteHolder:Array = [];
//Create a counter to keep track of the number of sprites
var lbCounter:int = 0;
//Maximum number of sprites on the canvas
var maxLB:int = 1;
//Keypress Code
stage.addEventListener(MouseEvent.CLICK, dropBullet);
//Function for the mouse event to fire bullet
function dropBullet(evt:MouseEvent):void{
var bcos:Number = Math.cos((Turret.rotation - 90) * Math.PI / 180);
var bsin:Number = Math.sin((Turret.rotation - 90) * Math.PI / 180);
//starting x and y
var startx:int = Turret.x + (70 * bcos);
var starty:int = Turret.y + (70 * bsin);
//calculates where the bullet needs to go by aiming in front of the gun
var endx:int = Turret.x + (100 * bcos);
var endy:int = Turret.y + (100 * bsin);
var Bullet:MovieClip = new bullet();
Bullet.x = startx;
Bullet.y = starty;
Bullet.xspeed = (endx - startx)/5;
Bullet.yspeed = (endy - starty)/5;
mySpriteHolder.push(Bullet);
stage.addChild(Bullet);
//this calls the move down function
stage.addEventListener(Event.ENTER_FRAME,BulletFire);
}
//Function to shoot bullet
var Points:Number = 0;
var Life:Number = 100;
stage.addEventListener(Event.ENTER_FRAME, TextCounter);
function BulletFire(evt:Event):void{
var Bullet:MovieClip;
//Use a for loop to move the Bullets
for(var i:int=mySpriteHolder.length-1; i>=0; i--){
Bullet = mySpriteHolder[i];
//Bounds Collision
if(Bullet.hitTestObject(Up)){
Bullet.yspeed*=-1;
}
if(Bullet.hitTestObject(Lower)){
Bullet.yspeed*=-1;
}
if(Bullet.hitTestObject(Left)){
Bullet.xspeed*=-1;
}
if(Bullet.hitTestObject(Right)){
Bullet.xspeed*=-1;
}
if(Bullet.hitTestObject(Tank)){
stage.removeChild(Bullet);
mySpriteHolder.splice(i,1);
lbCounter --;
Life -= 10;
}
//Blockade Collision
for(var t in myBlockadeHolder){
if(Bullet.hitTestObject(myBlockadeHolder[t])){
_trueRotation*=2
var newAngle = (180 - (_trueRotation) - (smallangle))*-1;
var newXspeed = Math.cos(newAngle);
var newYspeed = Math.sin(newAngle);
Bullet.xspeed = newXspeed+2.5;
Bullet.yspeed = newYspeed+2.5;
}
}
//Target Collision
for(var c in mytargetHolder){
if(Bullet.hitTestObject(mytargetHolder[c])){
stage.removeChild(Bullet);
mySpriteHolder.splice(i,1);
lbCounter --;
Points += 10;
mytargetHolder[c].y = Math.random()*380 + 10;
mytargetHolder[c].x = Math.random()*380 + 10;
while(mytargetHolder[c].hitTestObject(Turret)){
mytargetHolder[c].y = Math.random()*380 + 10;
mytargetHolder[c].x = Math.random()*380 + 10;
}
}
for(var a in mytargetHolder){
for(var s in mytargetHolder){
while(mytargetHolder[a].hitTestObject(mytargetHolder[s])&& a!=s){
mytargetHolder[a].y = Math.random()*380 + 10;
mytargetHolder[a].x = Math.random()*380 + 10;
}
}
for(var g in myBlockadeHolder){
while(mytargetHolder[a].hitTestObject(myBlockadeHolder[g])&& a!=g){
mytargetHolder[a].y = Math.random()*380 + 10;
mytargetHolder[a].x = Math.random()*380 + 10;
}
}
}
}
Bullet.y += Bullet.yspeed;
Bullet.x += Bullet.xspeed;
}
}//Bullet Code
stage.addEventListener(Event.ENTER_FRAME, HealthCheck);
function HealthCheck(e:Event):void{
if(Life<=0){
stage.removeEventListener(MouseEvent.CLICK, dropBullet);
stage.removeEventListener(Event.ENTER_FRAME, BulletFire);
stage.removeEventListener(Event.ENTER_FRAME, droptarget);
stage.removeEventListener(Event.ENTER_FRAME, dropblockade);
}
}//Health Code
//variables for blockade
var myblockadeSprite:Sprite;
//blockade is the linkage name in the library
var blockade:Blockade;
//Create an array to hold multiple sprites
var myBlockadeHolder:Array = new Array();
//Create a counter to keep track of the number of sprites
var LbCounter:int = 0;
//Maximum number of sprites on the canvas
var maxlb:int = 6;
//Keypress Code
stage.addEventListener(Event.ENTER_FRAME, dropblockade);
//Function for the mouse event to fire blockade
function dropblockade(evt:Event):void{
for(var i:int=0;i<maxlb; i++){
//PLACE DO LOOP INSIDE TO GENERATE EMPTY IN RANDOM COORDS
//add the blockades to the canvas
myblockadeSprite = new Sprite();
stage.addChild(myblockadeSprite);
//Get the actual picture from the library
blockade = new Blockade();
myblockadeSprite.addChild(blockade);
//Going to load up the array with the sprites
myBlockadeHolder[i] = myblockadeSprite;
myBlockadeHolder[i].y = Math.random()*390 + 10;
myBlockadeHolder[i].x = Math.random()*390 + 10;
myBlockadeHolder[i].rotation = Math.random()*360;
while(myBlockadeHolder[i].hitTestObject(Tank)){
myBlockadeHolder[i].y = Math.random()*390 + 10;
myBlockadeHolder[i].x = Math.random()*390 + 10;
}
}
for(var t:int=0;t<maxlb; t++){
for(var d:int=0;d<maxlb; d++){
while(myBlockadeHolder[t].hitTestObject(myBlockadeHolder[d])&& t!=d){
myBlockadeHolder[t].y = Math.random()*390 + 10;
myBlockadeHolder[t].x = Math.random()*390 + 10;
}
}
}
stage.removeEventListener(Event.ENTER_FRAME, dropblockade);
}//Blockade Code
//variables for target
var mytargetSprite:Sprite;
//target is the linkage name in the library
var target:Target;
//Create an array to hold multiple sprites
var mytargetHolder:Array = new Array();
//Create a counter to keep track of the number of sprites
var TargetCounter:int = 0;
//Maximum number of sprites on the canvas
var maxtrgs:int = 3;
//Keypress Code
stage.addEventListener(Event.ENTER_FRAME, droptarget);
function droptarget(evt:Event):void{
for(var i:int=0;i<maxtrgs; i++){
//PLACE DO LOOP INSIDE TO GENERATE EMPTY IN RANDOM COORDS
//add the targets to the canvas
mytargetSprite = new Sprite();
stage.addChild(mytargetSprite);
//Get the actual picture from the library
target = new Target();
mytargetSprite.addChild(target);
//Going to load up the array with the sprites
mytargetHolder[i] = mytargetSprite;
mytargetHolder[i].y = Math.random()*390 + 10;
mytargetHolder[i].x = Math.random()*390 + 10;
while(mytargetHolder[i].hitTestObject(Tank)){
mytargetHolder[i].y = Math.random()*390 + 10;
mytargetHolder[i].x = Math.random()*390 + 10;
}
}
for(var t:int=0;t<maxtrgs; t++){
for(var d:int=0;d<maxtrgs; d++){
while(mytargetHolder[t].hitTestObject(mytargetHolder[d])&& t!=d){
mytargetHolder[t].y = Math.random()*390 + 10;
mytargetHolder[t].x = Math.random()*390 + 10;
}
}
for(var w:int=0;w<maxtrgs; w++){
while(mytargetHolder[t].hitTestObject(myBlockadeHolder[w])&& t!=w){
mytargetHolder[t].y = Math.random()*390 + 10;
mytargetHolder[t].x = Math.random()*390 + 10;
}
}
}
stage.removeEventListener(Event.ENTER_FRAME, droptarget);
}//Target Code
function getRadians(delta_x:Number, delta_y:Number):Number{
var r:Number = Math.atan2(delta_y, delta_x);
if (delta_y < 0){
r += (2 * Math.PI);
}
return r;
}
/**
* Get degrees
* #param radians Takes radians
* #return Returns degrees
*/
function getDegrees(radians:Number):Number{
return Math.floor(radians/(Math.PI/180));
}
function TextCounter(e:Event):void{
PointCounter.text = String(Points);
LifeCounter.text = String(Life);
}

I'm not really a physics guy but I can refer you to an article/tutorial that will most likely help you solve this issue. If it does, please post your fixed code as an answer because that's a better/more direct answer for this question. If not, hopefully someone else will come along with a better answer:
http://blog.generalrelativity.org/actionscript-30/dynamic-circlecircle-collision-detection-in-actionscript-3/

Related

Actionscript 3.0 Mouse trail snake game logic

I am developing a game in actionscript 3.0 (adobe flash) similar to this https://www.tvokids.com/preschool/games/caterpillar-count. I have the code for dragging the head of the snake in the direction of the mouse. However, I do not know how do I add the body of the snake and make it follow the path of the head. Following is my code to drag movieclip in the direction of the mouse :
var _isActive = true;
var _moveSpeedMax:Number = 1000;
var _rotateSpeedMax:Number = 15;
var _decay:Number = .98;
var _destinationX:int = 150;
var _destinationY:int = 150;
var _dx:Number = 0;
var _dy:Number = 0;
var _vx:Number = 0;
var _vy:Number = 0;
var _trueRotation:Number = 0;
var _player;
var i;
createPlayer();
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function createPlayer():void{
_player = new head();
_player.x = stage.stageWidth / 2;
_player.y = stage.stageHeight / 2;
stage.addChild(_player);
}
function onDown(e:MouseEvent):void{
_isActive = true;
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
function onMove(e:MouseEvent):void{
updatePosition(_player);
updateRotation(_player);
}
function onUp(e:MouseEvent):void{
_isActive = false;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
function updatePosition(mc):void
{
// check if mouse is down
if (_isActive)
{
// update destination
_destinationX = stage.mouseX;
_destinationY = stage.mouseY;
// update velocity
_vx += (_destinationX - mc.x) / _moveSpeedMax;
_vy += (_destinationY - mc.y) / _moveSpeedMax;
}
else
{
// when mouse is not down, update velocity half of normal speed
_vx += (_destinationX - mc.x) / _moveSpeedMax * .25;
_vy += (_destinationY - mc.y) / _moveSpeedMax * .25;
}
// apply decay (drag)
_vx *= _decay;
_vy *= _decay;
// if close to target, slow down turn speed
if (getDistance(_dx, _dy) < 50)
{
_trueRotation *= .5;
}
// update position
mc.x += _vx;
mc.y += _vy;
}
function updateRotation(mc):void
{
// calculate rotation
_dx = mc.x - _destinationX;
_dy = mc.y - _destinationY;
// which way to rotate
var rotateTo:Number = getDegrees(getRadians(_dx, _dy));
// keep rotation positive, between 0 and 360 degrees
if (rotateTo > mc.rotation + 180) rotateTo -= 360;
if (rotateTo < mc.rotation - 180) rotateTo += 360;
// ease rotation
_trueRotation = (rotateTo - mc.rotation) / _rotateSpeedMax;
// update rotation
mc.rotation += _trueRotation;
}
function getDistance(delta_x:Number, delta_y:Number):Number
{
return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
}
function getRadians(delta_x:Number, delta_y:Number):Number
{
var r:Number = Math.atan2(delta_y, delta_x);
if (delta_y < 0)
{
r += (2 * Math.PI);
}
return r;
}
function getDegrees(radians:Number):Number
{
return Math.floor(radians/(Math.PI/180));
}
The script below will not miraculously work on its own, however it has all the logic you need, well-explained. It makes a chain of any length follow its head by certain rules. I used the same principle here many years ago: http://delimiter.ru/games/25-lines/alone.html
// This one will represent the Mouse position.
var Rat:Sprite = new Sprite;
// The ordered list of chain elements.
// It all starts with the Mouse.
var Snake:Array = [Rat];
// Call this one each time you want to
// extend the snake with the piece of tail.
function addTail(aPiece:DisplayObject):void
{
// Get the last snake element.
var lastPiece:DisplayObject = Snake[Snake.length - 1];
// Sync the tail coordinates.
aPiece.x = lastPiece.x;
aPiece.y = lastPiece.y;
// Add the new piece to the snake.
Snake.push(aPiece);
}
// Add the pre-defined head as the first element.
addTail(SnakeHead);
// Now start following the Mouse.
addEventListener(Event.ENTER_FRAME, onFrame);
// Fires every frame and adjusts the whole snake, if needed.
function onFrame(e:Event):void
{
// Sync the attractor point with the Mouse.
Rat.x = mouseX;
Rat.y = mouseY;
// Now lets make each piece follow the previous piece,
// one by one, starting from the head, down to the tail.
for (var i:int = 1; i < Snake.length; i++)
{
followOne(Snake[i - 1], Snake[i]);
}
}
function followOne(A:DisplayObject, B:DisplayObject):void
{
// Think of these values as of vector
// pointing from B position to A position.
var dx:Number = A.x - B.x;
var dy:Number = A.y - B.y;
// Figure out the distance between the given pieces.
var aDist:Number = Math.sqrt(dx * dx + dy * dy);
// Do nothing if pieces are closer than 20 px apart.
// You can change this value to make snake shorter or longer.
if (aDist < 20)
{
return;
}
// This literally means "eat one tenth of the distance
// between me and the previous piece". If you want pieces
// to follow each other with more vigor, reduce this value,
// if you want the whole snake to slither smoothly, increase it.
B.x += dx / 10;
B.y += dy / 10;
// Rotate the B piece so it would look right into A's direction.
// Well, unless your pieces are round and look all the same.
B.rotation = Math.atan2(dy, dx) * 180 / Math.PI;
}

AS3 animate dynamically created movie clips with ENTER_FRAME

I have some code which loads a movie clip from the library, reproduces it and spreads it around the stage in different sizes, positions and rotations. What I can't figure out is how to then animate each one with an ENTER_FRAME event listener - So maybe I can also animate the scale, position and rotations? Any help greatly appreciated. Thanks.
for (var i = 0; i < 20; i++ )
{
//Generate Item from library
var MovieClip_mc:mcMovieClip = new mcMovieClip();
addChild(MovieClip_mc);
//Size
var RandomSize = (Math.random() * 0.5) + 0.5;
MovieClip_mc.scaleX = RandomSize;
MovieClip_mc.scaleY = RandomSize;
//Rotation
var RandomRotation:Number = Math.floor(Math.random()*360);
MovieClip_mc.rotation = RandomRotation;
//Position
MovieClip_mc.x = Math.floor(Math.random() * CanvasWidth);
MovieClip_mc.y = Math.floor(Math.random() * CanvasHeight);
}
For performance benefits, it is better to do it using one ENTER_FRAME handler. The handler can be located in your main class and update each mcMovieClip's properties by calling certain methods declared in the mcMovieClip class. Below is a simple example.
Main class
var mcs:Array = [];
for(var i:int = 0; i < 1; i++)
{
mcs.push(new mcMovieClip());
addChild(mcs[i]);
}
addEventListener(Event.ENTER_FRAME, updateTime);
function updateTime(e:Event):void
{
for(var j:int = 0; j < mcs.length; j++)
{
mcs[j].updatePosition(Math.random() * stage.stageWidth,
Math.random() * stage.stageHeight);
mcs[j].updateRotation(Math.random() * 360);
mcs[j].updateSize(Math.random());
}
}
mcMovieClip class
function updateSize(size:Number):void
{
this.scaleX = this.scaleY = size;
}
function updateRotation(rot:Number):void
{
this.rotation = rot;
}
function updatePosition(newX:Number, newY:Number):void
{
this.x = newX;
this.y = newY;
}
You don't actually need to do that from the outside. You can animate it with its own script in the first frame, so each instance will be animated:
addEventListener(Event.ENTER_FRAME, onFrame);
function onFrame(e:Event):void
{
// Math.random() - 0.5 will produce a random value from -0.5 to 0.5
x += Math.random() - 0.5;
y += Math.random() - 0.5;
scaleX += (Math.random() - 0.5) / 10;
scaleY = scaleX;
rotation += (Math.random() - 0.5) * 5;
}

how to stop particles from moving off stage, Actionscript random particle generator

Below is some code for a random particle generator. I want to change it so the particles only move a small distance before stopping and not disappearing. As it is now, they keep moving until they go off stage. I'm new to Actionscript so any help would be appreciated, thanks.
var particleArray:Array = new Array();
var maxParticles:Number = 50000;
function addParticle(e:Event)
{
var Symbol:Symbol3 = new Symbol3();
Symbol.alpha = Math.random() * .8 + .2;
Symbol.scaleX = Symbol.scaleY = Math.random() * .8 + .2;
Symbol.xMovement = Math.random() * 10 - 5;
Symbol.yMovement = Math.random() * 10 - 5;
Symbol.x = mouseX;
Symbol.y = mouseY;
particleArray.push(Symbol);
addChild(Symbol);
Symbol.cacheAsBitmap = true;
if (particleArray.length >= maxParticles)
{
removeChild(particleArray.shift());
}
Symbol.addEventListener(Event.ENTER_FRAME,moveParticle);
}
function moveParticle(e:Event)
{
e.currentTarget.x += e.currentTarget.xMovement;
e.currentTarget.y += e.currentTarget.yMovement;
}
var myTimer:Timer = new Timer(50);
myTimer.addEventListener(TimerEvent.TIMER, addParticle);
myTimer.start();
One way to do this would be to remove the event listener after a number executions:
function addParticle(e:Event)
{
var Symbol:Symbol3 = new Symbol3();
Symbol.alpha = Math.random() * .8 + .2;
Symbol.scaleX = Symbol.scaleY = Math.random() * .8 + .2;
Symbol.xMovement = Math.random() * 10 - 5;
Symbol.yMovement = Math.random() * 10 - 5;
// set the number of times this instance can move.
// Using a randomly generated number here
Symbol.movementCount = int(Math.random() * 10);
Symbol.x = mouseX;
Symbol.y = mouseY;
particleArray.push(Symbol);
addChild(Symbol);
Symbol.cacheAsBitmap = true;
if (particleArray.length >= maxParticles)
{
removeChild(particleArray.shift());
}
Symbol.addEventListener(Event.ENTER_FRAME,moveParticle);
}
function moveParticle(e:Event)
{
e.currentTarget.x += e.currentTarget.xMovement;
e.currentTarget.y += e.currentTarget.yMovement;
// decrement your move count, and then check to see if it's hit zero
e.currentTarget.movementCount--;
if(e.currentTarget.movementCount <=0)
{
// if so, remove the event listener
e.currentTarget.removeEventListener(Event.ENTER_FRAME, moveParticle);
}
}

Particle's in AS3

I'm currently using this particle system and it work fine. Particle's should be destroy after cross boundry's or alpha's smaller then 0. But however sometimes when i use this code like pereatly 4 it fails and particles cant destory.
function init():void
{
particleArray = [];
addEventListener(Event.ENTER_FRAME, onEnterFrameLoop);
createParticle(s3.whell.x,s3.whell.y);
}
function onEnterFrameLoop(event:Event):void
{
updateParticle();
}
/**
* createParticle(target X position, target Y position)
*/
function createParticle(targetX:Number, targetY:Number):void
{
//run for loop based on particleTotal
for (var i:Number = 0; i < particleTotal; i++)
{
var particle_mc:MovieClip = new Particle();
//set position & rotation, alpha
particle_mc.x = targetX
particle_mc.y = targetY
particle_mc.rotation = Math.random() * 360;
particle_mc.alpha = Math.random() * 1.1;
//set particle boundry
particle_mc.boundyLeft = targetX - particleRange;
particle_mc.boundyTop = targetY - particleRange;
particle_mc.boundyRight = targetX + particleRange;
particle_mc.boundyBottom = targetY + particleRange;
//set speed/direction of fragment
particle_mc.speedX = Math.random() * particleMaxSpeed - Math.random() * particleMaxSpeed;
particle_mc.speedY = Math.random() * particleMaxSpeed - Math.random() * particleMaxSpeed;
particle_mc.speedX *= particleMaxSpeed
particle_mc.speedY *= particleMaxSpeed
//set fade out speed
particle_mc.fadeSpeed = Math.random()*particleFadeSpeed;
//just a visual particle counter
particleCurrentAmount++;
// add to array
particleArray.push(particle_mc);
// add to display list
addChild(particle_mc);
}
}
function updateParticle():void
{
for (var i = 0; i < particleArray.length; i++)
{
var tempParticle:MovieClip = particleArray[i];
//update alpha, x, y
tempParticle.alpha -= tempParticle.fadeSpeed;
tempParticle.x += tempParticle.speedX;
tempParticle.y += tempParticle.speedY;
// if fragment is invisible remove it
if (tempParticle.alpha <= 0)
{
destroyParticle(tempParticle);
}
// if fragment is out of bounds, increase fade out speed
else if (tempParticle.x < tempParticle.boundyLeft ||
tempParticle.x > tempParticle.boundyRight ||
tempParticle.y < tempParticle.boundyTop ||
tempParticle.y > tempParticle.boundyBottom)
{
tempParticle.fadeSpeed += 8;
destroyParticle(tempParticle);
}
}
}
function destroyParticle(particle:MovieClip):void
{
for (var i = 0; i < particleArray.length; i++)
{
var tempParticle:MovieClip = particleArray[i];
if (tempParticle == particle)
{
particleCurrentAmount--;
particleArray.splice(i,1);
removeChild(tempParticle);
}
}
}

animated "blob" in as3

I am currently playing around with a blob code and have a small problem.
The problem is that sometimes the blob gets inverted so the white color gets inside the blob itself and makes a white hole in it which I don't really want.
Any suggestions on how to fix this, so the blob stays all the time as one little nice piece?
This is the one im playing around with:
http://wonderfl.net/c/rYzh
class Blob extends Sprite
{
private var speed :Number = .01;
private var grav :Number = .25;
private var dist :Number = 27;
private var k :Number = .55;
private var damp :Number = .99;
private var cx :Number = 370;
private var cy :Number = 0;
private var points :Array = [];
private var mids :Array = [];
private var numPoints:Number = 30;
private var oneSlice :Number = Math.PI * 2 / numPoints;
private var radius :Number = 100;
public function Blob()
{
for (var i:Number = 0; i < numPoints; i++)
{
var angle:Number = oneSlice * i;
var obj:Object = {x:Math.cos(angle) * radius + cx, y:Math.sin(angle) * radius + cy, a:angle - Math.PI / 2, wave:i*.08, vx:0, vy:0};
points[i] = obj;
}
this.addEventListener(Event.ENTER_FRAME, update);
}
private function update(event:Event):void
{
this.graphics.clear();
this.graphics.lineStyle(1, 0x666666, 50);
this.graphics.beginFill(0x000000, 100);
for (var i:Number = 0; i < numPoints-1; i++)
{
mids[i] = {x:(points[i].x + points[i + 1].x) / 2, y:(points[i].y + points[i + 1].y) / 2};
}
mids[i] = {x:(points[i].x + points[0].x) / 2, y:(points[i].y + points[0].y) / 2};
this.graphics.moveTo(mids[0].x, mids[0].y);
for (var j:Number = 0; j < numPoints - 1; j++)
{
this.graphics.curveTo(points[j+1].x, points[j+1].y, mids[j+1].x, mids[j+1].y);
}
this.graphics.curveTo(points[0].x, points[0].y, mids[0].x, mids[0].y);
this.graphics.endFill();
var point:Object;
for (var k:Number = 0; k < numPoints - 1; k++)
{
point = points[k];
spring(point, points[k + 1]);
mouseSpring(point);
}
spring(points[k], points[0]);
mouseSpring(points[k]);
for (var l:Number = 0; l < numPoints; l++)
{
point = points[l];
point.vx *= damp;
point.vy *= damp;
point.vy += grav;
point.x += point.vx;
point.y += point.vy;
if (point.y > stage.stageHeight)
{
point.y = stage.stageHeight;
point.vy = 0;
}
if (point.x < 20)
{
point.x = 20;
point.vx = 0;
}
else if (point.x > stage.stageWidth)
{
point.x = stage.stageWidth;
point.vx = 0;
}
}
}
private function spring(p0:Object, p1:Object):void
{
var dx:Number = p0.x - p1.x;
var dy:Number = p0.y - p1.y;
var angle:Number = p0.a+Math.sin(p0.wave += speed)*2;
var tx:Number = p1.x + dist * Math.cos(angle);
var ty:Number = p1.y + dist * Math.sin(angle);
var ax:Number = (tx - p0.x) * k;
var ay:Number = (ty - p0.y) * k;
p0.vx += ax * .5;
p0.vy += ay * .5;
p1.vx -= ax * .5;
p1.vy -= ay * .5;
}
private function mouseSpring(p:Object):void
{
var dx:Number = p.x - stage.mouseX;
var dy:Number = p.y - stage.mouseY;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
if (dist < 40)
{
var angle:Number = Math.atan2(dy, dx);
var tx:Number = stage.mouseX + Math.cos(angle) * 40;
var ty:Number = stage.mouseY + Math.sin(angle) * 40;
p.vx += (tx - p.x) * k;
p.vy += (ty - p.y) * k;
}
}
}
By default, the Graphics APIs use an evenOdd winding, which means if a filled path overlaps itself, it negates the fill.
You need to use the Graphics.drawPath function with a winding value of "nonZero". This will cause it not to negate when the path overlaps itself. Check out this little demo, make a shape that overlaps itself, and switch the winding from evenOdd to nonZero to see how it works.
As for translating your code, instead of using graphics.moveTo() and .curveTo() calls in your update() routine, you'll need to build up a description of your path (aka, the inputs to drawPath) and pass them into graphics.drawPath() last. Adobe shows an example here.