Type Coercion failed: cannot convert []#13a355b9 to flash.display.DisplayObject - actionscript-3

I get this error when running, no compile errors.
package {
import flash.display.*;
import flash.events.*;
import flash.utils.*;
public class mainCode extends MovieClip{
//global variables go here
public var circled:Shape = new Shape();
public var circled2:Shape = new Shape();
public var circled3:Shape = new Shape();
public var angled:int = new int();
public var circlearray1:Array = new Array(4);
public var circlearray2:Array = new Array(4);
public function mainCode(){
makeCircle(circled, 100);
makeCircle(circled2, 50);
makeCircle(circled3, 50);
for(var i:int=0; i<4; i++){circlearray1[i] = new Array(20);}
for(var n:int=0; n<4; n++){circlearray2[n] = new Array(20);}
stage.addEventListener(Event.ENTER_FRAME, mainLoop);
}
//functions go here
private function mainLoop(e:Event){
trace(1);
angled+=1;
angled%=360;
circled.x = stage.stageWidth / 2;
circled.y = stage.stageHeight/ 2;
circled2.x = circled.x + 100*Math.cos(radians(angled));
circled2.y = circled.y + 100*Math.sin(radians(angled));
circled3.x = circled.x + 100*Math.cos(radians((angled + 180) % 360));
circled3.y = circled.y + 100*Math.sin(radians((angled + 180) % 360));
trace(2);
for (var i:int = 0; i < 4; i++)
{
trace(3);
if (circlearray1[i][0] != undefined)
{removeChild(circlearray1[i][0]);}
if (circlearray2[i][0] != undefined)
{removeChild(circlearray2[i][0]);}
trace(4);
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[m+1];
circlearray2[i][m] = circlearray2[m+1];
}
circlearray1[i][19] = new Shape();
circlearray2[i][19] = new Shape();
makeCircle(circlearray1[i][19], 25);
makeCircle(circlearray2[i][19], 25);
circlearray1[i][19].x = circled2.x + 50*Math.cos(radians(((-angled + (i*90)) * 2) % 360));
circlearray1[i][19].y = circled2.y + 50*Math.sin(radians(((-angled + (i*90)) * 2) % 360));
circlearray2[i][19].x = circled3.x + 50*Math.cos(radians(((-angled + (i*90)) * 2) % 360));
circlearray2[i][19].y = circled3.y + 50*Math.sin(radians(((-angled + (i*90)) * 2) % 360));
trace(8);
}
}
private function makeCircle(circles:Shape, radius:int)
{
circles.graphics.clear();
circles.graphics.lineStyle(2,0x000000);
circles.graphics.beginFill(0x990000);
circles.graphics.drawCircle(0,0,radius);
circles.graphics.endFill();
addChild(circles);
}
private function degrees(radians:Number):Number
{
return radians * 180/Math.PI;
}
private function radians(degrees:Number):Number
{
return degrees * Math.PI / 180;
}
private function killCircle(circlei:Shape):void {
removeChild(circlei);
}
}
}
I've traced it down to {removeChild(circlearray1[i][0]);}, which seems to be returning the error. I have no idea why it's doing this, I've tried alternatives such as circlearray1[i][0].parent.removeChild(circlearray1[i][0]); and if (circlearray1[i][0] is Shape) ... , but no dice.
For reference, I'm trying to make some circles circle around other circles, but have the outermost circles leave an "image lag" (or afterimage) while moving. I do this by creating objects and deleting them using for loops and multidimensional arrays, as I dont feel like typing out 50 create object calls manually and edit each one manually.

Probably, this part:
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[m+1];
circlearray2[i][m] = circlearray2[m+1];
}
You assign to endpoint elements, which you initially assume to be Shapes the elements which are Arrays. Then later you go at circlearray1[i][0] assuming it is Shape if it is not empty, but it is already an Array due to the assignment above. It's probably a typo and you meant this:
for (var m:int = 0; m < 19; m++)
{
circlearray1[i][m] = circlearray1[i][m+1];
circlearray2[i][m] = circlearray2[i][m+1];
}
There's actually a more clean way to do that. Array in AS3 is a lot like C# ArrayList, you can insert elements to either end and extract elements from either end without re-indexing elements manually:
trace(3);
// If you are sure the first element is not empty
// you can get its reference removing them from
// the Array at the same time.
removeChild(circlearray1[i].shift());
removeChild(circlearray2[i].shift());
trace(4);
// All Array elements are automatically shifted
// by -1 so you don't need to move each of them manually.
circlearray1[i][19] = new Shape();
circlearray2[i][19] = new Shape();

Related

How to change MovieClip transparency based on mouse position?

So, I'm trying to make a grid of rectangles each get more transparent the closer the mouse is to it.
Using some basic maths, I thought I had got it, but instead it seems I got a weird graphic bug(maybe?) shown here:
The middle of the rings is where the mouse is.
Part of code that deals with transparency:
private function update(e:Event = null):void
{
for (var i:int = 0; i < buttons.length; i++) {
lightFact = getDistance(buttons[i])
lightBrightness = lightPower - (lightFact * 10)
buttons[i].alpha = lightBrightness
}
}
getDistance is just getting distance from the block to the mouse.
Each rectangle is a movie clip, if that matters.
If you are trying to do this:
Then I think your problem is basically that your alpha value is ranging from 0 to about 3000 or something like that. That's going to cause strange effects. The value needs to range smoothly from 0 to 1 (so it needs to be a floating point number as in Number).
Here is the code which generated the image above which I wrote for you that will get you started in the right direction:
package
{
import flash.display.*;
import flash.events.*;
public class lightFactTest extends MovieClip
{
private var boxesArray: Array = new Array();
private var xDist: Number = 0;
private var yDist: Number = 0;
private var d: Number = 0;
private var size_Glow : Number = 0;
private var size_Radius : Number = 0;
public function lightFactTest(): void
{
// creates a background for rectangles array.
var BG_box: Sprite = new Sprite();
BG_box.graphics.lineStyle();
BG_box.graphics.beginFill(0x080839);
BG_box.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
BG_box.graphics.endFill();
addChild(BG_box);
//# creates a grid of sprites (rectangles).
for (var i:int = 0; i < (stage.stageWidth / 10); i++)
{
for (var j:int = 0; j < (stage.stageHeight / 10); j++)
{
var box: Sprite = new Sprite();
box.graphics.lineStyle();
box.graphics.beginFill(0xFFFFFF);
box.graphics.drawRect(0, 0, 10, 10);
box.graphics.endFill();
addChild(box);
box.x += i*10; //+ 50;
box.y += j*10; //+ 50;
boxesArray.push(box);
}
}
addEventListener(Event.ENTER_FRAME, lightCalc);
}
private function lightCalc(e: Event): void
{
size_Glow = 3.5;
size_Radius = 0.64;
//# iterates through the array calculating each distance and then alpha.
for (var i:int = 0; i < boxesArray.length; i++)
{
xDist = Math.abs(stage.mouseX - boxesArray[i].x);
yDist = Math.abs(stage.mouseY - boxesArray[i].y);
//var d: Number = Math.pow(xDist * xDist + yDist * yDist, 0.5);
d = Math.sqrt(xDist * xDist + yDist * yDist) / (size_Radius / 5);
//# This is the code that you really need to focus on...
boxesArray[i].alpha = Math.min(1 / d * 10, 1 ) * (Math.PI / 0.5 - Math.min(size_Radius, 0) ) * size_Glow;
}
}
}
}
Hope that helps!

Error #1502: A script has executed for longer than the default time period of 15 seconds

this is my first time using AS3 so I apologise if the cause of this problem is painfully obvious.
I'm making chess and I've got a class for each piece on the board. When it's player 1's turn, all the black pieces should wait to be clicked, but when I implement this it returns error #1502.
package chess.sprites{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class BlackBishop extends MovieClip{
public function BlackBishop(){
trace("bb created");
}
public function waitForClick(){
this.addEventListener(MouseEvent.MOUSE_DOWN, myTurn);
}
protected function myTurn(me:MouseEvent){
trace("Clicked");
}
}
}
The function waitForClick() in BlackBishop is being called by another class like this.
public function setBlackTurn(){
for(var i:int = 0;i < 8;i++){
blackPawn[i].waitForClick();
}
for(var i:int = 0;i < 2;i++){
blackRook[i].waitForClick();
blackKnight[i].waitForClick();
blackBishop[i].waitForClick();
}
blackQueen.waitForClick();
blackKing.waitForClick();
}
I've been reading up a lot on error #1502 but it seems it only happens when I add the listener in BlackBishop. Any ideas?
Game class:
package chess{
import flash.display.MovieClip;
import chess.sprites.*;
public class Game extends MovieClip{
//Contains all sprite classes
public var blackPawn:Array = new Array(8);
public var blackRook:Array = new Array(2);
public var blackKnight:Array = new Array(2);
public var blackBishop:Array = new Array(2);
public var blackQueen:BlackQueen;
public var blackKing:BlackKing;
public var whitePawn:Array = new Array(8);
public var whiteRook:Array = new Array(2);
public var whiteKnight:Array = new Array(2);
public var whiteBishop:Array = new Array(2);
public var whiteQueen:WhiteQueen;
public var whiteKing:WhiteKing;
public var boardArray:Array = new Array(64);
//Adds sprites to stage
public function addSprites(){
var spacing:int = 46;
for(var i:int = 0;i < 8;i++){
blackPawn[i] = new BlackPawn();
blackPawn[i].x = 112 + (spacing * i); //Sets x-pos of sprite
blackPawn[i].y = 316; //Sets y-pos of sprite
addChild(blackPawn[i]); //Adds sprite to stage
whitePawn[i] = new WhitePawn();
whitePawn[i].x = 112 + (spacing * i);
whitePawn[i].y = 362 - (spacing * 6);
addChild(whitePawn[i]);
}
for(i = 0;i < 2;i++){
blackRook[i] = new BlackRook();
blackRook[i].x = 112 + (spacing * 7 * i);
blackRook[i].y = 362;
addChild(blackRook[i]);
blackKnight[i] = new BlackKnight();
blackKnight[i].x = 158 + (spacing * 5 * i);
blackKnight[i].y = 362;
addChild(blackKnight[i]);
blackBishop[i] = new BlackBishop();
blackBishop[i].x = 204 + (spacing * 3 * i);
blackBishop[i].y = 362;
addChild(blackBishop[i]);
whiteRook[i] = new WhiteRook();
whiteRook[i].x = 112 + (spacing * 7 * i);
whiteRook[i].y = 362 - (spacing * 7);
addChild(whiteRook[i]);
whiteKnight[i] = new WhiteKnight();
whiteKnight[i].x = 158 + (spacing * 5 * i);
whiteKnight[i].y = 362 - (spacing * 7);
addChild(whiteKnight[i]);
whiteBishop[i] = new WhiteBishop();
whiteBishop[i].x = 204 + (spacing * 3 * i);
whiteBishop[i].y = 362 - (spacing * 7);
addChild(whiteBishop[i]);
}
blackQueen = new BlackQueen();
blackQueen.x = 112 + (spacing * 3);
blackQueen.y = 362;
addChild(blackQueen);
blackKing = new BlackKing();
blackKing.x = 112 + (spacing * 4);
blackKing.y = 362;
addChild(blackKing);
whiteQueen = new WhiteQueen();
whiteQueen.x = 112 + (spacing * 3);
whiteQueen.y = 362 - (spacing * 7);
addChild(whiteQueen);
whiteKing = new WhiteKing();
whiteKing.x = 112 + (spacing * 4);
whiteKing.y = 362 - (spacing * 7);
addChild(whiteKing);
}
public function resetArray(){
//Reset all values in array
for (var i:int = 0; i < 64; i++) {
boardArray[i] = false;
}
//Set appropriate values in array for starting positions
for (i = 0; i < 8; i++) {
boardArray[i] = true;
boardArray[i + 8] = true;
boardArray[i + (8 * 6)] = true;
boardArray[i + (8 * 7)] = true;
}
}
//Tells all black pieces to wait to be clicked
public function setBlackTurn(){
for(var i:int = 0;i < 8;i++){
blackPawn[i].waitForClick();
}
for(i = 0;i < 2;i++){
blackRook[i].waitForClick();
blackKnight[i].waitForClick();
blackBishop[i].waitForClick();
}
blackQueen.waitForClick();
blackKing.waitForClick();
}
public function setWhiteTurn(){
for(var i:int = 0;i < 8;i++){
whitePawn[i].waitForClick();
}
for(i = 0;i < 2;i++){
whiteRook[i].waitForClick();
whiteKnight[i].waitForClick();
whiteBishop[i].waitForClick();
}
whiteQueen.waitForClick();
whiteKing.waitForClick();
}
}
}
Code in frame:
import chess.*;
var turn:int = 1;//1 is black, 2 is white
var gameRunning:Boolean = false;
var game:Game = new Game();
addChild(game);
game.addSprites();
game.resetArray();
gameRunning = true;
while(gameRunning){
if(turn == 1){
game.setBlackTurn();
}else if(turn == 2){
game.setWhiteTurn();
}else{
}
}
Your issue lies here:
gameRunning = true;
while(gameRunning){
....
}
That while loop will lock the thread until gameRunning equals false. Which likely doesn't happen within 15 seconds. (I don't think it happens ever based of the code you've shared)
You're likely used to other languages that use a game loop. In AS3, a game loop needs to be done in an enter frame handler, or a timer tick.
What is happening by the looks of the code, is that over and over and over your are toggling the turn, and you are doing so in a loop that is running as fast as it can and will lock the UI.
Take out that while loop. I don't see how you need it anyway. You want to change turns after a player moves a piece.
Here is a tip on how to architect this application:
Make a base class that every piece extends. This way you won't have to make redundant code. So make a class called ChessPiece and make it extend MovieClip (or Sprite if you pieces don't use the timeline). Then have all your pieces extend that ChessPiece class. Now they will all have whatever function and vars you've defined in the base class (ChessPiece).
When you change turns, simply lock mouse events on the pieces that belong to the other color. This could be really easy if you made two containers:
var blackContainer:Sprite = new Sprite();
addChild(blackContainer);
var whiteContainer:Sprite = new Sprite();
addChild(whiteContainer);
//then in your for loops where you create your pieces, add them to the appropriate container
blackContainer.addChild(blackPawn[i]);
//then you can do this when the turn changes to white:
blackContainer.mouseChildren = false; //now none of the pieces can dispatch mouse events / be clicked

error while converting AS2 starfield code to AS3

I've tried to convert a nice AS2 script for starfirld effect to AS3 But i'm still getting strange errors
would really appreciate if any one could help me understand what am i doing wrong
here is the original AS2 code:
var stars = 100;
var maxSpeed = 16;
var minSpeed = 2;
var i = 0;
while (i < stars)
{
var mc = this.attachMovie("star", "star" + i, i);
mc._x = random(Stage.width);
mc._y = random(Stage.height);
mc.speed = random(maxSpeed - minSpeed) + minSpeed;
var size = random(2) + 6.000000E-001 * random(4);
mc._width = size;
mc._height = size;
++i;
} // end while
this.onEnterFrame = function ()
{
for (var _loc3 = 0; _loc3 < stars; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = Stage.height;
_loc2.speed = random(maxSpeed - minSpeed) + minSpeed;
_loc2._x = random(Stage.width);
} // end of for
};
and here is my AS3 version:
import flash.events.Event;
import flash.events.MouseEvent;
function starField():void
{
var stars:int = 100;
var maxSpeed:int = 16;
var minSpeed:int = 2;
var i:int = 0;
while (i < stars)
{
var mc = new Star();
addChild(mc)
mc._x = Math.random()(stage.stageWidth);
mc._y = Math.random()(stage.stageHeight);
mc.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
var size = Math.random()(2) + 6.000000E-001 * Math.random()(4);
mc._width = size;
mc._height = size;
++i;
} // end while
}
addEventListener(Event.ENTER_FRAME, update);
function update(_e:Event):void
{
for (var _loc3 = 0; _loc3 < 100; ++_loc3)
{
var _loc2 = this["star" + _loc3];
if (_loc2._y > 0)
{
_loc2._y = _loc2._y - _loc2.speed;
continue;
} // end if
_loc2._y = stage.stageHeight;
_loc2.speed = Math.random()(maxSpeed - minSpeed) + minSpeed;
_loc2._x = Math.random()(stage.stageWidth);
} // end of for
};
the error message I'm getting is: "TypeError: Error #1010: A term is undefined and has no properties. at _fla::MainTimeline/update()"
I understand it has a problem with the 'update' function but I'm net sure which term it refer to?
I'll bet a can of juice here is your problem:
var _loc2 = this["star" + _loc3];
put these into an associative array and access them from there.
#Discipol is right.
Just wanted to add a few more notes:
You can also use the display list to get the movie clip by name:
var _loc2:MovieClip = MovieClip(getChildByName("star" + _loc3));
You've got untyped variables and your are relying on MovieClip as a dynamic class to add properties (such as speed) at runtime. For a really simple project the impact is barely noticeable, but on the long run, for bigger projects, it's worth extending Sprite if you don't use the timeline and add the properties you need:
package {
import flash.display.Sprite;
import flash.events.Event;
public class Star extends Sprite {
private var speed:Number;
private var minSpeed:Number;
private var maxSpeed:Number;
public function Star(min:Number,max:Number) {
minSpeed = min;
maxSpeed = max;
var size = (Math.random()*2) + 1.82211880039 * (Math.random()*4);
width = size;
height = size;
this.addEventListener(Event.ADDED_TO_STAGE,reset);
}
private function reset(e:Event = null):void{
speed = (Math.random() * (maxSpeed-minSpeed)) + minSpeed;
x = Math.random() * stage.stageWidth;
if(e != null) y = Math.random() * stage.stageHeight;//initialized from added to stage event
else y = stage.stageHeight;//otherwise reset while updating
}
public function update():void{
if (y > 0) y -= speed;
else reset();
}
}
}
and the rest of the code would be as simple as:
var stars:int = 100;
var starClips:Vector.<Star> = new Vector.<Star>(stars,true);//a typed fixed vector is faster than a dynamically resizable untyped Array
for(var i:int = 0 ; i < stars; i++) starClips[i] = addChild(new Star(16,2)) as Star;
this.addEventListener(Event.ENTER_FRAME,updateStars);
function updateStars(e:Event):void{
for(var i:int = 0 ; i < stars; i++) starClips[i].update();
}

Collision detection and clipping issues in AS3

I've recently started putting together a little physics simulation from scratch, something I've never tried before, and I've run into an issue regarding the interaction between the collision of the objects I have on stage, and what I think is my constant gravity. I'm not sure if 200 lines of code is too large for here, but this is what I have.
package {
import flash.events.*;
import flash.display.*;
import flash.geom.Rectangle;
[SWF (width="1500", height="1000", frameRate="24")]
public class ElasticityV2 extends MovieClip{
/* Gravity is 9.8 m/s2, which for flash, since it's being applied every frame, needs to be
divided out by the frame rate as to not have super fast acceleration. GravMulti is to balance
out gravity's speed, as it seemed a little slow after the framerate division. Resistance is acting
like friction for now, and slows down the objects in the air and on the ground at the same rate.
Elasticity is how bouncy each object is and how the force it recieves is applied*/
public var gravMulti:Number = 5;
public var gravity:Number = gravMulti *(9.8/stage.frameRate);
public var resistance:Number = 0.98;
public var elasticity:Number = 0.8;
public var floor:Number = stage.stageHeight - 100;
public var objectList:Array = new Array();
public var shadowList:Array = new Array();
public var yVelocityList:Array = new Array();
public var xVelocityList:Array = new Array();
public var massList:Array = new Array();
public var frictionList:Array = new Array();
public var lastXList:Array = new Array();
public var lastYList:Array = new Array();
public var elasticityList:Array = new Array();
public var dragList:Array = new Array();
public var spawnNum:int = 20;
public var bounding:Rectangle = new Rectangle(0,0,stage.stageWidth - 100,stage.stageHeight);
public var distantBackground:Background = new Background();
public var starLight:Light = new Light();
public function ElasticityV2() {
addChild(starLight);
starLight.x = stage.stageWidth/2;
starLight.y = -400;
starLight.addEventListener(MouseEvent.MOUSE_DOWN, onLightDrag);
starLight.addEventListener(MouseEvent.MOUSE_UP, onLightDrag);
starLight.addEventListener(MouseEvent.MOUSE_OUT, onLightDrag);
for(var s:int=0;s<spawnNum;s++){
var ballShadow:Shadow = new Shadow();
addChild(ballShadow);
setChildIndex(ballShadow,0);
ballShadow.y = floor - (ballShadow.height/2);
ballShadow.x = 100;
shadowList.push(ballShadow);
var ball:ElasticBall = new ElasticBall();
var dragging:Boolean = false;
addChild(ball);
ball.y = 100;
ball.x = s * 200;
objectList.push(ball);
yVelocityList.push(randomMe(20,-20));
xVelocityList.push(randomMe(40,-40));
massList.push(randomMe(20,5));
frictionList.push(randomMe(0.6,0.01));
objectList[s].width = objectList[s].height = massList[s] * 10;
elasticityList.push(elasticity);
dragList.push(dragging);
ball.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
ball.addEventListener(MouseEvent.MOUSE_UP, onDrag);
ball.addEventListener(MouseEvent.MOUSE_OUT, onDrag);
}
addChild(distantBackground);
distantBackground.y = stage.stageHeight - distantBackground.height;
distantBackground.width = stage.stageWidth;
setChildIndex(distantBackground,0);
addEventListener(Event.ENTER_FRAME, onGameLoop);
}
public function onGameLoop(e:Event):void{
//checkCollision();
for(var i:int=0;i<objectList.length;i++){
updatePhysics(i);
updateShadows(i,starLight);
}
}
public function updatePhysics(objRef:int):void{
if(lastXList[objRef] != undefined){
if(lastXList[objRef] != objectList[objRef].x){
xVelocityList[objRef] = objectList[objRef].x - lastXList[objRef];
}
}
if(lastYList[objRef]!= undefined){
if(lastYList[objRef] != objectList[objRef].y){
yVelocityList[objRef] = 4*(objectList[objRef].y - lastYList[objRef])/stage.frameRate;
}
}
if(objectList[objRef].y>= floor - objectList[objRef].height){
yVelocityList[objRef] = -(yVelocityList[objRef] * elasticityList[objRef]);
objectList[objRef].y = floor - objectList[objRef].height;
}
if(objectList[objRef].y<= 0){
yVelocityList[objRef] = -(yVelocityList[objRef] * elasticityList[objRef]);
objectList[objRef].y = 0;
}
if(objectList[objRef].x > (stage.stageWidth - objectList[objRef].width)){
xVelocityList[objRef]=-xVelocityList[objRef];
objectList[objRef].x = stage.stageWidth - objectList[objRef].width;
}
if (objectList[objRef].x <0){
xVelocityList[objRef]=-xVelocityList[objRef];
objectList[objRef].x = 0;
}
if(!dragList[objRef]){
yVelocityList[objRef]+=gravity;
objectList[objRef].y += yVelocityList[objRef];
xVelocityList[objRef]= (xVelocityList[objRef] * resistance);
if(-0.5<xVelocityList[objRef] && xVelocityList[objRef]<0.5){
xVelocityList[objRef] = 0;
}
objectList[objRef].x += xVelocityList[objRef];
}
lastXList[objRef] = objectList[objRef].x;
lastYList[objRef] = objectList[objRef].y;
if(xVelocityList[objRef] == 0){
xVelocityList[objRef]=randomMe(90,-90);
yVelocityList[objRef]=randomMe(90,-90);
}
}
public function onDrag(e:Event):void{
if(e.type == "mouseDown"){
setChildIndex(DisplayObjectContainer(e.target),numChildren - 1)
e.target.startDrag(false,bounding);
//xVelocityList[objRef] = yVelocityList[objRef] = 0;
//dragging = true;
}else{
e.target.stopDrag();
//dragging = false;
}
}
public function onLightDrag(e:Event):void{
if(e.type == "mouseDown"){
e.target.startDrag(false,bounding);
}else{
e.target.stopDrag();
}
}
public function updateShadows(objRef:int, lightSource:MovieClip):void{
//-----Cut for convenience------
}
public function checkCollision():void{
for(var v:int=0;v<objectList.length;v++){
var ball1 = objectList[v];
for(var w:int=v+1;w<objectList.length;w++){
var ball2 = objectList[w];
if((ball1.x + getRadius(ball1) + getRadius(ball2) > ball2.x) && (ball1.x < ball2.x + getRadius(ball1) + getRadius(ball2)) && (ball1.y + getRadius(ball1) + getRadius(ball2) > ball2.y) && (ball1.y < ball2.y + getRadius(ball1) + getRadius(ball2))){
var dx:Number = ball2.x - ball1.x;
var dy:Number = ball2.y - ball1.y;
var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
if(dist < getRadius(ball1)+getRadius(ball2)){
var newX1:Number;
var newY1:Number;
var newX2:Number;
var newY2:Number;
trace("Magnitude 1 is : " + (Math.sqrt((xVelocityList[v] * xVelocityList[v]) + (yVelocityList[v] * yVelocityList[v]))));
trace("Magnitude 2 is : " + (Math.sqrt((xVelocityList[w] * xVelocityList[w]) + (yVelocityList[w] * yVelocityList[w]))));
newX1 = ((massList[v] * xVelocityList[v])+(massList[w] * xVelocityList[w]))/(massList[v] + massList[w]) * 2 - xVelocityList[v];
newY1 = ((massList[v] * yVelocityList[v])+(massList[w] * yVelocityList[w]))/(massList[v] + massList[w]) * 2 - yVelocityList[v];
newX2 = ((massList[v] * xVelocityList[v])+(massList[w] * xVelocityList[w]))/(massList[v] + massList[w]) * 2 - xVelocityList[w];
newY2 = ((massList[v] * yVelocityList[v])+(massList[w] * yVelocityList[w]))/(massList[v] + massList[w]) * 2 - yVelocityList[w];
xVelocityList[v] = newX1;
yVelocityList[v] = newY1;
xVelocityList[w] = newX2;
yVelocityList[w] = newY2;
ball1.x += newX1;
ball1.y += newY1;
ball2.x += newX2;
ball2.y += newY2;
}
}
}
}
}
public function randomMe(high:Number, low:Number = 0):Number{
return Math.random() * (high - low) + low;
}
public function getRadius(obj:MovieClip):Number{
return obj.width/2;
}
public function centerX(obj:MovieClip):Number{
return obj.x + getRadius(obj);
}
public function centerY(obj:MovieClip):Number{
return obj.y + getRadius(obj);
}
}
}
It's a very simple system to check for collision, just comparing the radius of the objects, and midair collisions seem fine, but if one ball lands on top of another that has no x or y velocity, it just sinks into it. Any ideas as to why?
I expect your balls behave like this: When one ball lands on top of the other, that's actually lying on the ground, the other ball gets pushed down into the ground, then you react at it within updatePhysics() by placing it into the position where it originated, thus, those balls become one within another. One of the suggestions that could remedy this will be to hold last collided object for each of the balls for one cycle of physics, say like this:
if(dist < getRadius(ball1)+getRadius(ball2)){
// process collision
ball1.lastCollided=ball2;
ball2.lastCollided=ball1;
}
Then, when you update your coordinates in updatePhysics(), check if lastCollided is null, if not, update that ball's coordinates and speed the same way, essentially simulating another collision. After checking for all the events within update physics cycle, assign null to lastCollided of all balls.

Detect when the Shader is done mixing the audio

so this the code with it i am able to mix several tracks
with a Shader done in pixel bender.
the problem here i don't know when the mixing is finish or all the sound reache their end
to be able to save the bytearray into a file any Event or something like that
help plz ?
package
{
import flash.display.*;
import flash.media.*;
import flash.events.*;
import flash.net.*;
import flash.utils.*;
import fl.controls.Slider;
import org.bytearray.micrecorder.encoder.WaveEncoder;
[SWF(width='500', height='380', frameRate='24')]
public class AudioMixer extends Sprite{
[Embed(source = "sound2.mp3")] private var Track1:Class;
[Embed(source = "sound1.mp3")] private var Track2:Class;
[Embed(source = "mix.pbj",mimeType = "application/octet-stream")]
private var EmbedShader:Class;
private var shader:Shader = new Shader(new EmbedShader());
private var sound:Vector.<Sound> = new Vector.<Sound>();
private var bytes:Vector.<ByteArray> = new Vector.<ByteArray>();
private var sliders:Vector.<Slider> = new Vector.<Slider>();
private var graph:Vector.<Shape> = new Vector.<Shape>();
private var recBA:ByteArray = new ByteArray();
private var BUFFER_SIZE:int = 0x800;
public var playback:Sound = new Sound();
public var container:Sprite = new Sprite();
public var isEvent:Boolean = false;
public function AudioMixer():void{
container.y = stage.stageHeight * .5;
addChild(container);
sound.push(new Track1(), new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2(),new Track2());
for(var i:int = 0; i < sound.length; i++){
var slider:Slider = new Slider();
slider.maximum = 1;
slider.minimum = 0;
slider.snapInterval = 0.025;
slider.value = 0.8;
slider.rotation += -90;
slider.x = i * 40 + 25;
container.addChild(slider);
sliders.push(slider);
var line:Shape = new Shape();
line.graphics.lineStyle(1, 0x888888);
line.graphics.drawRect(i * 40 + 14, 0, 5, -80);
line.graphics.endFill();
container.addChild(line);
var shape:Shape = new Shape();
shape.graphics.beginFill(0x00cc00);
shape.graphics.drawRect(i * 40 + 15, 0, 3, -80);
shape.graphics.endFill();
container.addChild(shape);
graph.push(shape);
}
playback.addEventListener(SampleDataEvent.SAMPLE_DATA, onSoundData);
playback.play();
}
private function onSoundData(event:SampleDataEvent):void {
for(var i:int = 0; i < sound.length; i++){
bytes[i] = new ByteArray();
bytes[i].length = BUFFER_SIZE * 4 * 2;
sound[i].extract(bytes[i], BUFFER_SIZE);
var volume:Number = 0;
bytes[i].position = 0;
for(var j:int = 0; j < BUFFER_SIZE; j++){
volume += Math.abs(bytes[i].readFloat());
volume += Math.abs(bytes[i].readFloat());
}
volume = (volume / (BUFFER_SIZE * .5)) * sliders[i].value;
shader.data['track' + (i + 1)].width = BUFFER_SIZE / 1024;
shader.data['track' + (i + 1)].height = 512;
shader.data['track' + (i + 1)].input = bytes[i];
shader.data['vol' + (i + 1)].value = [sliders[i].value];
graph[i].scaleY = volume;
}
var shaderJob:ShaderJob = new ShaderJob(shader,event.data,BUFFER_SIZE / 1024,512);
shaderJob.start(true);
var shaderJob2:ShaderJob = new ShaderJob(shader,recBA,BUFFER_SIZE / 1024,512);
shaderJob2.start(true);
}
}
}
You can tell when a shader has completed it's job using the ShaderEvent.COMPLETE listener. Like so:
shaderJob.addEventListener(ShaderEvent.COMPLETE, onShaderComplete);
private function onShaderComplete(e:Event):void
{
//Do Something here
}
See this link for more details.
One thing about your code though. You're doing this shader job inside of a sampleDataEvent and I can see this being problematic (possibly) in the sense that your mixing may be out of sync with your playback (that is, if you plan on mixing live and writing the mixed data back into the sound stream). Anyway that's perhaps an issue for a new question. This should solve your problem with needing to know when the mixing is complete.
Note you also need to add "false" to the shaderJob.start(false) function. From the documentation about the ShaderEvent.COMPLETE:
"Dispatched when a ShaderJob that executes asynchronously finishes processing the data using the shader. A ShaderJob instance executes asynchronously when the start() method is called with a false value for the waitForCompletion parameter."
Update
In response to your inquiry about how to only process inside the sampleDataEvent if the sound isnt being processed:
private var isProcessing:Boolean = false;
private function onSoundData(event:SampleDataEvent):void {
if(isProcessing != true){
for(var i:int = 0; i < sound.length; i++){
bytes[i] = new ByteArray();
bytes[i].length = BUFFER_SIZE * 4 * 2;
sound[i].extract(bytes[i], BUFFER_SIZE);
var volume:Number = 0;
bytes[i].position = 0;
for(var j:int = 0; j < BUFFER_SIZE; j++){
volume += Math.abs(bytes[i].readFloat());
volume += Math.abs(bytes[i].readFloat());
}
volume = (volume / (BUFFER_SIZE * .5)) * sliders[i].value;
shader.data['track' + (i + 1)].width = BUFFER_SIZE / 1024;
shader.data['track' + (i + 1)].height = 512;
shader.data['track' + (i + 1)].input = bytes[i];
shader.data['vol' + (i + 1)].value = [sliders[i].value];
graph[i].scaleY = volume;
}
var shaderJob:ShaderJob = new ShaderJob(shader,event.data,BUFFER_SIZE / 1024,512);
shaderJob.start(false);
shaderJob.addEventListener(ShaderEvent.COMPLETE, onShaderComplete);
var shaderJob2:ShaderJob = new ShaderJob(shader,recBA,BUFFER_SIZE / 1024,512);
shaderJob2.start(false);
}
}
private function onShaderComplete(e:ShaderEvent):void
{
//Do something here
isProcessing = false;
}