00:00
00:00
Newgrounds Background Image Theme

Neptuno84 just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

problem splicing from array [AS3]

1,968 Views | 22 Replies
New Topic Respond to this Topic

problem splicing from array [AS3] 2012-07-30 02:45:16


Okay, here is the current progress. Click to shoot enemies, rupees, and hearts.

Alright, so far I am able to shoot enemies and other objects. Then I was able to (in my own, probably inefficient, way) cause items to spawn from defeated enemies. In this case, when one of the monsters dies, a heart will drop out of it.

Here is my current collision code that allows this:

private function checkCollisions():void
		{			
					
			var bullet:MovieClip;
			var rupee = new Rupee();
			var impact = new Impact();
			var heart = new ZeldaHeart();
		for(var h:int = 0; h < heartArray.length; h++)
		{
			heart = heartArray[h];
			for (var k:int = 0; k < enemyArray.length; k++)
			{
				enemy = enemyArray[k];
				for (var j:int = 0; j < rupeeArray.length; j++)
				{
					rupee = rupeeArray[j];
					for (var i:int = 0; i < bulletArray.length; i++)
					{
						bullet = bulletArray[i];
						
						
						if (rupee.hitTestPoint(bullet.x,bullet.y,true))
						{

							stage.removeChild(bullet);
							stage.addChild(impact);
							impact.x = bullet.x;
							impact.y = bullet.y;
							rupee.rupeeHealth--;
							bulletArray.splice(i,1);
							//rupeeArray.splice(i,1);   //problem line
							if (rupee.rupeeHealth <= 0)
							{
								stage.removeChild(rupee);
							}
						}
						
						
						if (enemy.hitTestPoint(bullet.x,bullet.y,true))
						{
							stage.removeChild(bullet);
							stage.addChild(impact);
							impact.x = bullet.x;
							impact.y = bullet.y;
							enemy.enemyHealth--;
							enemy.gotoAndPlay("enemyHit");
							bulletArray.splice(i,1);
							if (enemy.enemyHealth <= 0)
							{
								heart = new ZeldaHeart();
								rupee = new Rupee();
								stage.addChild(impact);
								stage.addChild(heart);
								heart.x = enemy.x;
								heart.y = enemy.y;
								heartArray.push(heart);
								impact.x = enemy.x;
								impact.y = enemy.y;
								impact.width = 60;
								impact.height = 60;
								stage.removeChild(enemy);
								//enemyArray.splice(k,1);   //problem line
							}
						}
						
						
							if (heart.hitTestPoint(bullet.x,bullet.y,true))
						{

							stage.removeChild(bullet);
							stage.addChild(impact);
							impact.x = bullet.x;
							impact.y = bullet.y;
							bulletArray.splice(i,1);
							stage.removeChild(heart);
							//heartArray.splice(h,1);   //problem line
						}
					}
				}
			}
		}
	}

So, I have each shoot-able item in its own array being tested against the bullet array. Not sure if the way I have it set up is the best way, but it's mostly working correctly.

Some issues I've had: Before, when I was trying to make the collisions with my "heart" items, they wouldn't react to the bullets. It wasn't until I changed the initial heartArray declaration at the top of my program from this:

public var heartArray:Array = [];

into this:

public var heartArray:Array = [heart];

so, I added an initial value of "heart" to the array.

I guess because the array had no value in it at the start of the program, the entire loop was affected and the hearts were unreadable even if they were added to an array later. And I'm not that naive. I know that even though this solution "worked", it is probably a terrible way of doing it.

Now, about the splice. I've tried it in all sorts of different ways, but to no avail. I am no longer getting errors when I try to splice, but the collision checks stop working when I begin to splice objects from their arrays.

For instance, the situation when I only had the splice on my hearts and on my enemies: My hearts would disappear when shot as long as there was still an enemy on the screen. As soon as the final enemy was destroyed and the enemy array was spliced empty, I could no longer interact with any remaining hearts.

I know there must be some way to splice from my arrays and still keep the collision test working. Maybe by separating the collision tests? I thought combining them would be better, but if they are all so dependent on each other, maybe it's not the best idea.

Thoughts?

Response to problem splicing from array [AS3] 2012-07-30 04:49:43


At 7/30/12 02:45 AM, Barzona wrote: Thoughts?

I think its stupid to post a new topic every day because you make a simple mistake obfuscated by the terrible mess that is your code.
Aside from the obvious fact that you have 4 nested for loops inside your function, are misusing the stage object, and have no intentions of breaking a long function into better structure; you lack overall insight in actionscript and honestly, commenting out your error-causing code and posting it to us shouldn't be your solution.
Also making the entire written part of your post appear in bold has a close effect AS TO USING CAPS LOCK ALL THE TIME TO GET ATTENTION; which is frowned upon in general to say the least.

If you still need to figure out how arrays and loops work, I suggest you learn this in a separate project; not when you are already in the process of making something; especially when to continue you require outside help all the time.

Response to problem splicing from array [AS3] 2012-07-30 09:32:20


At 7/30/12 04:49 AM, Sandremss128 wrote:
At 7/30/12 02:45 AM, Barzona wrote: Thoughts?
I think its stupid to post a new topic every day because you make a simple mistake obfuscated by the terrible mess that is your code.

Well, if you have a problem with my multiple posts, don't reply to them or read them. You haven't replied to a single one int these past few days, so for you to have a problem now without ever offering help is a bit out of place.

Aside from the obvious fact that you have 4 nested for loops inside your function, are misusing the stage object, and have no intentions of breaking a long function into better structure; you lack overall insight in actionscript and honestly, commenting out your error-causing code and posting it to us shouldn't be your solution.

No intentions of changing it? "I thought combining them would be better, but if they are all so dependent on each other, maybe it's not the best idea.". Did you even read the post? I'm guessing not. Come back when you actually do.

You can insult my code. That's fine. It does suck, but that's really easy to say by someone who is an alleged expert. I say alleged because you only have one, single tiny game on NG and not much else.

Also making the entire written part of your post appear in bold has a close effect AS TO USING CAPS LOCK ALL THE TIME TO GET ATTENTION; which is frowned upon in general to say the least.

How does that get me attention? It's not like people can see bold writing from inside my thread on the forum page. I do it because I feel it is easier to read compared to the thin type against the black background.


If you still need to figure out how arrays and loops work, I suggest you learn this in a separate project; not when you are already in the process of making something; especially when to continue you require outside help all the time.

If it's a crime to ask for guidance, am guilty. I don't want anyone to write this for me and that is not what I'm asking for. And how else am I going to figure this out than without "outside help"? Should I just blindly type crap into flash and hope something happens?

I'm not trying to be to bombard this forum with endless crap. I haven't exactly gotten very clear answers most of the time. At least, not clear to an amateur.

If you think I'm going too far with my posts, I will stop posting.

Response to problem splicing from array [AS3] 2012-07-30 10:05:17


At 7/30/12 09:32 AM, Barzona wrote: You can insult my code. That's fine. It does suck, but that's really easy to say by someone who is an alleged expert. I say alleged because you only have one, single tiny game on NG and not much else.

I don't think you know what the word "alleged" means.
At what point did he Sandremss, or anyone else for that matter, claim that he was an expert?

At 7/30/12 09:32 AM, Barzona wrote: I do it because I feel it is easier to read compared to the thin type against the black background.

Then you might need glasses; the non-bold font type is very legible.

And as for your problem:

Break up your code.
You posted an 82 line code snippet which involves a for loop nested in a for loop which is nested in another for loop.
You're also modifying the arrays as you're iterating over them.
And you're accessing the stage directly in a class which has no reason to be accessing the stage (though that is unlikely to be the cause of your problems, it's just not very good design).

As it stands the code that you posted is too verbose and obfuscated for anyone to effectively help you.
My advice is to do one of the following:

1) Start over from scratch. Learn the basics of working with arrays and collision detection.
2) Debug your code (using a debugger; not just arbitrarily removing pieces of code to see the affects) and find out precisely where the problem is, and then ask for help regarding that section.

Response to problem splicing from array [AS3] 2012-07-30 10:26:04


At 7/30/12 10:05 AM, Diki wrote:
At 7/30/12 09:32 AM, Barzona wrote: You can insult my code. That's fine. It does suck, but that's really easy to say by someone who is an alleged expert. I say alleged because you only have one, single tiny game on NG and not much else.
I don't think you know what the word "alleged" means.
At what point did he Sandremss, or anyone else for that matter, claim that he was an expert?

Despite the advice given, I still think Sandremss's tone was a bit harsh. Although that may be just how I'm reading it.

Nevertheless, Barzona, it's hard to tell what the problem you're having is without actually understanding what it is you're trying to do. Break your problem into its simplest form. What are you trying to achieve? Splicing elements cleanly from an array? Then make a new fla, try that, see where it gets you, if it doesn't work the way you think it should, post *that* code.

From what I can tell you just need to structure your code better. If I understand you correctly, you have an array that you loop through to check collision, then you remove elements from this array, then you are surprised that the collision stops working?

Obviously if an object needs to have collision as long as it exits then you should never remove it from that array unless the object is destroyed.

My only advice to you now is to try breaking up your problems into their basic form to see if everything is working the way it should, and work your way up.

Response to problem splicing from array [AS3] 2012-07-30 10:35:57


At 7/30/12 10:05 AM, Diki wrote:
At what point did he Sandremss, or anyone else for that matter, claim that he was an expert?

Well, you would think that someone who is so critical of the code of others might actually know what he's talking about.. and might actually DO something with what he knows. We can argue what an "expert" is another time.

At 7/30/12 09:32 AM, Barzona wrote: I do it because I feel it is easier to read compared to the thin type against the black background.
Then you might need glasses; the non-bold font type is very legible.

Sure.

And as for your problem:

Break up your code.
You posted an 82 line code snippet which involves a for loop nested in a for loop which is nested in another for loop.
You're also modifying the arrays as you're iterating over them.
And you're accessing the stage directly in a class which has no reason to be accessing the stage (though that is unlikely to be the cause of your problems, it's just not very good design).

Okay, so we have established that nesting all those loops inside each other is a bad thing. I will break that up. I was going in the wrong direction, it would seem, by combining them.

As it stands the code that you posted is too verbose and obfuscated for anyone to effectively help you.
My advice is to do one of the following:

1) Start over from scratch. Learn the basics of working with arrays and collision detection.

You may be right. I just feel like running instead of learning how to crawl or walk.

2) Debug your code (using a debugger; not just arbitrarily removing pieces of code to see the affects) and find out precisely where the problem is, and then ask for help regarding that section.

I've never messed around with flash's debugger before. I'll give it a try.

Thank you for your help. :)

Response to problem splicing from array [AS3] 2012-07-30 10:42:12


At 7/30/12 10:26 AM, 4urentertainment wrote: Despite the advice given, I still think Sandremss's tone was a bit harsh. Although that may be just how I'm reading it.

Oh it absolutely was harsh; I completely agree with you on that; my point was just that he never once claimed to be an expert, so accusing him of being an "alleged expert" just shows that the OP is using words that he doesn't know the definition of (technically for him to be an alleged expert someone other than himself would have to accuse him of being one, but let's not get into that).

At 7/30/12 10:26 AM, 4urentertainment wrote: You posted an 82 line code snippet which involves a for loop nested in a for loop which is nested in another for loop.

I also just realised that I misread your code and there's actually a total of four for loops, not three.
You really need to fix that OP; the number of potential computations being performed there is outrageous; if each of those arrays has only 10 elements you're looking at 10,000 iterations.

Typically how many elements are in each of those arrays?

Response to problem splicing from array [AS3] 2012-07-30 10:46:16


At 7/30/12 10:26 AM, 4urentertainment wrote: Despite the advice given, I still think Sandremss's tone was a bit harsh. Although that may be just how I'm reading it.

Nevertheless, Barzona, it's hard to tell what the problem you're having is without actually understanding what it is you're trying to do. Break your problem into its simplest form. What are you trying to achieve? Splicing elements cleanly from an array? Then make a new fla, try that, see where it gets you, if it doesn't work the way you think it should, post *that* code.

Well, I'll probably hold off on posting new threads for awhile since I HAVE been asking a bit too much.

From what I can tell you just need to structure your code better. If I understand you correctly, you have an array that you loop through to check collision, then you remove elements from this array, then you are surprised that the collision stops working?

I see your point. Hopefully, when I break up the loops into their own, individual collisions tests, things will start working the way I want them to without problems.

Obviously if an object needs to have collision as long as it exits then you should never remove it from that array unless the object is destroyed.

well, the objects are intended from their arrays to be spliced when each one is destroyed. That's the idea.

My only advice to you now is to try breaking up your problems into their basic form to see if everything is working the way it should, and work your way up.

Fair enough. I really need to start being more patient with this.

Response to problem splicing from array [AS3] 2012-07-30 10:48:20


At 7/30/12 10:35 AM, Barzona wrote: Okay, so we have established that nesting all those loops inside each other is a bad thing. I will break that up. I was going in the wrong direction, it would seem, by combining them.

Nested for loops are not bad per se. There are times when using them is the optimal choice. For example if you wanted to search a two dimensional array for a value it would be optimal to use a for loop nested inside another for loop.
However I can't think of any reason why you'd need three for loops nested inside of another for loop. If each array contains an equal number of elements then your script will perform n^4 iterations (where n is the number of elements).

Is there a specific need to compare every rupee to every bullet, and every enemy to every rupee/bullet, and every heart to every enemy/rupee/bullet? That's what your code is doing right now.

Response to problem splicing from array [AS3] 2012-07-30 10:53:27


At 7/30/12 10:42 AM, Diki wrote:
I also just realised that I misread your code and there's actually a total of four for loops, not three.
You really need to fix that OP; the number of potential computations being performed there is outrageous; if each of those arrays has only 10 elements you're looking at 10,000 iterations.

Typically how many elements are in each of those arrays?

The way it's currently set up to test it, there are 5 rupees in the rupeeArray, 3 enemies in the enemyArray, and a total of 3 possible hearts in the heartArray.

The bullets can be infinite right now because I don't have a boundary function set up to remove them, yet. However, the bullets are spliced from their own array whenever they hit something.

Actually, the loop continues to work even if all the hearts are spliced from their arrays. I'm guessing that is because the splicing for the hearts is done at the innermost part of the function, so the outer hitTests aren't effected.

Response to problem splicing from array [AS3] 2012-07-30 11:06:34


At 7/30/12 10:48 AM, Diki wrote:
At 7/30/12 10:35 AM, Barzona wrote: Okay, so we have established that nesting all those loops inside each other is a bad thing. I will break that up. I was going in the wrong direction, it would seem, by combining them.
Nested for loops are not bad per se. There are times when using them is the optimal choice. For example if you wanted to search a two dimensional array for a value it would be optimal to use a for loop nested inside another for loop.
However I can't think of any reason why you'd need three for loops nested inside of another for loop. If each array contains an equal number of elements then your script will perform n^4 iterations (where n is the number of elements).

Is there a specific need to compare every rupee to every bullet, and every enemy to every rupee/bullet, and every heart to every enemy/rupee/bullet? That's what your code is doing right now.

What if I make individual collision tests for all of my different objects and just use a single nested loop to test each item against the bullets? like so:

for (i:var = 0; i < enemyArray.length; i++){
for(j:var = 0; j < bulletArray.length; j++){
//hittest stuff;
}
}

And just do that for each different item? So, currently, I would need 3 separate collision functions for the rupee, heart, and enemy.

Would that be a better method?

Response to problem splicing from array [AS3] 2012-07-30 11:23:16


At 7/30/12 11:06 AM, Barzona wrote:
At 7/30/12 10:48 AM, Diki wrote:
At 7/30/12 10:35 AM, Barzona wrote: Okay, so we have established that nesting all those loops inside each other is a bad thing. I will break that up. I was going in the wrong direction, it would seem, by combining them.
Nested for loops are not bad per se. There are times when using them is the optimal choice. For example if you wanted to search a two dimensional array for a value it would be optimal to use a for loop nested inside another for loop.
However I can't think of any reason why you'd need three for loops nested inside of another for loop. If each array contains an equal number of elements then your script will perform n^4 iterations (where n is the number of elements).

Is there a specific need to compare every rupee to every bullet, and every enemy to every rupee/bullet, and every heart to every enemy/rupee/bullet? That's what your code is doing right now.
What if I make individual collision tests for all of my different objects and just use a single nested loop to test each item against the bullets? like so:

for (i:var = 0; i < enemyArray.length; i++){
for(j:var = 0; j < bulletArray.length; j++){
//hittest stuff;
}
}

And just do that for each different item? So, currently, I would need 3 separate collision functions for the rupee, heart, and enemy.

Would that be a better method?

You need to write/map out what needs to collide with what. Will a rupee or hearts state change when they collide? As Diki said, you're essentially wasting cycles doing unnecessary checks.

Start with enemies and bullets, you need a nested loop for that - I'd imagine. That's an easy one. Do enemies need to collide with the hearts? I wouldn't have thought so, so you don't need to loop for that. As far as I can tell, bullets are the common denominator for all of your collisions.

Why not nest 3 for loops inside the 1 (not 1 inside 1 inside 1...).

for(b in bullets)
{
    for(e in enemies)
    {
       if(bullet collides with enemy)
    }

    for(r in rupees)
    {
       if(bullet collides with rupee)
    }

    for(h in hearts)
    {
       if(bullet collides with heart)
    }
}

That would allow for each bullet to be tested against each heart, rupee and enemy.

Response to problem splicing from array [AS3] 2012-07-30 11:28:45


At 7/30/12 10:53 AM, Barzona wrote: Actually, the loop continues to work even if all the hearts are spliced from their arrays. I'm guessing that is because the splicing for the hearts is done at the innermost part of the function, so the outer hitTests aren't effected.

That's what happening, yes. The for loop iterating over the hearts array will not exit until the h < heartArray.length argument returns false, and that argument is never performed until all the nested for loops finish, so if you remove all elements from the heart array while inside one of the nested for loops the nested for loops will not be affected.

At 7/30/12 11:06 AM, Barzona wrote: What if I make individual collision tests for all of my different objects and just use a single nested loop to test each item against the bullets? like so:

. . .

And just do that for each different item? So, currently, I would need 3 separate collision functions for the rupee, heart, and enemy.
Would that be a better method?

That would be a much better design, though I don't see any need for three separated collision functions.
Personally I would have a universal collision function (which can be overridden through inheritance if necessary) that, upon detecting a collisions, performs the required actions (usually by executing a specified callback). Here's some psuedo-code to illustrate what I mean:

for i in collidableObjects {
  for j in projectileObjects {
    if j.collides(i) {
        i.performCollideAction();
    }
  }
}

The "performCollideAction" method could be defined in the constructor via a passed callback, or it could be defined/overridden through inheritance.

Response to problem splicing from array [AS3] 2012-07-30 11:34:15


At 7/30/12 11:23 AM, Sam wrote: Why not nest 3 for loops inside the 1 (not 1 inside 1 inside 1...).

for(b in bullets)
{
for(e in enemies)
{
if(bullet collides with enemy)
}

for(r in rupees)
{
if(bullet collides with rupee)
}

for(h in hearts)
{
if(bullet collides with heart)
}
}

That would allow for each bullet to be tested against each heart, rupee and enemy.

I was having trouble before when I put my bullet loop outside my other item (heart, rupee, and enemy) loops, but I'll give it another try using this method.

Response to problem splicing from array [AS3] 2012-07-30 16:28:23


At 7/30/12 11:28 AM, Diki wrote: for i in collidableObjects {
for j in projectileObjects {
if j.collides(i) {
i.performCollideAction();
}
}
}

Surely he'd be better off having the projectile loop as the outer loop? Collidable objects will remain on the screen for a larger amount of time than a bullet would. No need to cycle through the collidable objects if you know there aren't any bullets for them to collide with.

Response to problem splicing from array [AS3] 2012-07-30 16:34:47


Omg, another splicing array problem? I can hardly even read this at this point I've read it so many times it's like spam code. I've never touched splice just always used the swap 'n pop method and never had such terrible issues. Is this the same problem you had 5-ish threads ago? Or is it a new one every time? If it's the same you should really just stick in the same thread. If it's a new problem you should look at something for more than five minutes before you go and ask everyone for help.


If ya have something to say, PM me. I have a lot of time to spare.

Also never PM egg82.

BBS Signature

Response to problem splicing from array [AS3] 2012-07-30 16:38:02


At 7/30/12 04:28 PM, Sam wrote: Surely he'd be better off having the projectile loop as the outer loop? Collidable objects will remain on the screen for a larger amount of time than a bullet would. No need to cycle through the collidable objects if you know there aren't any bullets for them to collide with.

That's a good point; I wrote that psuedo-code on the spot and didn't think it through very thoroughly, and in doing so introduced poor design. :)

Though that's also why if I were to write that in real code I would include a clause to ensure that continuing to check for collisions is necessary (say, for example, checking for when a collidable or projectile object leaves the viewable area and thus no longer could possibly collide with anything).
That of course assumes it would be possible to write a function that computationally offsets the collision detection, otherwise it would be superfluous and possibly less efficient.

In short: yeah you're right. That would be a better way of doing it.

Response to problem splicing from array [AS3] 2012-07-31 13:51:59


Well, after everybody's advice, I broke my collision test into separate parts and now it all works perfectly and that included splicing from each item's separate array.

However, after combining the array the way Sam told me by having the three item "for loops" inside the one arrow "for loop", it works and the splicing works...until a bullet happens to hit two objects at once. If I happen to shoot a bullet that collides with two enemy bodies, it throws the following error again:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.

Now, I have a theory:

After deciding to move on from that and use the three separate collision functions, I starting writing some code that would make the bullets disappear if they went a certain distance from the player. Thus creating and out of bounds function.

The problem is that even if a bullet hits and enemy or an object, something remains because a short while later, the out of bounds function will execute and it will trace "out of bounds" like I told it to.

Does removeChild not completely remove the object? Could that be the cause of the splicing issue?

Response to problem splicing from array [AS3] 2012-07-31 14:07:43


At 7/31/12 01:51 PM, Barzona wrote: Does removeChild not completely remove the object?

It removes the object from the display list.

You are trying to remove the bullet a second time, which is what the error says.

Could that be the cause of the splicing issue?

Please stop the guesswork.

You were told what to do when you splice from the array.

Response to problem splicing from array [AS3] 2012-07-31 14:21:16


At 7/31/12 02:07 PM, milchreis wrote:
At 7/31/12 01:51 PM, Barzona wrote: Does removeChild not completely remove the object?
It removes the object from the display list.

You are trying to remove the bullet a second time, which is what the error says.

Could that be the cause of the splicing issue?
Please stop the guesswork.

You were told what to do when you splice from the array.

Then what do I do about the object lingering on the stage? Even after the arrow is removed (via removeChild), something is still traveling towards the out of bounds area and is setting off the function.

Response to problem splicing from array [AS3] 2012-07-31 14:52:48


At 7/31/12 02:21 PM, Barzona wrote: Then what do I do about the object lingering on the stage? Even after the arrow is removed (via removeChild), something is still traveling towards the out of bounds area and is setting off the function.

What is the "out of bounds area"? Why do you come up with new stuff if the old still produces errors?

Response to problem splicing from array [AS3] 2012-07-31 18:54:13


HOLY HELL THIS IS THE SINGLE MOST INEFFICIENT SOLUTION I HAVE EVER SEEN!!!

Have you ever concerned using one array and one loop and can easily be done. Do you know anything about OOP? you can easily have you objects handle there own collisions without having to have a long and confusing loops designed to work out what's what. Like a bullet hits an object, let the object dictate what should be done, it will make your code simpler and easier to debug!

Response to problem splicing from array [AS3] 2012-08-01 00:26:16


At 7/31/12 06:54 PM, JoSilver wrote: HOLY HELL THIS IS THE SINGLE MOST INEFFICIENT SOLUTION I HAVE EVER SEEN!!!

Have you ever concerned using one array and one loop and can easily be done. Do you know anything about OOP? you can easily have you objects handle there own collisions without having to have a long and confusing loops designed to work out what's what. Like a bullet hits an object, let the object dictate what should be done, it will make your code simpler and easier to debug!

Well, I had that idea before, but a lot of people were telling me it was a bad idea. Especially because I was having the object remove itself. I don't necessarily mind the main class loop method, though.

See, I always thought that the sub classes for objects, like the bullets, were just meant to hold things like the physics and movement of the object.