ForumsProgramming ForumHittesting multiple movie clips with the same identifier? (AS2)

43 24008
mightybob
offline
mightybob
360 posts
Peasant

Well somewhere I read that the more enterFrame's I use the more lag there will be.

So I am trying to make a lot of things be in 1 enterFrame, like coins.

So I need it to be so that when you hit a coin, it goes away, and you 1 point, just like it already does but so that I only need 1 enterFrame. Kind of like target objects in As3. But I don't know how to do this in as2â¦

Help?

  • 43 Replies
arobegamr
offline
arobegamr
130 posts
Nomad

You said you're using AS2?

You can't use getChildAt(), the function is not present in ActionScript2 except for accordion components.

My advice would be to create an array called coins.
var coins:Array = new Array();

When you create the movie clips, push them into the array
coins.push(newCoin);

In your main loop, create a for loop which checks for each item in the array
for(i=0;i

arobegamr
offline
arobegamr
130 posts
Nomad

Apologies, I accidentally hit the submit button.

In your main loop, create a for loop which check for each item in the array
[i]for(i=0;i

arobegamr
offline
arobegamr
130 posts
Nomad

Apologies again, it seems html is getting in my way

In your main loop, create a for loop which checks for each item in the array

for(i=0;i &lt coins.length; i++) {
object = coins[i];
if(char.hitTest(object)) {
object.removeMovieClip();
coins.splice(i,1);
i--;
trace("You win"
}
}


Splice prevents the program from checking for a coin which is no longer there by removing its place in the array. Because all elements thereafter get shifted down, you need to decrease i to avoid skipping the next element.

mightybob
offline
mightybob
360 posts
Peasant

Thanks, but really, this is the first time I have worked with things like this. I need an explanation because or else I can't get it to work.

Here is the code:

var coins:Array = new Array();

coins.push(newCoin);

onEnterFrame = function() {

for(var i:Number = 0; i < coins.numChildren;i++)
{
for(i=0;i < coins.length; i++) {
object = coins[i];
if(char.hitTest(object)==true) {
object.removeMovieClip();
coins.splice(i,1);
i --;
trace("You win&quot;
}
}
}

}

The coin has an identifier of newCoin, it is in the main timeline also with this code.

It is probs because I am getting the names in your code mixed up.

Thanks for all the help

weirdlike
offline
weirdlike
1,299 posts
Prince

you have the for code going on 2 times

var coins:Array = new Array();

coins.push(newCoin);

onEnterFrame = function() {

for(var i:Number = 0; i < coins.numChildren;i++)
{
for(i=0;i < coins.length; i++) {
object = coins[i];
if(char.hitTest(object)==true) {
object.removeMovieClip();
coins.splice(i,1);
i --;
trace("You win&quot;
}
}
}

}

as you already know mine is adapted from as3 so use arobegamr's setup

mightybob
offline
mightybob
360 posts
Peasant

Ohh, thats whats going on. Ok, thanks.

arobegamr
offline
arobegamr
130 posts
Nomad

To clarify, the for loop I gave you is meant to replace the previous one. numChildren is also not available in AS2, array.length is used instead to give the number of elements within the array.

So your enterFrame loop should look like the following:

onEnterFrame = function() {
for(i=0; i &lt coins.length; i++) {
object = coins[i];
if(char.hitTest(object)) {
object.removeMovieClip();
coins.splice(i,1);
i--;
trace("You win&quot;
}
}
}


Note: Because the hitTest function will return either true or false,
saying hitTest(object) == true is redundant. An if condition is triggered if the argument is anything except undefined, false, or null. If you would like me to explain further, please ask.

mightybob
offline
mightybob
360 posts
Peasant

Okay thanks for explaining that it all makes sense now!

But I am confused of still a few things:

The variables⦠I don't get them? I have a coin on the main timeline and the code is on the main timeline. The identifier of the coin is "newCoin".

Is the coins var referring to the identifier? Where does my identifier even come in? Plus object = coins[i];, sounds like your saying coins is my coin, when how can that be when coins is the array?

Sorry, again, total newby at this way of coding, I've never had to use a for loop or an array, and only used identifiers once before, so the simplest explanation would be the best

thanks

weirdlike
offline
weirdlike
1,299 posts
Prince

You can't use getChildAt(), the function is not present in ActionScript2 except for accordion components.


this prompted me to look around for a similar method and found this link HERE, and while arobegamr's method is correct, I think it is not suited for what you are trying to achieve as you have your coins either on a frame or in a movie clip already placed without specifying the x or y coordinates

try this
onEnterFrame = function() {
for(var i in _root){
trace('key: ' + i + ', value: ' + _root[i]);
}
}

then when you have identified the coin

onEnterFrame = function() {
for(var i in _root){
trace('key: ' + i + ', value: ' + _root[i]);

if(char.hitTest(_root[i])) {
object = _root[i];
if(object is newCoin){
//remove coin here
}
if(object is key){
//remove key here
}
}
}
}

this is based off the source link above plus a little of my own style
arobegamr
offline
arobegamr
130 posts
Nomad

object = coins[i];

This is what is called array access syntax. When accessing an element inside of an array (as opposed to the array itself), use the syntax arrayname[indexnumber]

So in other words, retrieve the item in array "coins" at index i.

The array is simply giving you a nice organized list of the movie clips, for example, if you said trace(coins[i]);, flash would return the following:
_level0.newCoin

_level0 is the main stage, also called _root. Weirdlike, it's better to not use var in _root, because you are going to be accessing a lot of unnecessary data. Using that method is only good when you don't already know the identifier for the variables you are trying to access.

And mightybob, It appears as though you are trying to use multiple objects, some of which are coins, and some which are not. I would suggest creating different arrays for different kinds of objects, each array only containing one type. For example, enemies or health packs. Then have a different for loop for each array and handle collisions as necessary for each item type.

weirdlike
offline
weirdlike
1,299 posts
Prince

I already explained that _root can be changed to levelMC, but as the case that not all the coins are placed into a level MC and on main timeline instead leaves only the option of _root.

also you will find that in order to push an item into an array you will need to first access that item such as looking up the instance name (which bob probably already knows) then adding to the array via

coins.push(newCoin1);
coins.push(newCoin2);
coins.push(newCoin2);

this would work well unless you had over a hundred coins (again bob is not adding via code, he already has them placed on the main timeline)

arobegamr
offline
arobegamr
130 posts
Nomad

There actually is a very easy way to do this. By using the _name property of a movie clip, you can specify the identifier via code instead of manually renaming each coin.

Go into the coin movie clip, and in the actions panel on the first frame, type the following:

this._name = "coin"+_root.coins.length;
_root.coins.push(this);


And you're done. You can copy the clip as many times as you want and flash will automatically give each coin a unique identifier and place it in the coins array to be easily manipulated.

mightybob
offline
mightybob
360 posts
Peasant

This last post here is very interesting, so no identifiers even? And I would use the code you gave earlier to make it work I guess.

I will try that definitely.

Btw weirdlike, thanks for the help but on your last post here it showed me that you thought I was working with instance names, but really the whole point I was wanting to use identifiers and such is so I don't have to do coin1, coin2, coin3, blah, blah, blah, etc, irritation, rage quit, etc.

But anyways thanks for all the help I will try that last method there.

weirdlike
offline
weirdlike
1,299 posts
Prince

I knew what you were doing I was stating that you would need to do that in order to add to the array, until I saw arobegamr's post

Go into the coin movie clip, and in the actions panel on the first frame, type the following:

this._name = "coin"+_root.coins.length;
_root.coins.push(this);
mightybob
offline
mightybob
360 posts
Peasant

Well, doesnt work anyway.

I have your EXACT code inside the actions panel on the main timeline, I have your EXACT code inside the first frame of my coin movie clip, and I triple checked the char instance name making sure it wasn't a stupid mistake.

Code on main timeline:
var coins:Array = new Array();
onEnterFrame = function() {
for(i=0; i < coins.length; i++) {
object = coins[i];
if(char.hitTest(object)) {
object.removeMovieClip();
coins.splice(i,1);
i--;
trace("You win&quot;
}
}
}

Player instance name: char

Code inside of the first frame of the coin movie clip:

this._name = "coin"+_root.coins.length;
_root.coins.push(this);

Char is on main timeline, and so is the coin movie clip.

Showing 16-30 of 43