In Actionscript 3, how do I create movieclips through a looping statement? - actionscript-3

The statement for takes a triple as an argument
(initial value of i, condition to cease looping, i increment)
I want to create a different movie clip each time the loop goes on.
So, I tried:
for (i = 0; i < 9; i++){
var Unit+i:MovieClip = new MovieClip()
}
But, this triggers the following error:
1086: Syntax error: expecting semicolon before plus"
What's the correct syntax, then?

To address the issue. You cannot create a var dynamically by using the var keyword. So doing var Unit+i will give you a syntax error.
You can create an array ahead of time and put your objects in that (as per #Panzercrisis's answer which is perfectly acceptable).
Other ways you can do this:
If you current context is dynamic (like if this is timeline code or part of a dynamic class like MovieClip), you do something like this:
this["Unit"+i] = new MovieClip();
From a compile time checking and code maintenance perspective, this is a little sloppy in my opinion, but for quick timeline projects it's certainly acceptable.
You could also just not store the clip anywhere but the display list:
for(var i:int=0;i<9;i++){
var mc:MovieClip = new MovieClip();
//do whatever you need to do to the clip
//like draw something for instance
mc.graphics.beginFill(0xFF0000);
mc.graphics.drawRect(0,0,100,100);
addChild(mc); //add to the display list so you can see it
}
If you never need to remove this clip, this way is great.
Or, you could add them to a container display object
var clipContainer:Sprite = new Sprite(); //Sprite is the same as movie clip but without the timeline stuff
addChild(clipContainer);
for(var i:int=0;i<9;i++){
var mc:MovieClip = new MovieClip();
//do whatever you need to do to the clip
//like draw something for instance
mc.graphics.beginFill(0xFF0000);
mc.graphics.drawRect(0,0,100,100);
clipContainer.addChild(mc);
}
The clipContainer would then act the same as an array, where you can access all it's children. Also, moving/scalling the container would in turn move/scale all it's children

Basically this is what you want to do:
var arrMovieClips:Array = new Array(9);
for (var i:int = 0; i < arrMovieClips.length; i++)
{
arrMovieClips[i] = new MovieClip();
}
This will create an array with nine elements, so you essentially have nine variables in a row:
arrMovieClips[0]
arrMovieClips[1]
arrMovieClips[2]
...
arrMovieClips[8]
Then it will go through and loop 0, 1, 2, etc. When it gets to the length of arrMovieClips, which is 9, then it'll stop. As it goes through 0-8, it'll create a new MovieClip and store it in each spot.

Related

How to display player lives in game AS3

Hey everyone so having a little trouble trying to accomplish this. I understand how to add lives and display them through a Dynamic Text Field on the stage. My game is set up right now to where this happens and whenever the player dies a live decrements so it works fine.
But I want to display and Image of all 3 lives a custom Movie Clip that I drew in Flash CS6 to represent the lives. So All 3 lives will be displayed in the game and once the player dies one of the lives images is removed.
I have some idea on what to do. For instance I created a "for loop" to display all 3 images on the screen and created variables to place them horizontally next to each other with a space of 30 pixels.
But I'm not sure if this is the correct way to approach this. Also kind of confused on how I would remove one of the images when the player dies?
Her is my code so far:
public var playerLives:mcPlayerLives;
private var nLives:Number = 3;
private var startPoint:Point;
private var aPlayerLivesArray:Array;
In my main class Engine:
aPlayerLivesArray = new Array;
addPlayerLivesToStage();
Then the addplayerlivestostage function:
public function addPlayerLivesToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) - 300, (stage.stageHeight / 2) - 200);
var xSpacing:Number = 30;
for (var i = 0; i < nLives; i++)
{
trace(aPlayerLivesArray.length);
playerLives = new mcPlayerLives();
stage.addChild(playerLives);
playerLives.x = startPoint.x + (xSpacing * i);
playerLives.y = startPoint.y;
aPlayerLivesArray.push(playerLives);
}
}
So like i stated above everything works fine and it does display the 3 images that represent the lives, but would this be the correct approach or is there an easier method?
i think you're using right way to add lives.
and for removing them, you don't need to remove all and add new lives, you can remove the last element of lives array, so, it's done, i think thats already an easy method
so, you can implement this
for (var i = 0; i < nLives; i++)
to make a better usage for "adding lives in-game (earning lives)"
something like
for (var i = aPlayerLivesArray.length; i < nLives; i++)
but don't forget to decrease array length by 1 after removing last element of livesArray when player dies
Looks pretty close to a reasonable approach. I would have a blank container movieclip on stage where you want the lives icons to display. Create one life icon in your library and link it for export with actionscript. When you generate your game view, you can populate this container with the starting value of three lives. Place the first one, then place the subsequent ones based on the first location.
Some untested code:
NOTE: The following presumes your container clip for the lives is named lives_container and your link instance name for the life icon in the library is Life_icon.
var numberOfLives:Number = 3;
var iconSpacing:Number = 5;
var nextX:Number = 0;
for(var i:int = 0; i < numberOfLives; i++ )
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
This way you could add extra lives easily if the player gained any by adding new icons at the last nextX value, like so:
function addLife():void
{
var icon:MovieClip = new Life_icon();
icon.x = nextX;
lives_container.addChild( icon );
nextX += icon.width + iconSpacing;
}
or remove them as the player loses them:
function removeLife():void
{
var numberOfLivesDisplayed:Number = lives_container.numChildren();
lives_container.removeChildAt( numberOfLivesDisplayed - 1 );
nextX -= icon.width + iconSpacing;
}
Using a container clip for the lives icons makes adjusting the location of the life icons easier if it becomes necessary later.

stage.removeChild throwing an error

I've built a simple snake game that uses a Main class (this is my document class), a Snake class and a Food class. The Main class makes a new object of the Snake class, and another of the Food class. Within both the Snake and Food classes, I'm making sprites like so:
var segment:Sprite = new Sprite();
segment.graphics.beginFill(0xFFFFFF);
segment.graphics.drawRect(0, 0, 10, 10);
segment.filters = [new GlowFilter(0xFF6699, .50, 3, 3, 2, 2, false, false)];
segment.graphics.endFill();
segment.x = x;
segment.y = y;
this.stage.addChild(segment);
this.segments.push(segment);
The snake's body is stored in an array of sprites called segments. You can see from that code I'm making a new sprite to extend the length of the snake and pushing it to the segments array. I do something similar for any food items, except within the food class I've defined the food sprite as public var foodSprite:Sprite; because I only need one on the stage at a time.
Now, when I call the gameOver() method from the Main class (where I have my game loop), I want to call stage.removeChild() on each of the snake segments and the food sprite. I tried doing this:
for(var i:Number = 0; i < this.snake.segments.length; i++)
{
stage.removeChild(this.snake.segments[i]);
}
But I get this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Main/gameOver()
From what I know this should work, as this.snake.segments[i] points to a sprite, the one which I want to remove from the stage.
What could be going wrong here? Thank you.
EDIT: I guess it's also worth noting that segments is defined as:
public var segments:Array = new Array;
Please see comments on this answer for the actual solution.
Try this:
for(var i:Number = 0; i < snake.segments.length; i++)
{
var seg:Sprite = snake.segments[i] as Sprite;
if(seg.parent)
seg.parent.removeChild(seg);
}

AS3: How to refer an object by his properties

Well, I'm doing a checkers game and I need to refer a piece by its position (x and y, both) and remove it from the screen (no problem with this).
I've been traying combinations with "this." but nothing.
How would you do that?
this.x and this.y are functional from the scope of your checkers pieces object; however, if you're accessing a piece outside of their scope, you must use a piece's instance name. Although not optimal, you could loop through children DisplayObjects.
// create a collection of your checker pieces
var checkers:Array = [];
// create a checker piece, whatever your DisplayObject class is.
var checker:Checker;
checkers.push(checker);
// add it to the stage, probably your game board
addChild(checker);
checker.x = 100;
checker.y = 100;
// loop through the children (from your game board)
for (var i:uint = 0; i < numChildren; i++)
{
var checker:DisplayObject = getChildAt(i);
trace(checker.x);
trace(checker.y);
}
Using coordinates to reference a piece may not be optimal for game play. You might want to consider a row / column or approach it from how your game board works.
If this is not clear, you should specify some code or expand your question with more detail.

AS3: How can I construct this Linkage problem?

I want to do something like this with AS3, but I'm new to AS3 and I'm not sure how to go about the coding.
What I need to do is I have 1 x blank MC called all_mc, inside that I need to have 200 x empty_mc all lined up one after another on the x axis.
Each empty_mc is 100px wide and load from a Linkage in the library called panelClass (which is a MovieClip).
The empty_mc itself is called emptyClass in the library.
I need the all_mc to display on the stage from start. It should look like this image. The I need 200 of these red squares.
I know instead of adding all 200 MCs manually, I should be making a loop? But I can not get my head around it for the life of me. Can someone please kindly help me out?
Just make a loop and dynamically create your MovieClips:
var mcWidth:Number = 100; // Using hardcoded value because MovieClip.width is not always reliable (if the MovieClip contains shapes with strokes, etc.)
for (var i:int = 0; i < 200; i++) {
var mc:panelClass = new panelClass();
all_mc.addChild(mc);
mc.name = "empty_mc" + i; // set a name so that it can be accessed later on
mc.x = mcWidth * i;
}

How to avoid create new bitmapData object in loop in AS3?

I want to store the bitmap data from _sampleTile in array, but I was wondering how to increase the performance. If I do it like this:
var _sampleTile:BitmapData;
var _arrayLenght:int = _tileClipArray.length;
for(var i:int = 0; i < _arrayLenght; ++i){
_sampleTile = new BitmapData(65, 65, false);
_sampleTile.draw(_tileClipArray[int(i)]);
_tileBitmapDataArray[i] = _sampleTile;
}
Then it would do too much constructing job in the loop, right? But if I do as bellow:
var _sampleTile:BitmapData = new BitmapData(65, 65, false);
var _arrayLenght:int = _tileClipArray.length;
for(var i:int = 0; i < _arrayLenght; ++i){
_sampleTile.fillRect(_sourceRectangle, 0x00FFFFFF);
_sampleTile.draw(_tileClipArray[int(i)]);
_tileBitmapDataArray[i] = _sampleTile.clone();
}
The .clone() returns a new BitmapData object so basically the result is the same, right?
In the second example if we replace the _sampleTile.clone() with _sampleTile - is it somehow possible to not store in array a reference to _sampleTile, but get the actual bitmapData from the _simpleTile?
No, you need to create a new BitmapData each iteration... either with clone() or new.
I see a couple alternatives though:
Make your creation asynchronous. Do just a few each frame, till you finish the whole batch.
Create a big BitmapData, draw all tiles in there and use references for the position of each tile. If the tiles are always the same, then you could eventually save the final BitmapData + positions and load them instead of creating them each time you run the application.