I'm making a tile based game where ta_*(number)* and ca_*(number)* acts like bins. You drag things towards it and drop. But the level may put several these tiles.
I am not going to make something like:
if (my_mc.hitTestObject(ta_0) || my_mc.hitTestObject(ta_1) || my_mc.hitTestObject(ta_2).........)
Because some may not exist and throw an error at me, and I don't want to make like hundreds of them.
Is there a way to find movieclips on stage that start with the name "ta_" and "ca_"?
So that I can get: ta_1, ta_2.....?
No, you can't. Unless you loop on getChildAt() and check all children's names.
But, why don't you add your bins to an array when creating them?
(I assume you create them dynamically)
var myBinArray:Array = new Array(10);
for (var i:int = 0; i < myBinArray.length; i++)
{
var myBin = new Bin();
myBinArray[i] = myBin;
}
Then you simply loop on your array:
for (var i:int = 0; i < myBinArray.length; i++)
{
if (mybinArray[i] != null)
if (my_mc.hitTestObject(mybinArray[i])
{
// statements
// and here I assume you want to break for loop
}
}
Related
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.
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.
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.
I am trying to put together a match activity where word in one column are linked by a line to definitions in another column. Once all words have been linked to their definitions, you end up with a series of crossing lines so, so I want the definitions and their line to move so that each is level with their connected word and the lines have unravelled. I've got as far as connecting the words to their definitions using a line (as a sprite) and the definitions can then be moved using tweenlite -but I have no idea how I move the lines with their definition. Here is a much simplified section of code to give you an idea of what I am trying to do
import com.greensock.*;
import com.greensock.easing.*;
var wordArray:Array = [word1, word2, word3, word4];
var definitionArray:Array = [definition1, definition2, definition3,definition4];
for (var i:int = 0; i < wordArray.length; i++){
var line:Sprite = new Sprite();
line.graphics.lineStyle(2,0x000000);
line.graphics.moveTo(wordArray[i].x, wordArray[i].y);
line.graphics.lineTo(definitionArray[i].x, definitionArray[i].y);
this.addChild(line);
}
for (var j:int = 0; j < wordArray.length; j++){
TweenLite.to(definitionArray[j], 2, {delay:1, y:wordArray[j].y});
}
I am new to this so any help on how I would animate the lines to they follow the definitions would be very much appreciated.
Thanks for the help, it got me started - the errors occur because when onUpdate occurs, TweenLite needs to know the type of the arguments that are passed to the function. What I did was to call to a separate function and use onUpdateParams: to specify the nature of the arguments passed. Here is the code:
TweenLite.to(definitionArray[i], 3, {y:wordArray[j].y,onUpdate:refreshLines,
onUpdateParams:[lines,wordArray,definitionArray]});
with the function
function refreshLines(param1:Array,param2:Array,param3:Array):void{
for (var j:int = 0; j < param4.length; j++){
param1[j].graphics.clear();
}
for (var i:int = 0; i < param4.length; i++)
{
param1[i].graphics.lineStyle(2,0x000000);
param1[i].graphics.moveTo(param2[i].x, param2[i].y);
param1[i].graphics.lineTo(param3[i].x, param3[i].y);
}
}
Once again, many thanks for pointing me in the right direction, it saved me heaps of time.
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.