How to removechild in as3? - actionscript-3

this is my code:
var star:Sprite = new Sprite();
for (var i:Number = 0; i<50; ++i) //check if sky contains star , remove them
{
if (sky.contains(star)) //this "if" didnt work!
{
sky.removeChild(star);
}
}
for (i= 0; i<50; ++i) //add new stars to sky
{
star = new Sprite();
star.graphics.beginFill(0xFFFFFF);
star.graphics.drawCircle(0, 0, ((Math.random() * 1.5) + 0.25));
star.x = Math.random() * stage.stageWidth ;
star.y = Math.random() * stage.stageHeight;
sky.addChild(star);
}
the 1st "if" didnt work and in 2nd "for" stars add to sky over previous stars! what is the correct code to remove previous stars?thanks

Use this remove stars from the sky. It will remove all objects from sky.
for (var i:Number = 0; i < sky.numchildren; ++i)
{
sky.removeChildAt(i);
}
If you want to remove only stars from the sky , declare a new class for star
for (var i:Number = 0; i<sky.numchildren; ++i)
{
if(sky.getChildAt(i) is Star){
sky.removeChildAt(i);
}
}

As #DodgerThud said in his comment, it's better to use an array to store your stars for this portion of your code and may be for others operations you will do / need in next steps, so you can do like this :
var star:Sprite,
stars:Array = [], // array to store our stars
i:int;
for (i = 0; i < stars.length; i++)
{
Sprite(stars[i]).parent.removeChild(stars[i]);
}
stars = [];
for (i = 0; i < 50; i++)
{
star = new Sprite();
star.graphics.beginFill(0xFF00FF);
star.graphics.drawCircle(0, 0, ((Math.random() * 1.5) + 0.25));
star.x = Math.random() * stage.stageWidth ;
star.y = Math.random() * stage.stageHeight;
stars.push(star); // store your star into the stars array
sky.addChild(star);
}
Hope that can help.

you should use while loop instead of if here.
// that removes all the childs
while(sky.numChildren > 0){
sky.removeChildAt(0);
}
// if you want to keep just 1 clip
while(sky.numChildren > 1){
sky.removeChildAt(0);
}

Assuming you are going to remove all stars from the sky and:
Sky is also a sprite or subclass of sprite
Your sky only contains stars and nothing else
You want to clear all stars from the sky and then add them back.
Hope this helps.
var stars:Array = new Array();
for(var i:int=0; i<sky.numChildren; ++i)
{
sky.removeChild(sky.getChildAt(i));
}
if(stars.length == 0) //create stars if not created before
{
for (i= 0; i<50; ++i)
{
var star:Sprite = new Sprite();
star.graphics.beginFill(0xFFFFFF);
star.graphics.drawCircle(0, 0, ((Math.random() * 1.5) + 0.25));
star.x = Math.random() * stage.stageWidth ;
star.y = Math.random() * stage.stageHeight;
stars.push(star);
}
}
//add all stars created to sky
for each(var _star:Sprite in stars)
{
sky.addChild(_star);
}

Related

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 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!

how to call objects created in a loop?

Newbie question:
If I create several shape objects in a loop, like:
var i:int;
for (i = 0; i < 3; i++) {
var circle:Shape = new Shape();
circle.graphics.beginFill(color);
circle.graphics.drawCircle(100,100, radius);
circle.graphics.endFill();
addChild(circle);
}
How can I then call those different shapes separately, so I could manipulate their properties? It would seem to me they would all have the same name?
You can access them via their index (the order they have been put on the stage).
So something like:
DisplayObject(getChildAt(1)).x = 100; // Where the 1 is the index (starting at 0)
Actually, you can just have an array (or vector) of objects, so you won't depend on current displaylist.
var i:int;
var circleArray:Array = new Array();
for (i = 0; i < 3; i++) {
var circle:Shape = new Shape();
circleArrayList.push(circle);
circle.graphics.beginFill(color);
circle.graphics.drawCircle(100,100, radius);
circle.graphics.endFill();
addChild(circle);
}
//And then access them with
for(i = 0; i < circleArray.length, i++)
{
circleArrayList[i].x = 15 * i;
}
//Or
foreach(var circle:DisplayObject in circleArray)
{
circle.x = 15 * i;
}
for(int i=0;i<3;i++)
{
class x =new class(i);
x.print()
}

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/

getting array coordinates (8 queens problem)

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