targeting a movie clip and removing it (array)

I'm trying to figure out a solution to a (probably simple) problem regarding spawning a movieclip with addchild() then later to delete them by their name i set them via the movieclip.name function.


Example in the code.

This doesn't seem to always be able to detect if there is a QHERO on stage or not... It seems very unreliable, and won't continue to check even if i KNOW there is an instance of QHERO on the stage (There could potentially be many spawned at once, in which case on the function call, I'd like it to kill all of them) yet it seems to only find one at a time..

the released = true part makes the movieclip tween to a location, then remove itself (which clears up the QHERO name for the next spawn to be deleted or something?)

Not 100% sure.

Help!
public function stepboom(stepx:int, stepy:int, ID:String):void {
			var newHero:Hero = new Hero();
			newHero.targetX = stepx;
			newHero.targetY = stepy;
			newHero.name = ID;
			_root.heroctn.addChild(newHero);
			newHeroArray.push(newHero.name);
			trace(newHeroArray);
		}

		public function killHero(searchValue) {
			for (var i=0; i<newHeroArray.length; i++) {
				if (searchValue == newHeroArray[i]) {
					var target:MovieClip = MovieClip(heroctn.getChildAt(i));
					target.released = true;//tells movieclip to kill itself
				}
			}
		}


		public function eFrameMain(e:Event):void {
			if (key.isDown(key.Q)) {
				if (Qdown == false) {
					Qdown = true;
					stepboom(pad_30.x, pad_30.y, "QHERO"); //spawn movieclip at x, y pos with the name QHERO
				}
			}
			else {
				if (Qdown == true) {
					Qdown = false;
					killHero("QHERO"); // Find QHERO (that was spawned above) and tell it to kill itself

				}
			}


		}

Open in new window

John_RakeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Antonio EstradaTech Leader / Senior Web DeveloperCommented:
I'm not sure I follow completely...

However, here's a sample fla that does what you're asking:

http://vulturous.110mb.com/eefiles/deleteByName.fla

Here's the code too:

<code>

And if this isn't what you're looking for, please post your fla so I can take a look at it and do a better diagnostic.

Good Luck!

-V
var testArray:Array = new Array();

addTests(15);
btnDelete.addEventListener(MouseEvent.MOUSE_DOWN, deleteTests);

function addTests(num:Number):void {
	for(var i:int = 0; i <= num-1; i++) {
		var test:Test = new Test();
		test.x = Math.random() * (stage.stageWidth - test.width);
		test.y = Math.random() * (stage.stageHeight - test.height);
		test.name = "SOME_NAME";
		testArray.push(test.name);
		addChild(test);
	}
}

function deleteTests(event:Event):void {
	for(var i:int = 0; i <= testArray.length-1; i++) {
		if(testArray[i] == "SOME_NAME") {
			try {
				removeChild(getChildByName(testArray[i]));
			} catch(error:Error) {}
		}
	}
}

Open in new window

0
John_RakeAuthor Commented:
This looks perfect.

Will try when I get home & inform you if it works.
0
IqAndreasCommented:
You don't even need to access the hero according to name. Just keep a reference to the hero you created.

See attached code. If you have any questions or want me to elaborate on how it works, just ask.
public function stepboom(stepx:int, stepy:int):void {
      var newHero:Hero = new Hero();
      newHero.targetX = stepx;
      newHero.targetY = stepy;
      newHero.name = ID;
      _root.heroctn.addChild(newHero);
      newHeroArray.push(newHero);
      //trace(newHeroArray);
      
      currentHero = newHero;
}

public var currentHero:Hero;

public function killHero(hero:Hero) {
      hero.released = true;//tells movieclip to kill itself
}

public function eFrameMain(e:Event):void {
      if (key.isDown(key.Q)) {
              if (Qdown == false) {
                      Qdown = true;
                      stepboom(pad_30.x, pad_30.y); //spawn movieclip at x, y pos
              }
      }
      else {
              if (Qdown == true) {
                      Qdown = false;
                      killHero(currentHero); // Find the current hero (that was spawned above) and tell it to kill itself
              }
      }

}

Open in new window

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

John_RakeAuthor Commented:
Sadly it needs to be specifically referenced on a key by key basis (as I'll be spawning them with all the keys, not just Q) therefore a reference to the previous created hero isnt necessarily going to be accurate enough.

I'm having some issues implementing the previous as well, doesn't seem to like it oh so much.

Will tinker a bit more, if can't get working, i'll make a stripped down version and post the fla.
0
John_RakeAuthor Commented:
I'm getting down to this point now, but it's just not allowing me to define the target ("QHERO") as a movieclip, in fact its not letting me do anything with it, but if i trace what it is, the result is just, QHERO


Am I missing something silly here?



public function stepboom(stepx:int, stepy:int, ID:String):void {

			var newpressureBoom:PressureBoom = new PressureBoom();
			//set the bullet's coordinates
			newpressureBoom.x = stepx;
			newpressureBoom.y = stepy;
			_root.splashctn.addChild(newpressureBoom);

			var newHero:Hero = new Hero();
			newHero.targetX = stepx;
			newHero.targetY = stepy;
			newHero.name = "QHERO";
			_root.heroctn.addChild(newHero);
			newHeroArray.push(newHero.name);
			//trace(newHeroArray);
		}	
	

public function killHero(event:Event):void {
			trace(newHeroArray
			for (var i:int = 0; i <= newHeroArray.length-1; i++) {
				if (newHeroArray[i] == "QHERO") {
					try {
						var target:MovieClip = MovieClip(newHeroArray[i]);
						target.released = true
					} catch (error:Error) {
						trace("error killing QHERO")
					}
				}
			}
		}

Open in new window

0
IqAndreasCommented:
Ah. I see now. And I'm assuming everything is AS2 as well, correct?

Try the attached code and see if it works. If not, just reply back with the error message, and I will track down the problem.

Just ask if you want me to explain any part of the code better.

Good luck with your programming,
Andreas
public var keysDown:Array = new Array();
public var heroes:Array = new Array();

public function killHero(keyCode:int) {
    if (heroes[keyCode:int])
    {
        //tells movieclip to kill itself
        heroes[keyCode:int].released = true;
    } 
}

public function eFrameMain(e:Event):void {
      if (key.isDown(key.Q)) {
              if (keysDown[key.Q] == false) {
                      keysDown[key.Q] = true;
                      stepboom(pad_30.x, pad_30.y, key.Q); //spawn movieclip at x, y pos
              }
      }
      else {
              if (keysDown[key.Q] == true) {
                      keysDown[key.Q] = false;
                      killHero(key.Q); // Find the current hero (that was spawned above) and tell it to kill itself
              }
      }

}

public function stepboom(stepx:int, stepy:int, keyCode:int):void {
      var newHero:Hero = new Hero();
      newHero.targetX = stepx;
      newHero.targetY = stepy;
      newHero.name = ID;
      _root.heroctn.addChild(newHero);
      
      heroes[keyCode] = newHero;
      //trace(newHeroArray);
}

Open in new window

0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
lgAndreas, it's not AS2, it's AS3.

John Rake, I think it's time to see your fla, it might be something simple that it's right there, but it might be something else.

-V
0
IqAndreasCommented:
It look like AS3 to me to, but he uses "key.isDown". Is that some kind of custom class that allows for an "AS2 to AS3 bridge" for developers? Also, he uses "_root", so I'm pretty sure we can assume it's AS2, correct?

But try my code. It should really work! :) Just ask if you have any questions about it.
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Not necessarily, I'd lean toward the bridge option but you can now do things like

var _root:MovieClip = new MovieClip();
addChild(_root);

And it's fine :p

-V
0
IqAndreasCommented:
Yes, I know it is possible to do so, and make it seem like AS2, but what I am saying is:
John Rake IS using ActionScript 2 for this project!  (right?)
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Take it easy. I won't turn this into a dumb argument, but types "void" and "int" would throw errors, properties "x" and "y" wouldn't work, the functions "addChild" and "getChildAt" wouldn't exist unless they were prototyped, and he's obviously using custom MovieClips exported for ActionScript, thus getting the classes "Hero" and "PressureBoom".

-V
0
IqAndreasCommented:
Sorry about that. You are right, it's just one of those blond days for me. :P Sorry, I should have thought of those. I tend to assume too much. :(

Anyway, now that I know it's AS3, that is fantastic! It makes all the code A LOT easier! :) See the attached code, and just ask if you have ANY questions.

Andreas
public var heroContainer:MovieClip = new MovieClip();
public var keysDown:Array = new Array();
public var heroes:Array = new Array();

//Added this function to contain all "setup" items
public function setup()
{
    this.addChild(heroContainer);
    
    //Add the event listeners for key presses
    stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
    stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}

public function onKeyDown(ke:KeyboardEvent):void
{   
    //Only add a hero if the pressed key is between A and Z (keycodes 65 and 90)
    const A:int = 65;
    const Z:int = 90;
    
    if ((ke.keyCode > 65) && (ke.keyCode < 90))
    //Only add a hero if one does not already exist
    if (heroes[keyCode])
    {
        trace("Hero already exists for this key", String.fromCharCode(ev.keyCode));
    }
    else
    {
        //spawn movieclip at x, y pos
        stepboom(pad_30.x, pad_30.y, ke.keyCode); 
    }
}

public function onKeyUp(ke:KeyboardEvent):void
{   
    //Remove a hero if the pressed key is between A and Z (keycodes 65 and 90)
    const A:int = 65;
    const Z:int = 90;
    
    if ((ke.keyCode > 65) && (ke.keyCode < 90))
    //Only remove the hero if it actually exists yet
    if (heroes[keyCode])
    {
        killHero(ke.keyCode);
    }
}

public function stepboom(stepx:int, stepy:int, keyCode:int):void {
      
      var newHero:Hero = new Hero();
      newHero.targetX = stepx;
      newHero.targetY = stepy;
      newHero.name = String.fromCharCode(keyCode) + "HERO";
      
      heroContainer.addChild(newHero);
      
      heroes[keyCode] = newHero;
      trace("Created a hero named", newHero.name);
}

public function killHero(keyCode:int) {
    var heroToKill:Hero = heroes[keyCode];
    if (heroToKill != null)
    {
        //tells movieclip to kill itself
        heroToKill.released = true;
        
        //Do you also want to remove the hero from the stage and array?
        heroContainer.removeChild(heroToKill);
        heroes[keyCode] = null;
    } 
}

Open in new window

0
John_RakeAuthor Commented:
Hi, thanks for the assistance, but I'm just having huge issues with this - I've built a stripped down fla which has the issue.

Currently have Q and W keys, but more will be added later these two for now demonstrate the issue.

What it should do, is when I hit a key, a blue block should spawn and move to the location of the represented key - this works fine, however when I let go of the key, I need some function to loop through, and target the hero which is associated with the key released, eg my "QHERO" or "WHERO", via sending the function the name of the hero to look for, so ideally, in my part where the key is let go (the else) it would call a function eg killHero("QHERO") and then would loop through the heros, find all the ones named QHERE and send them a boolean value of true for their own "released" property, I was trying to do this by after finding them within the array, telling it they're a movieclip with this:

var target:MovieClip = MovieClip(newHeroArray[i]);
target.released = true;


which should work fine, I'm pretty sure the syntax is wrong though.

Thanks for the help with this!! It's driving me crazy!!!
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Can you post the stripped down fla?

-V
0
John_RakeAuthor Commented:
Wow, I swear I attached it to my previous post must have failed and I didn't realise,

Here it is: files.me.com/kgosschalk/esxv6b

I had issues uploading the file to EE due to it recjecting it due to hidden files it seems (being made on a mac, it disliked the hidden "mac" file stuff)

Cheers
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Uh oh... can you re-upload just the fla file or send it to my email? (it's in my profile).

Apparently something went wrong and I can't open your *.fla, everything else is fine though. Turns out that I'm on a PC so there could be issues in how the file was zipped, how it was transfered and whatnot.

Sorry for the inconvenience.

-V
0
John_RakeAuthor Commented:
no worries, here is the fla

(it's CS4)
Demo-JohnRakeCS4.fla
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Alright, sorry for not getting back to this earlier. I wasn't around this weekend. Anyway, I changed your Main class and I think it's working now, (I'm guessing this is what you need), hope it is, check the code below.

Good Luck!

-V
package com.lasquiggle{
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.lasquiggle.*;
	import flash.ui.Keyboard;
	import flash.display.*;
	import flash.events.*;
	import flash.net.SharedObject;

	public class Main extends MovieClip {

		private var debug:Boolean = true;
		private var _root:MovieClip;
		public var newHeroArray:Array = new Array  ;
		private var Qdown:Boolean;
		private var Wdown:Boolean;
		public var key:KeyObject = new KeyObject(stage);

		public function Main() {
			this.addEventListener(Event.ADDED,beginClass);
		}

		//stuff to do at load;
		private function beginClass(e:Event):void {
			_root = MovieClip(root);

			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			stage.focus = stage;
			this.removeEventListener(Event.ADDED,beginClass);
		}

		public function stepboom(stepx:int,stepy:int,ID:String):void {
			var newHero:Hero = new Hero();
			newHero.targetX = stepx;
			newHero.targetY = stepy;
			newHero.name = ID;
			_root.addChild(newHero);
			newHeroArray.push(newHero.name);
			if(debug) trace("After Adding: " + newHeroArray);
		}



		public function deleteTests(instanceName:String):void {
			if(debug) trace("Before Deleting (" + instanceName + "): " + newHeroArray);
			for (var i:int = 0; i <= newHeroArray.length - 1; i++) {
				if (newHeroArray[i] == instanceName) {
					try {
						var target:* = _root.getChildByName(newHeroArray[i]);
						newHeroArray.splice(i,1);
						_root.removeChild(target);
					} catch (error:Error) {
						throw new Error("Error killing " + instanceName);
					}
				}
			}
			if(debug) trace("After Deleting (" + instanceName + "): " + newHeroArray);
		}

		protected function keyPressed(event:KeyboardEvent):void {
			if(event.keyCode == 81) { //Q
				if (Qdown == false) {
					Qdown = true;
					stepboom(pad_30.x,pad_30.y,"QHERO");
				}			
			} else {
				if (Qdown == true) {
					deleteTests("QHERO");
					Qdown = false;
				}				
			}
			if(event.keyCode == 87) { //W
				if (Wdown == false) {
					Wdown = true;
					stepboom(pad_14.x,pad_14.y,"WHERO");
				}
			} else {
				if (Wdown == true) {
					deleteTests("WHERO");
					Wdown = false;
				}
			}
		}


	}
}

Open in new window

0
John_RakeAuthor Commented:
Close, except I'd like to send the variable "released" as true to the hero to be killed, rather then removing it (they will remove themselves once this is done)

Also it seems to only be deleting them when you press another button - rather then when you release the keys themselves? mistake in true/false?

So close!
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Oh, ok I think I get it now... give me a few minutes and you should have it.
-V
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
This seems to be ok. Also, on Hero.as, you need to change released from private to public.

Main.as:

<code>

-V
package com.lasquiggle{
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.lasquiggle.*;
	import flash.ui.Keyboard;
	import flash.display.*;
	import flash.events.*;
	import flash.net.SharedObject;

	public class Main extends MovieClip {

		private var debug:Boolean = true;
		private var _root:MovieClip;
		public var newHeroArray:Array = new Array  ;
		private var Qdown:Boolean;
		private var Wdown:Boolean;
		public var key:KeyObject = new KeyObject(stage);

		public function Main() {
			this.addEventListener(Event.ADDED,beginClass);
		}

		//stuff to do at load;
		private function beginClass(e:Event):void {
			_root = MovieClip(root);

			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUnPressed);
			stage.focus = stage;
			this.removeEventListener(Event.ADDED,beginClass);
		}

		public function stepboom(stepx:int,stepy:int,ID:String):void {
			var newHero:Hero = new Hero();
			newHero.targetX = stepx;
			newHero.targetY = stepy;
			newHero.name = ID;
			newHero.released = false;
			_root.addChild(newHero);
			newHeroArray.push(newHero.name);
			if(debug) trace("After Adding: " + newHeroArray);
		}



		public function deleteTests(instanceName:String):void {
			if(debug) trace("Before Deleting (" + instanceName + "): " + newHeroArray);
			for (var i:int = 0; i <= newHeroArray.length - 1; i++) {
				if (newHeroArray[i] == instanceName) {
					try {
						var target:* = _root.getChildByName(newHeroArray[i]);
						target.released = true;
						trace(target.released);
						newHeroArray.splice(i,1);
						//_root.removeChild(target);
					} catch (error:Error) {
						throw new Error("Error killing " + instanceName);
					}
				}
			}
			if(debug) trace("After Deleting (" + instanceName + "): " + newHeroArray);
		}

		protected function keyPressed(event:KeyboardEvent):void {
			if(event.keyCode == 81) { //Q
				if (Qdown == false) {
					Qdown = true;
					stepboom(pad_30.x,pad_30.y,"QHERO");
				}
			}
			if(event.keyCode == 87) { //W
				if (Wdown == false) {
					Wdown = true;
					stepboom(pad_14.x,pad_14.y,"WHERO");
				}
			}
		}

		protected function keyUnPressed(event:KeyboardEvent):void {
			if(event.keyCode == 81) { //Q
				if (Qdown == true) {
					deleteTests("QHERO");
					Qdown = false;
				}			
			}
			if(event.keyCode == 87) { //W
				if (Wdown == true) {
					deleteTests("WHERO");
					Wdown = false;
				}
			}
		}

	}
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
John_RakeAuthor Commented:
Perfect solution, A+ support.

You guys never cease to amaze me.
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Glad to help!

-V
0
John_RakeAuthor Commented:
Thanks for the assistance, will be very useful!
0
John_RakeAuthor Commented:
Vulturous, any chance you're still monitoring this?

Quick Q:

What would be the easiest way to make it so it couldn't spawn say a QHERO if one already existed?
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
Well, you have that reference in two places, the array and the display list, so I guess it's pretty much a matter of tastes but I'd do this:

<code>

-V
if(_root.getChildByName("QHERO") == null) {
   stepboom(pad_30.x,pad_30.y,"QHERO");
}

Open in new window

0
John_RakeAuthor Commented:
You sir, are a genius, works perfect - got an email link somewhere? (it's not in your profile)? I'd love to share the outcome of this stuff.
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
It's there (right above some dates), but in any case, it's vulturous at gmail. Would love to see how this project ends!

-V
0
John_RakeAuthor Commented:
Still having some issues with this code actually - it seems sometimes they get "stuck" and then you can't remove/do anything with them, any clue why this is happening?
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
What do you mean "stuck" and when does it happen?

-V
0
John_RakeAuthor Commented:
The graphics seem to get stuck every now and then if you just spam click the key. It doesn't seem to have a threashhold on when you can release the key - sometimes the block will remain, and then you can't make a new one on the same key.
0
Antonio EstradaTech Leader / Senior Web DeveloperCommented:
I wasn't able to reproduce that error, but I tried to fix it anyway, here it is... and I couldn't make it stop working fine.

<code>

-V
package com.lasquiggle{
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.lasquiggle.*;
	import flash.ui.Keyboard;
	import flash.display.*;
	import flash.events.*;
	import flash.net.SharedObject;

	public class Main extends MovieClip {

		private var debug:Boolean = true;
		private var _root:MovieClip;
		public var newHeroArray:Array = new Array  ;
		private var Qdown:Boolean;
		private var Wdown:Boolean;
		public var key:KeyObject = new KeyObject(stage);

		public function Main() {
			this.addEventListener(Event.ADDED,beginClass);
		}

		//stuff to do at load;
		private function beginClass(e:Event):void {
			_root = MovieClip(root);

			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUnPressed);
			stage.focus = stage;
			this.removeEventListener(Event.ADDED,beginClass);
		}

		public function stepboom(stepx:int,stepy:int,ID:String):void {
			var newHero:Hero = new Hero();
			newHero.targetX = stepx;
			newHero.targetY = stepy;
			newHero.name = ID;
			newHero.released = false;
			_root.addChild(newHero);
			newHeroArray.push(newHero.name);
			if(debug) trace("After Adding: " + newHeroArray);
		}



		public function deleteTests(instanceName:String):void {
			if(debug) trace("Before Deleting (" + instanceName + "): " + newHeroArray);
			for (var i:int = 0; i <= newHeroArray.length - 1; i++) {
				if (newHeroArray[i] == instanceName) {
					try {
						var target:* = _root.getChildByName(newHeroArray[i]);
						target.released = true;
						trace(target.released);
						newHeroArray.splice(i,1);
						//_root.removeChild(target);
					} catch (error:Error) {
						throw new Error("Error killing " + instanceName);
					}
				}
			}
			if(debug) trace("After Deleting (" + instanceName + "): " + newHeroArray);
		}

		protected function keyPressed(event:KeyboardEvent):void {
			if(event.keyCode == 81) { //Q
				if ((Qdown == false)&&(_root.getChildByName("QHERO") == null)) {
					Qdown = true;
					stepboom(pad_30.x,pad_30.y,"QHERO");
				}
			}
			if(event.keyCode == 87) { //W
				if ((Wdown == false)&&(_root.getChildByName("WHERO") == null)) {
					Wdown = true;
					stepboom(pad_14.x,pad_14.y,"WHERO");
				}
			}
		}

		protected function keyUnPressed(event:KeyboardEvent):void {
			if(event.keyCode == 81) { //Q
				if (Qdown == true) {
					deleteTests("QHERO");
					Qdown = false;
				}			
			}
			if(event.keyCode == 87) { //W
				if (Wdown == true) {
					deleteTests("WHERO");
					Wdown = false;
				}
			}
		}

	}
}

Open in new window

0
John_RakeAuthor Commented:
Hi, I've sent you an email with the issue,

Thanks for the help!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Web Development Software

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.