-
-
Senior Member
In order to listen to an event it has to be dispatched. So NewWar has to be changed for example to this.
PHP Code:
private function initialize(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
addEventListener(TankEvent.TANK_INACTIVE, deactivateTank);
stage.addEventListener(MouseEvent.CLICK, moveTarget);
ks_camera = new Camera(this);
ks_abrams = new Abrams(ks_camera, new Point(200, 300));
ks_t90 = new T90(ks_camera, new Point( 400, 300));
}
private function deactivateTank(e:Event):void
{
trace("tank is no longer active");
}
private function moveTarget(e:MouseEvent):void
{
trace(Globals.targetName);
dispatchEvent(new Event(TankEvent.TANK_INACTIVE));
}
- The right of the People to create Flash movies shall not be infringed. -
-
It works when I dispatch an event from NewWar.as but I don't need it. I need my tank to dispatch this event when it's clicked. And this is where I'm completely confused. It should work the same way, but it doesn't
Even though the the tank reacts to the MouseEvent.CLICK perfectly.
Last edited by caseyryan; 06-21-2010 at 09:07 AM.
-
Senior Member
This will also work, when you change from stage to the tanks.
ks_t90.addEventListener(TankEvent.TANK_INACTIVE, deactivateTank);
ks_abrams.addEventListener(TankEvent.TANK_INACTIVE , deactivateTank);
The event when dispatched from the tanks is only received by the tanks but not by the stage.
- The right of the People to create Flash movies shall not be infringed. -
-
aha, bingo! It works now, thanks!
But I still can't get why can't stage listen for this event...
-
Senior Member
I think, because the event is dispatched from the superclass and so only objects extending the superclass can listen. however, you can extend the scope to the stage if you change some part in the Tank class:
var myTimelineisplayObjectContainer = ks_tank.parent.root as DisplayObjectContainer;
myTimeline.dispatchEvent(new TankEvent(TankEvent.TANK_INACTIVE));
This is now received by the stage as well.
The way event dispatching works is a good way to limit the listener to certain objects.
Last edited by cancerinform; 06-21-2010 at 10:32 AM.
- The right of the People to create Flash movies shall not be infringed. -
-
Events do not care about what dispatchers and listeners extend, except that they must extend EventDispatcher or implement IEventDispatcher. Other than that, the lineage of an object has no bearing on what can listen to its events or what events it can listen to.
The probable actual reason that only the dispatching tank could hear the event was that the event did not bubble. I haven't seen the actual code, but unless you set the bubbles property to true when you create the event, it will only go to the same object which dispatches it.
-
Senior Member
It's not quite true. The event bubbling was set to true and both classes implemented IEventDispatcher. I have also noticed something similar when using custom events.
- The right of the People to create Flash movies shall not be infringed. -
-
Great. Now I've got to look at the code. Is the fla necessary?
-
Senior Member
And for completion here is a much simpler example, where the bubbles are set to true but the event is only caught by the object dispatching it.
http://flashscript.biz/test/EventExample.zip
- The right of the People to create Flash movies shall not be infringed. -
-
Originally Posted by 5TonsOfFlax
Is the fla necessary?
Yes. I compile it in Flash CS4.
-
Okay, so here's the deal:
The TANK_INACTIVE event is dispatched from Tank, but the Tank instances are not actually on the displayList, so the events have nowhere to bubble to. Changing the dispatchEvent to be
Code:
ks_tank.dispatchEvent(new TankEvent(TankEvent.TANK_INACTIVE));
makes the MovieClip which actually is on the display dispatch the event, which can then bubble as desired.
There's a lot in this project which I think could be better designed, but that's partially a personal preference.
-
5TonsOfFlax, I'm just learning it So, if you know the better way to design it, I'd really like to know about that.
I don't have an established personal preference yet
The TANK_INACTIVE event is dispatched from Tank, but the Tank instances are not actually on the displayList, so the events have nowhere to bubble to.
So, invoking the super class Tank thru it's children is not the same as invoking it directly?
Last edited by caseyryan; 06-21-2010 at 11:43 AM.
-
Senior Member
5Tons, what you are saying is not completely true. If you look at my example, which I linked, not all objects (Displayobjects) can listen.
- The right of the People to create Flash movies shall not be infringed. -
-
There's actually a lot to like about the way you've put things together, but there are also a few things which can cause some trouble. The first is that your Tank extends MovieClip, but is never actually put on the display. This indicates to me that you've got a bit of confusion regarding what exactly each of your classes does. For instance, you're setting mouseChildren and buttonMode in Tank, but since you never see a tank on the display, these are useless. Also, you explicitly say that Tank implements IEventDispatcher, but since MovieClip already does, that's unnecessary.
Anyway. I'd suggest either being very clear about what is a "logical" class and what is a "display" class, or just actually using your Tanks as display objects. Which brings me to the next point.
I don't think it's a good idea for objects to be passed a parent in the constructor and put themselves on the display. In this case, you are actually putting a graphic asset on the display and NOT the Tank itself. I'd forget the parent parameter, and just have the Tanks set themselves up. Add the graphics to the Tank subclass instance itself, then add the Tank instance in the place where you create the tank. This would also remove the need to pass the location parameter, since the code which creates the Tank can also position it.
I'm not sure that making your events default to bubble = true is a good idea, but this one does seem like personal preference more than anything. The only reason I have an opinion is that the Event base class does have a default for the bubbles parameter, which is false. Without knowing your code, seeing a new TankEvent without a bubbles parameter would look like that was a non-bubbling event.
I think Globals are generally a bad idea. Pass values up through function returns, or event targets, or even data fields in events.
If you DO want to continue using Globals, at least store the information you really want. Do you really want to know the name of the target? Or would you rather have a reference to the target itself?
Before adding a listener to the stage, strongly consider whether that listener should be on the document class or other container instead. In this case, I think the click listener should be on the stage if you need to click blank areas. The TANK_INACTIVE listener could be on the document class instance.
Consider in general the proper classes to extend. If a class does not need frames or frame script, it should not be a MovieClip.
cancerinform, I don't have flash here so I can't compile your example as is. I replaced the List with a Sprite so I could compile it. When I click the sprite, the onListItemClick function executes as expected. I'm not sure what that was supposed to illustrate.
-
Senior Member
The Receiver object cannot listen to the event. Therefore as shown in the script I have to have a reference to the stage or Documentclass. Listening would be bubbling down. So in other words there are certain limits. Also I think it is not a good idea to set the bubbles to true, since the objects, which can listen are not as much limited as if bubbling is false. But that is a different issue.
PHP Code:
public function Receiver (myClip:DisplayObjectContainer):void { myText = new TextField(); addChild (myText); myClip.addEventListener (ListItemClickEvent.LIST_ITEM_CLICK, onListItemClick); } private function onListItemClick (evt:ListItemClickEvent):void { var obj:Object = evt.data; myText.text = String(obj); }
myClip here is a reference to the Document class.
- The right of the People to create Flash movies shall not be infringed. -
-
Oh. We are talking across each other then. Yes, obviously Reciever cannot recieve events via bubbling from its parent. Bubbles only go up. Except in Guinness.
My point was that Reciever can in fact listen to its parent as you've shown there, just not via bubbling. It has to add the listener to the parent directly.
I've mentioned an EventManager pattern here before which allows you to emulate a global broadcast pattern. The idea is that you have a singleton broadcaster instance, and all dispatchEvent and addListener calls for broadcast events are done on that instance. But that's neither here nor there.
-
The first is that your Tank extends MovieClip, but is never actually put on the display. This indicates to me that you've got a bit of confusion regarding what exactly each of your classes does. For instance, you're setting mouseChildren and buttonMode in Tank, but since you never see a tank on the display, these are useless
Yeah, sometimes I really get a bit confused about what to use, sprite or moviclip
Also, you explicitly say that Tank implements IEventDispatcher, but since MovieClip already does, that's unnecessary.
Does it? When I first created it, it only extended MovieClip but this gave me a lot of errors when I tried to dispatch any event from it, but after I implemented an IEventDispatcher to it, it worked out fine
I don't think it's a good idea for objects to be passed a parent in the constructor and put themselves on the display. In this case, you are actually putting a graphic asset on the display and NOT the Tank itself. I'd forget the parent parameter, and just have the Tanks set themselves up. Add the graphics to the Tank subclass instance itself, then add the Tank instance in the place where you create the tank. This would also remove the need to pass the location parameter, since the code which creates the Tank can also position it.
I tried to do it both ways. The same result but less lines of code.
I'm not sure that making your events default to bubble = true is a good idea
I tried it set to false, it didn't work, then I changed it to true, didn't work either
If you DO want to continue using Globals, at least store the information you really want. Do you really want to know the name of the target?
At this point, not. But when I add a UI I'll need it, because the target returns something like "instance3" instead of the name of the tank that I clicked, and if I use Global variable to store the name, it works just fine.
Also I think it is not a good idea to set the bubbles to true, since the objects, which can listen are not as much limited as if bubbling is false.
I never try to set any of them to true it everything works like I planned
-
Originally Posted by caseyryan
At this point, not. But when I add a UI I'll need it, because the target returns something like "instance3" instead of the name of the tank that I clicked, and if I use Global variable to store the name, it works just fine.
That's because the target is the graphic instance which you added to the logical instance. The graphic instance doesn't have a name, because you never gave it one. Names aren't that useful anyway.
If you make it so that the Tanks are actually on the display, and set mouseChildren appropriately on them (false), they will dispatch the click events, and will be the targets.
-
There's also a little problem with this way. If I add the tanks as you say and click the edge of any of them it will work like it's supposed to, but the trick is that each tank movieclip has another movieclip inside, which is called mTurret. So if I click the turret area it returns the name "mTurret" no matter if I set it's mouseChildren property to false or true
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|