animated "blob" in as3 - actionscript-3

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.

Related

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);
}
}
}

as3 MOUSE_UP stopDrag() not functioning

I am working on a basic as3 slingshot game which uses startDrag() and stopDrag() to let the user pull an object and fire. when the object is not stretching the "elastic" the MOUSE_UP function works as it should, but when it is below the set points and is stretching the string the MOUSE_UP function is not being called.
vars
var gravity = 0.1;
var angle1:Number = 0;
var angle2:Number = 0;
var radius:Number = 1;
var elasticCoefficient:Number = 0.002;
var released:Boolean = true;
var forced:Boolean = false;
var acc:Object = {x:0 , y:0};
var vel:Object = {x:0 , y:0};
var elastic:MovieClip = new MovieClip();
the ENTER_FRAME code is
function doConstantly(e:Event):void
{
acc.x = 0;
acc.y = gravity;
if(released == true)
{
vel.x += acc.x;
vel.y += acc.y;
ball.x += vel.x;
ball.y += vel.y
}
if(ball.y > stage.stageHeight + 500 || ball.y < -50)
{
resetLevel();
}
elastic.graphics.clear();
elastic.graphics.lineStyle(2, 0xFFF2BD);
if(ball.y > point1.y && ball.x < point2.x)
{
forced = true;
var x1:Number = ball.x - point1.x;
var y1:Number = ball.y - point1.y;
var x2:Number = point2.x - ball.x;
var y2:Number = point2.y - ball.y;
var distance1:Number = Math.sqrt(x1 * x1 + y1 * y1);
var distance2:Number = Math.sqrt(x2 * x2 + y2 * y2);
angle1 = Math.atan2(y1,x1);
angle2 = Math.atan2(y2,x2);
var xOffset:Number = Math.cos(angle1 + Math.PI / 2) * radius;
var yOffset:Number = Math.sin(angle1 + Math.PI / 2) * radius;
var xOffset2:Number = Math.cos(angle2 + Math.PI / 2) * radius;
var yOffset2:Number = Math.sin(angle2 + Math.PI / 2) * radius;
angle1 += Math.sin(radius / distance1);
angle2 += Math.sin(radius / distance2) * -1;
elastic.graphics.moveTo(point1.x, point1.y);
elastic.graphics.lineTo(ball.x+xOffset, ball.y+yOffset);
elastic.graphics.moveTo(point2.x, point2.y);
elastic.graphics.lineTo(ball.x+xOffset2, ball.y+yOffset2);
}
else
{
forced = false;
if(forced == true){trace("forced is true")}
if(forced == false){trace("forced is false")}
elastic.graphics.moveTo(point1.x, point1.y);
elastic.graphics.lineTo(point2.x, point2.y);
}
if (released == true && forced == true)
{
acc.x += distance1 * Math.sin(angle2) * elasticCoefficient;
acc.y += - distance1 * Math.cos(angle1) * elasticCoefficient;
acc.x += distance2 * Math.sin(angle1) * elasticCoefficient;
acc.y += - distance2 * Math.cos(angle2) * elasticCoefficient;
vel.x += acc.x;
vel.y += acc.y;
}
}
and the mouse events
function ballMouseDown(event:MouseEvent)
{
//call function to reset level
resetLevel();
//follow mouse
ball.x = mouseX;
ball.y = mouseY;
ball.startDrag();
//set released to false so that gravity wont affect the ball when clicked
released = false;
}
function ballMouseUp(event:MouseEvent)
{
trace("mouse up function called")
released = true; //gravity will affect the ball when released
ball.stopDrag();
}
Thanks.
Try adding the MOUSE_UP handler to the stage instead - at the moment, you will need to release your mouse while it is over the ball which may not be the case.
Update your MOUSE_DOWN handler to attach the listener to the stage:
function ballMouseDown(e:MouseEvent):void
{
// ...your current code.
stage.addEventListener(MouseEvent.MOUSE_UP, ballMouseUp);
}
And removing the listener when the handler is triggered:
function ballMouseUp(e:MouseEvent):void
{
// ...your current code.
stage.removeEventListener(MouseEvent.MOUSE_UP, ballMouseUp);
}

actionscript 3.0 can't figure out why a collision fails with one line in an array of lines

can't figure out why the ball object falls right through line[2] while it bounces off all the others. I have two classes below; a main class that creates the lines along with some collision and motion code for the ball, and a class for the ball. I included a comment above the line in the main class which pertains to the line that doesn't interact. When the program runs, it bounces off of all the lines with some distance based collision code - but passes right through one of the lines- the line created in the array at line[2]
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
public class MultiAngleBounce extends Sprite
{
private var ball:Ball;
private var lines:Array;
private var numLines:uint = 6;
private var gravity:Number = 0.3;
private var bounce:Number = -0.6;
public function MultiAngleBounce()
{
init();
}
private function init():void
{
ball = new Ball(20);
addChild(ball);
ball.x = 100;
ball.y = 100;
//create five lines
lines = new Array();
for(var i:uint = 0; i < numLines; i++)
{
var line:Sprite = new Sprite();
line.graphics.lineStyle(1);
line.graphics.moveTo(-50, 0);
line.graphics.lineTo(50, 0);
addChild(line);
lines.push(line);
}
lines[0].x = 100;
lines[0].y = 100;
lines[0].rotation = 30;
lines[1].x = 100;
lines[1].y = 230;
lines[1].rotation = 50;
//why does this one get ignored
lines[2].x = 250;
lines[2].y = 180;
lines[2].rotation = -30;
lines[3].x = 150;
lines[3].y = 330;
lines[3].rotation = 10;
lines[4].x = 230;
lines[4].y = 250;
lines[4].rotation = -30;
lines[5].x = 300;
lines[5].y = 350;
lines[5].rotation = -20;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
//normal motion code
ball.vy += gravity;
ball.x += ball.vx;
ball.y += ball.vy;
//bounce off ceiling, floor, walls
if(ball.x + ball.radius > stage.stageWidth)
{
ball.x = stage.stageWidth - ball.radius;
ball.vx *= bounce;
}
else if(ball.x - ball.radius < 0)
{
ball.x = ball.radius;
ball.vx *= bounce;
}
if(ball.y + ball.radius > stage.stageHeight)
{
ball.y = stage.stageHeight - ball.radius
ball.vy *= bounce;
}
else if(ball.y - ball.radius < 0)
{
ball.y = ball.radius;
ball.vy *= bounce;
}
//check each line
for(var i:uint = 0; i < numLines; i++)
{
checkLine(lines[i]);
}
}
private function checkLine(line:Sprite):void
{
//get the bounding box of the line
var bounds:Rectangle = line.getBounds(this);
if(ball.x > bounds.left && ball.x < bounds.right)
{
//get angle, sine and cosine
var angle:Number = line.rotation * Math.PI / 180;
var cos:Number = Math.cos(angle);
var sin:Number = Math.sin(angle);
//get position of ball, relative to line
var x1:Number = ball.x - line.x;
var y1:Number = ball.y - line.y;
//rotate coordinates
var y2:Number = cos * y1 - sin * x1;
//rotate velocity
var vy1:Number = cos * ball.vy - sin * ball.vx;
//perform bounce with rotated values
if(y2 > -ball.height / 2 && y2 < vy1)
{
//rotate coordinates
var x2:Number = cos * x1 + sin * y1;
//rotate velocity
var vx1:Number = cos * ball.vx + sin * ball.vy;
y2 = -ball.height / 2;
vy1 *= bounce;
//rotate everything back;
x1 = cos * x2 - sin * y2;
y1 = cos * y2 + sin * x2;
ball.vx = cos * vx1 - sin * vy1;
ball.vy = cos * vy1 + sin * vx1;
ball.x = line.x + x1;
ball.y = line.y + y1;
}
}
}
}
}
package
{
import flash.display.Sprite;
public class Ball extends Sprite
{
public var radius:Number;
private var color:uint;
public var internalAngle:Number;
public var internalRadius:Number;
internal var vx:Number = 0;
internal var vy:Number = 0;
public function Ball(radius:Number = 40, color:uint = 0xff0000)
{
this.radius = radius;
this.color = color;
init();
}
public function init():void {
graphics.beginFill(color);
graphics.drawCircle(0, 0, radius);
graphics.endFill();
}
}
}
You bounds check
if(ball.x > bounds.left && ball.x < bounds.right)
is failing for the second line. The ball hasn't attained enough speed by the time it reaches lines[2] that it can get completely into the bounds rect. You can use
if(line.hitTestObject(ball))
to do collision detection instead.

Physics angular bounce as3

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/

canvas.onmousedown function to add a shape won't work

I have some code, which can be seen below. At the bottom is a block of code to add a shape. For some reason it won't work unless the very first lines of code are different. Up until I added the 'addShape' code, it was all working fine, so I wandered if anyone on here could have a look and perhaps figure out a solution?
Cheers
Jon
EDIT Also available on jsFiddle http://jsfiddle.net/pukster/mfNq4/1/
$(document).ready(function() {
var canvas = $('#myCanvas');
var ctx = canvas.get(0).getContext("2d");
var context = new webkitAudioContext();
var canvasWidth = canvas.width();
var canvasHeight = canvas.height();
$(window).resize(resizeCanvas);
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth - 2);
canvas.attr("height", $(window).get(0).innerHeight - 2);
canvasWidth = canvas.width();
canvasHeight = canvas.height();
};
resizeCanvas();
ctx.strokeStyle = "rgb(255, 0, 0)";
ctx.lineWidth = 2;
var playAnimation = true;
var Ring = function(x, y, radius, vx, vy) {
this.x = x;
this.y = y;
this.radius = radius;
this.vx = vx;
this.vy = vy;
};
var rings = [];
for (var i = 0; i < 10; i++) {
var x = Math.random()*ctx.canvas.width;
var y = Math.random()*ctx.canvas.height;
var vx = Math.random()*6-3;
var vy = Math.random()*6-3;
rings.push(new Ring(x, y, 40, vx, vy));
};
function animate() {
var ringsLength = rings.length;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
for (var i = 0; i < ringsLength; i++) {
var tmpRing = rings[i];
for (var j = i+1; j < ringsLength; j++) {
var tmpRingB = rings[j];
var dx = tmpRingB.x - tmpRing.x;
var dy = tmpRingB.y - tmpRing.y;
var dist = Math.sqrt((dx * dx) + (dy * dy));
if(dist < tmpRing.radius + tmpRingB.radius) {
var sinewave = new SineWave(context);
var angle = Math.atan2(dy, dx);
var sine = Math.sin(angle);
var cosine = Math.cos(angle);
var x = 0;
var y = 0;
var xb = dx * cosine + dy * sine;
var yb = dy * cosine - dx * sine;
var vx = tmpRing.vx * cosine + tmpRing.vy * sine;
var vy = tmpRing.vy * cosine - tmpRing.vx * sine;
var vxb = tmpRingB.vx * cosine + tmpRingB.vy * sine;
var vyb = tmpRingB.vy * cosine - tmpRingB.vx * sine;
vx *= -1;
vxb *= -1;
xb = x + (tmpRing.radius + tmpRingB.radius);
tmpRing.x = tmpRing.x + (x * cosine - y * sine);
tmpRing.y = tmpRing.y + (y * cosine + x * sine);
tmpRingB.x = tmpRing.x + (xb * cosine - yb * sine);
tmpRingB.y = tmpRing.y + (yb * cosine + xb * sine);
tmpRing.vx = vx * cosine - vy * sine;
tmpRing.vy = vy * cosine + vx * sine;
tmpRingB.vx = vxb * cosine - vyb * sine;
tmpRingB.vy = vyb * cosine + vxb * sine;
tmpRing.loop = true;
};
};
tmpRing.x += tmpRing.vx;
tmpRing.y += tmpRing.vy;
if (tmpRing.x - tmpRing.radius < 0) {
var sinwave = new SinWave(context);
tmpRing.x = tmpRing.radius;
tmpRing.vx *= -1;
} else if (tmpRing.x + tmpRing.radius > ctx.canvas.width) {
var sinwave = new SinWave(context);
tmpRing.x = ctx.canvas.width - tmpRing.radius;
tmpRing.vx *= -1;
};
if (tmpRing.y - tmpRing.radius < 0) {
var sinwave = new SinWave(context);
tmpRing.y = tmpRing.radius;
tmpRing.vy *= -1;
} else if (tmpRing.y + tmpRing.radius > ctx.canvas.height) {
var sinwave = new SinWave(context);
tmpRing.y = ctx.canvas.height - tmpRing.radius;
tmpRing.vy *= -1;
};
ctx.beginPath();
ctx.arc(tmpRing.x, tmpRing.y, 40, 0, Math.PI*2, false);
ctx.closePath();
ctx.stroke();
//-------------------- The addRing Function Code --------------------//
var mx, my;
var offsetX, offsetY;
//canvas.onmousedown = sglClick;
function addRing(x, y, radius, vx, vy) {
var x = mx-5;
var y = my-5;
var vx = Math.random()*6-3;
var vy = Math.random()*6-3;
rings.push(new Ring(x, y, 40, vx, vy));
}
function sglClick(e) {
getMouse(e);
addRing();
}
function getMouse(e) {
var element = ctx, offsetX = 0, offsetY = 0;
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
}
};
if(playAnimation) {
setTimeout(animate, 33);
};
};
animate();
});
I noticed a couple of problems.
First, you misspelled SineWave in a few places. Second, you are trying to bind an event to the canvas using canvas.onmousedown = sglClick;. You should try canvas.bind('mousedown', sglClick); instead and you shouldn't do the binding inside of your animate method. It will add a new event each iteration of the animation.