I would like to set a displacement between the circles that are drawn here. Besides, I would like to copy the circles positions to the head circle, but the offset of course is cleared due to that.
public var circles:Vector.<circle> = new Vector.<circle>(5);
public function t()
{
var offset:int = 10;
for ( var i:int = 0; i<5; i++)
{
var c:circle = new circle();
c.xPosition= 120+offset;
c.yPosition = 120;
c.vx = 1;
c.vy = 0;
circles[i] = c;
offset+=40;
}
addEventListener(Event.ENTER_FRAME, gameLoop);
}
public function gameLoop(event:Event):void
{
for ( var i:int = 0; i<5; i++)
{
addChild(circles[i]);
circles[i].drawCircle(circles[i].xPosition, circles[i].yPosition);
}
for ( var i:int = 0; i<5; i++)
{
if ( i != 0 )
{
circles[i].xPosition = circles[i-1].xPosition;
circles[i].yPosition = circles[i-1].yPosition;
}
else {
}
}
circles[0].xPosition-=circles[0].vx*(2*5);
circles[0].yPosition-=circles[0].vy*(2*5);
}
Do the loop from back to front. What you did change every circle's position same with circle 0
for ( var i:int = 4; i > 0; i--)
{
circles[i].xPosition = circles[i-1].xPosition;
circles[i].yPosition = circles[i-1].yPosition;
}
Related
I'm currently working on a game with AS3, wherein the player needs to avoid falling random objects by tilting the phone. These objects uses timer for delay to make them fall one time per row. So I'm working now on the level where there are two objects falling randomly on the screen, which are movieclips "mercury" with class name of planet1 and "venus" with class name of "planet2". The problem is, sometimes they overlapped with each other when falling. I want the two movieclips to not overlap with each other when they start to fall. I had look for scripts and tried it but it doesn't work. I'm beginner in AS3.
Here is the script:
var mercury:planet1;
var mercuryArray:Array = new Array();
var mercuryClock = new Timer(5000, 0);
mercuryClock.addEventListener(TimerEvent.TIMER, spawnMercury);
var venus:planet2;
var venusArray:Array = new Array();
var venusClock = new Timer(2000, 0);
venusClock.addEventListener(TimerEvent.TIMER, spawnVenus);
addEventListener(Event.ENTER_FRAME, onMyEnterFrame);
function onMyEnterFrame(e:Event)
{
galawMercury();
galawVenus();
checkCollision();
}
/*==================PLANET 1=====================*/
function spawnMercury(e:Event)
{
gawaMercury();
}
function gawaMercury()
{
var mercury:planet1 = new planet1();
mercury.x = Math.random() * 400;
mercury.y = 0;
addChild(mercury);
mercuryArray.push(mercury);
}
function galawMercury()
{
for(var ee:int = mercuryArray.length - 1; ee >= 0; ee--)
{
mercuryArray[ee].y += 13;
if(mercuryArray[ee].y > stage.stageHeight)
{
mercuryArray[ee].parent.removeChild(mercuryArray[ee]);
mercuryArray.splice(ee, 1);
}
}
}
/*==================PLANET 2=====================*/
function spawnVenus(e:Event)
{
gawaVenus();
}
function gawaVenus()
{
var venus:planet2 = new planet2();
venus.x = Math.random() * 400;
venus.y = 0;
venus.width = 126;
venus.height = 200;
addChild(venus);
venusArray.push(venus);
}
function galawVenus()
{
for(var yy:int = venusArray.length - 1; yy >= 0; yy--)
{
venusArray[yy].y += 12;
if(venusArray[yy].y > stage.stageHeight)
{
venusArray[yy].parent.removeChild(venusArray[yy]);
venusArray.splice(yy, 1);
}
}
}
function checkCollision()
{
for(var oo:int = mercuryArray.length - 1; oo >= 0; oo --)
{
if(stella.hitStella.hitTestObject(mercuryArray[oo]))
{
keme();
}
}
for(var uu:int = venusArray.length - 1; uu >= 0; uu --)
{
if(stella.hitStella.hitTestObject(venusArray[uu]))
{
keme();
}
}
}
function keme()
{
soundtrackChannel.stop();
soundtrackChannel = stellaDead.play();
removeEventListener(Event.ENTER_FRAME, onMyEnterFrame);
mercuryClock.stop();
venusClock.stop();
score.stop();
stella.play();
blah.text = lbl_iskor.text;
removeObjects();
}
function removeObjects()
{
for each (var mercury:planet1 in mercuryArray)
{
mercuryArray.splice(mercury, 0);
removeChild(mercury);
}
for each (var venus:planet2 in venusArray)
{
venusArray.splice(venus, 0);
removeChild(venus);
}
}
The problem is when i have 2 or more balls on stage,some balls are bouncing perfect and some other are sink in floors.
The floors on stage are already on stage.
Is that a drawing problem or its something else?
stop();
//ARRAYS
var ballArray:Array = new Array();
//ADD BALLS
var mediumBall1f2:Ball = new Ball ;
ballArray.push(mediumBall1f2);
this.addChild(mediumBall1f2);
mediumBall1f2.ballX = 3;
mediumBall1f2.ballY = 8;
mediumBall1f2.x = 300;
mediumBall1f2.y = 250;
mediumBall1f2.width = 120;
mediumBall1f2.height = 120;
var mediumBall1f3:Ball = new Ball ;
ballArray.push(mediumBall1f3);
this.addChild(mediumBall1f3);
mediumBall1f3.ballX = -3;
mediumBall1f3.ballY = 8;
mediumBall1f3.x = 200;
mediumBall1f3.y = 350;
mediumBall1f3.width = 140;
mediumBall1f3.height = 140;
var mediumBall1f4:Ball = new Ball ;
ballArray.push(mediumBall1f4);
this.addChild(mediumBall1f4);
mediumBall1f4.ballX = -3;
mediumBall1f4.ballY = 8;
mediumBall1f4.x = 300;
mediumBall1f4.y = 250;
mediumBall1f4.width = 50;
mediumBall1f4.height = 50;
var mediumBall1f5:Ball = new Ball ;
ballArray.push(mediumBall1f5);
this.addChild(mediumBall1f5);
mediumBall1f5.ballX = -3;
mediumBall1f5.ballY = 8;
mediumBall1f5.x = 400;
mediumBall1f5.y = 350;
mediumBall1f5.width = 80;
mediumBall1f5.height = 80;
var mediumBall1f6:Ball = new Ball ;
ballArray.push(mediumBall1f6);
this.addChild(mediumBall1f6);
mediumBall1f6.ballX = 3;
mediumBall1f6.ballY = 8;
mediumBall1f6.x = 400;
mediumBall1f6.y = 320;
mediumBall1f6.width = 30;
mediumBall1f6.height = 30;
var mediumBall1f7:Ball = new Ball ;
ballArray.push(mediumBall1f7);
this.addChild(mediumBall1f7);
mediumBall1f7.ballX = 3;
mediumBall1f7.ballY = 8;
mediumBall1f7.x = 400;
mediumBall1f7.y = 230;
var mediumBall1f8:Ball = new Ball ;
ballArray.push(mediumBall1f8);
this.addChild(mediumBall1f8);
mediumBall1f8.ballX = 3;
mediumBall1f8.ballY = 8;
mediumBall1f8.x = 400;
mediumBall1f8.y = 240;
var mediumBall1f9:Ball = new Ball ;
ballArray.push(mediumBall1f9);
this.addChild(mediumBall1f9);
mediumBall1f9.ballX = 3;
mediumBall1f9.ballY = 8;
mediumBall1f9.x = 400;
mediumBall1f9.y = 110;
//FLOOR
var downArray:Array = new Array();
for (var dA:int = numChildren - 1; dA>= 0; dA--)
{
var childdA:DisplayObject = getChildAt(dA);
if (childdA.name == "downfloor")
{
downArray.push(MovieClip(childdA));
}
}
var upArray:Array = new Array();
for (var uA:int = numChildren - 1; uA>= 0; uA--)
{
var childuA:DisplayObject = getChildAt(uA);
if (childuA.name == "upfloor")
{
upArray.push(MovieClip(childuA));
}
}
var rightArray:Array = new Array();
for (var rA:int = numChildren - 1; rA>= 0; rA--)
{
var childrA:DisplayObject = getChildAt(rA);
if (childrA.name == "rightfloor")
{
rightArray.push(MovieClip(childrA));
}
}
var leftArray:Array = new Array();
for (var lA:int = numChildren - 1; lA>= 0; lA--)
{
var childlA:DisplayObject = getChildAt(lA);
if (childlA.name == "leftfloor")
{
leftArray.push(MovieClip(childlA));
}
}
//USE ONCE
stageclear.visible = false;
stageclear.gotoAndStop(1);
stage.addEventListener(Event.ENTER_FRAME,ballLoop);
function ballLoop(evt:Event)
{
//BALL
for (var j = 0; j<ballArray.length; j++)
{
var ball:Ball = ballArray[j] as Ball;
ball.ballY--;
ball.y -= ball.ballY;
ball.x -= ball.ballX;
if (player.hitTestObject(ball))
{
ball.y = 600;
}
if(ball.x - ball.width/2 < 0)
{
ball.ballX = -3;
}
if(ball.x + ball.width/2 > 800)
{
ball.ballX = 3;
}
if(ball.y + ball.height/2 > 384.45)
{
ball.ballY = 20;
}
if(ball.y - ball.height/2 < 0)
{
ball.ballY = -2;
}
for (var d = 0; d<downArray.length; d++)
{
var down:DownFloor = downArray[d] as DownFloor;
if (ball.hitTestObject(down))
{
ball.ballY = 20;
}
}
for (var r = 0; r<rightArray.length; r++)
{
var right:RightFloor = rightArray[r] as RightFloor;
if (ball.hitTestObject(right))
{
ball.ballX = 3;
}
}
for (var l = 0; l<leftArray.length; l++)
{
var left:LeftFloor = leftArray[l] as LeftFloor;
if (ball.hitTestObject(left))
{
ball.ballX = -3;
}
}
for (var u = 0; u<upArray.length; u++)
{
var up:UpFloor = upArray[u] as UpFloor;
if (ball.hitTestObject(up))
{
ball.ballY = -2;
}
}
if (ball.y >= 600)
{
ball.parent.removeChild(ball);
ballArray.splice(j,1);
}
if (ballArray.length <= 0)
{
stageclear.visible = true;
stageclear.gotoAndPlay(1);
}
}
if(stageclear.currentFrame == stageclear.totalFrames)
{
stage.removeEventListener(Event.ENTER_FRAME,ballLoop);
MovieClip(this.root).gotoAndPlay(1, "Scene 2");
}
}
the reason this is happening
This is happening because hitTest is only true if the MCs overlap. If you could look more closely, you'd see that this happens to all of the balls (it's just more apparent with some than others).
the only fix that I know of
Make your own collision detection.
It could look like this:
function collisionTest (mc1:MovieClip,mc2:MovieClip){
// test if mc1 is going to hit mc2's left side *on the next frame*
if (mc1.x + mc1._xSpeed + mc1.width>= mc2.x){
mc1.x = mc2.x; // this may cause a momentary pause... The ball may seem to stick to the wall for a frame... If this is a problem let me know and I'll show you how to fix that
mc1._xSpeed *= -1;
}
// test if mc1 is going to hit top edge of mc2 *on the next frame*
if (mc1.y + mc1._ySpeed + mc1.height >= mc2.y){
mc1.y = mc2.y; // same possible sticking here
mc1._ySpeed *= -1;
}
}
note
For this to work, the registration point for the MCs should be top-left (which is the default).
Also, my code only works for object 1 moving down, colliding with the top of object2 or object 1 moving right colliding with left side of object 2.
_xSpeed and _ySpeed are things you will need to add as properties to your ball class and use that property to dictate motion of the balls. This is the key: it allows you to look ahead, into the future, and see if the ball is going to hit the wall on the next frame, and if it is, run the result of collision now, instead of after they overlap.
You'll need to add similar code for if the ball is moving left and you want it to detect collision with the right edge of a wall. Also for if the ball is moving up and you want to detect collision with the bottom of a wall
Don't forget to include an adjustment for the width of the wall or the width of the ball (since we are using the registration point which is top left of the bounding box)
if I add the else statement I do receive the "not hit" in my output window, so it looks like the statement only returns true on the first few frames, when it is supposed to return false. Now my problem is that the code wants to remove child objects before they've even been created. I just want to achieve basic collision detection between the enemy and the bullet so that i can remove both children when an enemy is shot. Please keep in mind that there will be multiple enemies and bullets on the stage at a given time.
I seemed to narrow down my problem. What was happening was the instance of an enemy would still exist, after i used the removeChild() function. Only now I couldn't see it for some reason. And its x and y properties were equal to 0. Therefore if I moved the ship to x = 0, it would have an "invisible" enemy collide with it. So I think my problem is I am not removing the instance properly? if not could you please help me?
` <pre>
var BulletsArr:Array = new Array();
var EnemysArray:Array = new Array();
for(i = 0; i < 5; i++)
{
BulletsArr[i] = new Bullet();
}
for(i = 0; i < 5; i++)
{
EnemysArray[i] = new Enemy();
//EnemysArray[i].x = 2000; //Fix
//EnemysArray[i].y = 2000; //Fix
}
stage.addChild(Ship);
Ship.addEventListener(Event.ENTER_FRAME, fnEnterFrame);
function fnEnterFrame(event:Event)
{
txtScore.text = "Score: " + score;
//Make Ship follow cursor
Ship.x = stage.mouseX;
//Boundries
if (Ship.x > 500)
{
Ship.x = 550 - 50;
}
if (Ship.x <= 0)
{
Ship.x = 0 ;
}
for(var i = 0; i < 5; i++){
for(var p = 0; p < 5; p++)
{
if(BulletsArr[i].hitTestObject(EnemysArray[p]))
{
remove(BulletsArr[i]);
removeChild(EnemysArray[p]);
}
for(i = 0; i < 5; i++)
{
BulletsArr[i].y -= 15;
}
for(i = 0; i < 5; i++)
{
EnemysArray[i].y += 5;
}
for(var z = 0; z < 5; z++)
{
if(Ship.hitTestObject(EnemysArray[z])
{
Ship.parent.removeChild(Ship);
EnemysArray[z].parent.removeChild(EnemysArray[z]);
trace("Game over");
}
}
for(i = 0; i < 5; i++)
{
var found:Boolean = false;
for(var p = 0; p < 5; p++)
{
if(BulletsArr[i].hitTestObject(EnemysArray[p]))
{
BulletsArr[i].parent.removeChild(BulletsArr[i]);
BulletsArr[i] = new Bullet();
EnemysArray[p].parent.removeChild(EnemysArray[p]);
EnemysArray[p] = new Enemy();
//EnemysArray[p].x = 2000;//fix
//EnemysArray[p].y = 2000;//fix
score += 50;
found = true;
break;
}
if(found)
{
break;
}
}
}
}
var count_Enemys:int = 0;
var Timer_3_sec:Timer = new Timer(3000, 0);
Timer_3_sec.start();
Timer_3_sec.addEventListener(TimerEvent.TIMER,spawn_ship);
function spawn_ship(Event:TimerEvent):void
{
if(count_Enemys >= 5)
{
count_Enemys = 0;
EnemysArray[count_Enemys].x = fl_GenerateRandomNumber(450) + 70;
EnemysArray[count_Enemys].y = 0 - fl_GenerateRandomNumber(250) - 100;
addChild(EnemysArray[count_Enemys]);
count_Enemys++;
}
else
{
EnemysArray[count_Enemys].x = fl_GenerateRandomNumber(450) + 70;
EnemysArray[count_Enemys].y = 0 - fl_GenerateRandomNumber(250) - 100;
addChild(EnemysArray[count_Enemys]);
count_Enemys++;
}
}
`</code>
I am trying to make a graphic program that solves the 8 queens problem and so far what i have is the chess board
var chessBoard:Array = new Array();
for(var i:int = 0; i < 4; i++)
{
chessBoard.push(new Array(1,0,1,0,1,0,1,0));
chessBoard.push(new Array(0,1,0,1,0,1,0,1));
}
var tileSize:int = 20;
function createChessBoard():void
{
for(var i:int = 0; i < chessBoard.length; i++)
{
for(var j:int = 0; j < chessBoard[i].length; j++)
{
var tile:Sprite = new Sprite();
var tileColor:int = chessBoard[i][j] * 0xffffff;
tile.graphics.beginFill(tileColor);
tile.graphics.drawRect(0, 0, tileSize, tileSize);
tile.graphics.endFill();
tile.x = j * tileSize;
tile.y = i * tileSize;
addChild(tile);
}
}
}
createChessBoard();
(thanks André for this code)
this creates a black and white checkered board for the problem but now i need to be able to place the queens. How am i able to see where the user clicks in order to put the queen in the box that is clicked on?
(sorry if my question isn't fully clear)
I added a very simple example to your question. See below:
var chessBoard:Array = new Array();
for(var i:int = 0; i < 4; i++)
{
chessBoard.push(new Array(1,0,1,0,1,0,1,0));
chessBoard.push(new Array(0,1,0,1,0,1,0,1));
}
var tileSize:int = 20;
function createChessBoard():void
{
for(var i:int = 0; i < chessBoard.length; i++)
{
for(var j:int = 0; j < chessBoard[i].length; j++)
{
var tile:Sprite = new Sprite();
var tileColor:int = chessBoard[i][j] * 0xffffff;
tile.graphics.beginFill(tileColor);
tile.graphics.drawRect(0, 0, tileSize, tileSize);
tile.graphics.endFill();
//I added the name property and a MouseEvent.CLICK event listener
tile.name = "tile__" + i + "_" j + "_sp";
tile.addEventListener(MouseEvent.CLICK, onTileClick);
tile.x = j * tileSize;
tile.y = i * tileSize;
addChild(tile);
}
}
}
function onTileClick(event:MouseEvent):void
{
//This tells you which tile the user clicked on
trace(event.target.name);
};
createChessBoard();
Good luck,
Rob
How do you loop through all the childs in a DisplayObjectContainer in as3? I would like a syntax like this:
for each(var displayObject:DisplayObject in displayObjectContainer )
{
displayObject.x += 10;
displayObject.y += 10;
}
Not sure if for each works, but this works.
for (var i:int = 0; i<myObj.numChildren; i++)
{
trace(myObj.getChildAt(i));
}
something like this maybe?
function getChildren(target:DisplayObjectContainer):Array {
var count:uint = target.numChildren;
var ret:Array = [];
for (var i:int = 0; i < count; i++)
ret.push(target.getChildAt(0));
return ret;
}
and then
for each (var child:Array in getChildren(displayObjectContainer)) {
//....
}
greetz
back2dos
You can use following recursive function to iterate through all children of any DisplayObjectContainer class.
function getChildren(dsObject:DisplayObjectContainer, iDepth:int = 0):void
{
var i:int = 0;
var sDummyTabs:String = "";
var dsoChild:DisplayObject;
for (i ; i < iDepth ; i++)
sDummyTabs += "\t";
trace(sDummyTabs + dsObject);
for (i = 0; i < dsObject.numChildren ; ++i)
{
dsoChild = dsObject.getChildAt(i);
if (dsoChild is DisplayObjectContainer && 0 < DisplayObjectContainer(dsoChild).numChildren)
getChildren(dsoChild as DisplayObjectContainer,++iDepth);
else
trace(sDummyTabs + "\t" + dsoChild);
}
}
It will display all children in hierarchical manner exactly as DisplayList tree.
My two cents.
public static function traceDisplayList(displayObject:DisplayObject, maxDepth:int = 100, skipClass:Class = null, levelSpace:String = " ", currentDepth:int = 0):void
{
if (skipClass != null) if (displayObject is skipClass) return;
trace(levelSpace + displayObject.name); // or any function that clean instance name
if (displayObject is DisplayObjectContainer && currentDepth < maxDepth)
{
for (var i:int = 0; i < DisplayObjectContainer(displayObject).numChildren; i++)
{
traceDisplayList(DisplayObjectContainer(displayObject).getChildAt(i), maxDepth, skipClass, levelSpace + " ", currentDepth + 1);
}
}
}