How to Hit Test with duplicated object on stage? - actionscript-3

Hey everyone so I have my main Movie Clip added to the stage called mcObstacles now in this movie clip i have a nested movie clip with an instance name of mcAsteroidsSpin this movie clip has 4 rotating asteroids that I use to hit test against my spaceship those 4 rotating asteroids have a hit box named mcSpinningHit now everything is working fine as far as the hitTestObject functions goes against all 4 of the nested movie clips. The issue that I am struggling with is that when I try and Duplicate that mcAsteroidsSpin movie clip that is on the stage and run the game again it only hitTests againts the duplicate Movie clip instance. I have tried multiple ideas like adding all the duplicate movie clips to an array and hit test then but didn't work for me or maybe set it up wrong. Instead I resorted to renaming the duplicate mcAsteroidsSpin to mcAsteroidsSpin2 and mcAsteroidsSpin3 and so on and making multiple functions. Which i know is the hard way and there is an easier method I am over looking here is how I Have it setup and any help would be appreciated!
//MAIN OBSTACLES HANDLER LOOP INNER IS EVERYTHING ELSE INSIDE IT
for (var i:int = 0; i < aObstacleArray.length; i++)
{
// Get a platform instance from the Array.
var aObstacle:mcObstacles = aObstacleArray[i];
/************************SPINNING ASTEROIDS 1************************
* *
**********************************************************/
for (var a:int = 0; a < aObstacle.mcAsteroidsSpin.numChildren; a++)
{
// Get a potential Asteroid.
var spinningAsteroids:mcSpinningHit = aObstacle.mcAsteroidsSpin.getChildAt(a) as mcSpinningHit;
// Skip if it is not a Asteroid.
if (!spinningAsteroids) continue;
// Ignore wrong Asteroid by name.
if (spinningAsteroids.name != "mcSpinningHit") continue;
if (spaceship.mcHit.hitTestObject(spinningAsteroids))
{
spaceship.destroy();
trace("HIT");
}
}
}
So Pretty much i am trying to hitTest against more than one of aObstacle.mcAsteroidsSpin movie clips/

Related

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

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.

push objects that equal true, into an array

I have an enemy hitting a bunch of tiles, and through a loop, I check all the tiles if the enemy is hitting them. I trace them and some will tell me if it's true or false. I want to be able to get the enemy to randomly choose from those that are true, and go on those tiles. It traces all the tiles that are in contact with the enemy, problem is, I'm not sure how I can get those tiles that are registering as true, into its own array, then have the enemy move randomly into those tiles.
for (var j:int = 0; j < tileset.length; j++){
trace(tileset[j].currentFrameLabel, tileset[j].hitTestObject(enemy));
if (tileset[j].hitTestObject(enemy) && !tileset[j].hitTestObject(player)){
options.push(Boolean(true));
}
EDIT: here's my timer function, where every 5 second, I want the enemy to move to an available tile. Although you can't see tileset, it is an array that is equal to the movieclip that is a tile, which is in a for loop itself. So basically, tileset is 49 movie clips of tile. I have those available tiles pushed into another array which is options. Then I make a var called enemyPick which would be the counter. That's how far I am.
function timerenemy (event:TimerEvent) {
var options:Array = [];
for (var j:int = 0; j < tileset.length; j++){
if (tileset[j].hitTestObject(enemy) && ! tileset[j].tileMiddle.hitTestObject(player)) {
//trace(tileset[j].currentFrameLabel, tileset[j].hitTestObject(enemy));
tileset[j].outline.gotoAndStop("attack");
options.push(tileset[j]);
}
if (options.length > 0){
var enemyPick:int = Math.floor(Math.random()*options.length)
}
}
trace(enemyPick, options);
}
First, create an array who's length is the maximum number of acceptable tiles. For instance, in a straight line of tiles, only two can possibly be available at a time. Now, each time you need to have the enemy move tiles, initialize a counter to 0. Then, loop through each tile, and 'ask' if it is touching the enemy. If it its, record it in array[counter], and increment counter. After the loop, pick a random number from 0 to (counter) and use array[random number] as the tile that the enemy moves to.

Splicing elements out of a Vector in a loop which goes through the same Vector (ActionScript 3)

I'm making a simple game and have a Vector full of enemies in order to do hit-checking on them from my "laser" object (it's a space shmup). Every laser loops through the Vector and checks if it's occluding the hit circle. The problem lies in when one laser destroys an enemy, the rest of the lasers try to also check the same Vector, only to go out of bounds since the enemy's already been spliced out and it's changed the size of the Vector.
for each (var enemy:Enemy in enemies){
var distanceX = this.x - enemy.x;
var distanceY = this.y - enemy.y;
var distance = Math.sqrt( (distanceX*distanceX) + (distanceY*distanceY) );
if (distance <= enemy.hitRadius) {
enemy.removeEnemy();
enemies.splice(enemies.indexOf(enemy),enemies.indexOf(enemy));
}
}
How would I go about collecting the index of individual elements in the Vector to be deleted, then only deleting them when every Laser object is finished its checking?
edit: here's my removeEnemy() function from my Enemy class, just in case:
public function removeEnemy(){
removeEventListener(Event.ENTER_FRAME, move);
parent.removeChild(this);
trace("removed Enemy", enemies.indexOf(this));
}
edit edit: I'm also getting a null reference pointer error to "parent" in my removeEnemy() function... but only sometimes. I have a feeling that if I fix one of these two problems, the other will also be fixed but I'm not sure.
I fixed it! The problem was actually in how I used the "splice()" method. Turns out that the second parameter isn't the end index of where to stop splicing, it's the number of elements to be spliced. So when I was trying to splice element 0, I wasn't splicing anything, and when I was trying to splice element 3, I was also splicing 4 and 5. I feel like such a dunce for not reading the API right and wasting a couple hours on this. Thanks to everyone who commented-- you guys helped me rule out what I thought the problem was.

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;
}