Results 1 to 15 of 15
Thread: RemoveChild
-
April 12th, 2012, 08:24 PM #19Registered User
postsRemoveChild
Hey, i just started flash and dont know much. I am trying to spawn a sprite (which works correctly). But i cant seem to remove the sprite on mouseclick. Any ideas what i am doing wrong? I have my object called Cactus. It runs fine but returns an error when clicking.
Code:
Error:Code:package { import flash.display.*; import flash.text.*; import flash.events.*; public class Main extends MovieClip { var score = 0; public function Main() { stage.addEventListener(KeyboardEvent.KEY_DOWN, spawner); stage.addEventListener(MouseEvent.CLICK,killTarget); } public function spawner ( k:KeyboardEvent ):void { if ( k.keyCode == 32 ) { trace("test"); var theCactus:Cactus = new Cactus(); theCactus.x = Math.random() * 800; theCactus.y = Math.random() * 600; addChild(theCactus); } } private function killTarget(toDie:MouseEvent):void { var deadTarget:Cactus = (toDie.current target as Cactus); trace(Cactus); if (removeChild(deadTarget)) { score++; //ScoreText.text = "test"; } } } }
Parameter child must be non-null.
at flash.display:
isplayObjectContainer/removeChild()
at Main/killTarget()
Any ideas? Thanks in advance.
-
April 12th, 2012, 11:18 PM #2
theCactus is a local variable, only available within the spawner method.
Declare it as a class property within the class block, then define it within the spawner method. You will then be able to access it from other methods.
Also, just noticed: it's "currentTarget", not "current target"
You are also tracing the Class name instead of the instance.
Lots of little problems in that code.Last edited by snickelfritz; April 12th, 2012 at 11:22 PM.
-
April 12th, 2012, 11:42 PM #3
Nowhere in killTarget does he attempt to use the name theCactus. Obviously deadTarget isn't referencing any object, but that's also obviously not the actual code that he's using since, if it was, he'd be getting a compile time error instead of a run time error.
Proud Montanadian
We tolerate living and breathing. And niches.
Name Brand Watches
Maybe getTimer() or TweenMax is the answer to your problem . . .
-
April 13th, 2012, 01:55 AM #41,391Registered User
postsquick fix? add the killTarget listener to each theCactus instance in spawner - then simply remove as e.currentTarget:
Code://in spanwner ... theCactus.y = Math.random() * 600; theCactus.addEventListener( MouseEvent.CLICK, killTarget, false, 0, true ); addChild(theCactus); ... //not in spawner ;) private function killTarget( e:MouseEvent ):void { removeChild( e.currentTarget ) score++; }
-
April 13th, 2012, 01:24 PM #59Registered User
postsThanks guys.
When i changed it so that cactus was no longer a local variable it worked but now it only removes the last object then displays.
I am spawning more then one object. It will remove one object but then error.Code:ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/removeChild() at Main/killTarget()
I also tried your code cbeech but i received this error:
Code:1118: Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:DisplayObject.
I am guessing i need to create an array and add to it or something?
Thanks
-
April 13th, 2012, 01:40 PM #6
When using the cbeech code, try this:
(I am supposing that Cactus extends a DisplayObject, i.e. MovieClip or Sprite, is it right?)Code:removeChild(e.currentTarget as Cactus);
Last edited by giobongio; April 13th, 2012 at 01:46 PM.
-
April 13th, 2012, 02:17 PM #71,391Registered User
postsright on giobongio
but also marsh, if you use the method i purpose, you should also leave the declaration within the local scope of spawner - otherwise, you'll overwrite the last instance stored each time spawner activates
-
April 13th, 2012, 07:25 PM #89Registered User
postsThat worked perfectly! Thanks a lot.
If you guys arent tired of answering my questions yet:
I am now trying to move my many objects around the screen. But the only object that is moving is the last one i added. I am killing the eventlistener inside the function that creates the object so i should have access to them all?
Is there any way to access each one? like theCactus[1] etc?
Here is my new code:
ThanksCode:package { import flash.display.*; import flash.text.*; import flash.events.*; public class Main extends MovieClip { var score = 0; var theCactus:Cactus = new Cactus(); public function Main() { stage.addEventListener(KeyboardEvent.KEY_DOWN, spawner); } public function spawner ( k:KeyboardEvent ):void { if ( k.keyCode == 32 ) { trace("test"); theCactus = new Cactus(); theCactus.x = Math.random() * 550; theCactus.y = Math.random() * 400; addChild(theCactus); theCactus.addEventListener( MouseEvent.CLICK, killTarget, false, 0, true ); theCactus.addEventListener( Event.ENTER_FRAME, moveCactus); } } private function killTarget( e:MouseEvent ):void { if (removeChild(e.currentTarget as Cactus)) { score++; Score.text = String ("Score: "+score); } } public function moveCactus(evt:Event):void { theCactus.x+=5; trace("test"); } } }
Last edited by marsh0; April 13th, 2012 at 07:34 PM.
-
April 13th, 2012, 08:02 PM #91,391Registered User
postsyou still will probably want to move theCactus declaration back within the spawner method
then similarly to in killTarget use:
Code:public function moveCactus( evt:Event ):void { evt.currentTarget.x += 5; }
-
April 13th, 2012, 08:55 PM #109Registered User
postsWorks great, thanks for all the help.
[Edit]
Well once again i am hopeless in flash. So my program is working as intended and the cactuses move across the screen. When it hits the other side it moves back the way it came.
The problem is that if i have 10 cactuses, if 1 hits the left hand side of the screen they all start moving right and vice versa.
code
Code:package { import flash.display.*; import flash.text.*; import flash.events.*; public class Main extends MovieClip { var score = 0; var direction = 0; public function Main() { stage.addEventListener(KeyboardEvent.KEY_DOWN, spawner); } public function spawner ( k:KeyboardEvent ):void { if ( k.keyCode == 32 ) { var theCactus:Cactus = new Cactus(); theCactus.x = Math.random() * 550; theCactus.y = Math.random() * 400; addChild(theCactus); theCactus.addEventListener( MouseEvent.CLICK, killTarget, false, 0, true ); theCactus.addEventListener( Event.ENTER_FRAME, moveCactus); } } private function killTarget( e:MouseEvent ):void { if (removeChild(e.currentTarget as Cactus)) { score++; Score.text = String ("Score: " +score); } } public function moveCactus(evt:Event):void { if (direction == 0) { evt.currentTarget.x += 5; if(evt.currentTarget.x > 540) { direction = 1; } } else { evt.currentTarget.x -= 5; if(evt.currentTarget.x < 10) { direction = 0; } } } } }Last edited by marsh0; April 13th, 2012 at 09:18 PM.
-
April 13th, 2012, 11:12 PM #111,391Registered User
postsno prob - but you're not 'hopeless' at all, and you're doing well - just takes time

the issue is that 'direction' is a 'single' property of the Document class - this means that when any of the elements hit, they all change the same/only property - so the solution is to store a 'direction' property on each instance, and use it within the move method - i'll rewrite this a bit and show you a little trick to reversing the direction
so now, direction has values of 1 and -1, so when you multiply the speed factor by the current direction you can adjust the travel direction - plus you can simply multiply the direction by -1 to change from one to the other, and it doesn't matter which way it was previous traveling - all this saves a great deal of confusing conditional statements, as you just experiencedCode://in the spawner ... theCactus.x = Math.random() * 550; theCactus.y = Math.random() * 400; theCactus.direction = Math.random()<0.5?1:-1; ... public function moveCactus( evt:Event ):void { var cactus:Cactus = Cactus(evt.currentTarget); if( cactus.x < 10 || cactus.x > 540 ) cactus.direction *= -1; cactus.x += 5 * cactus.direction; }
-
April 13th, 2012, 11:20 PM #121,391Registered User
postsi also just noticed that i think you may want to restructure the killTarget method you have in the last post there
this will explicitly remove the listeners from the object so that you don't end up with memory leaksCode:private function killTarget( e:MouseEvent ):void { Cactus(e.currentTarget).removeEventListener( MouseEvent.CLICK, killTarget ); Cactus(e.currentTarget).removeEventListener( Event.ENTER_FRAME, moveCatcus ); removeChild( Cactus(e.currentTarget) ); score++; Score.text = String ("Score: " +score); }
-
April 14th, 2012, 12:11 AM #139Registered User
postsAh, that makes sense. Should have realized that. I am used to c++ and dont understand what flash handles and does for me. Working great now.
2 Small questions as always
What is the .5 for? Also why doesnt this generate zeros?Code:theCactus.direction = Math.random()<0.5?1:-1;
So if i put the code you have the cactus's dont move. So i decided to check with trace what was happening and it started working. But if i remove the trace it stops again. Any ideas why? I could just leave it there i was just curious.
Thanks for all the help.Code:public function moveCactus(evt:Event):void { var cactus:Cactus = Cactus(evt.currentTarget); trace(cactus.x += 5 * cactus.direction); if( cactus.x < 10 || cactus.x > 540 ) { cactus.direction *= -1; cactus.x += 5 * cactus.direction; } }
-
April 14th, 2012, 01:21 AM #141,391Registered User
postsawesome
the Math.random() method returns a number between 0-1, so since we would like a 'either/or' selection, we can compare the random value against 'half' - if it's less than do one thing, greater than do another - so the line is a conditional comparison, you could also say: if(r<0.5) n=1 else n=-1 - but we can write it in the above form in order to return the result of the condition and assign the value to the property 'direction'What is the .5 for? Also why doesnt this generate zeros?
yes, because you changed what i had written above... LOL...But if i remove the trace it stops again. Any ideas why?
jk
you added braces to the IF statement and surround the elements into a block - it was not meant to function in this way - if there are no braces, the statement following the condition is executed, previous to a line break ; - so you can write it without them if you only are using a single line - as in the above where the ONLY thing we want to do is change the direction when it hits the bounds - but we ALWAYS want to integrate the travel vector
so remove the braces, place the direction change to follow the condition, remove the trace - and it will work again
(ps - it was 'working' with the trace because you are incrementing the value within the trace previous to the condition)
-
April 14th, 2012, 01:35 AM #159Registered User
postsAlright, thanks for explaining
. Finally got it all working

Reply With Quote


Bookmarks