how to call function on movie load in actionscript instead using event listener? - actionscript-3

Here is the code to call function using event listener:
var listListener:Object = new Object();
listListener.change = function() { changeImage(); }
thelist.addEventListener("change", listListener);
Is there a way to call the function simply when the frame is loaded using the same function as above?
Thanks
agus

So long as you're calling this from within an instance of a Class that extends EventDispatcher (i.e. MovieClip, Sprite, etc.)...
Use this to dispatch an event of that type (i.e. "change").
dispatchEvent(new Event("change"));

Related

MOUSE_DOWN and MOUSE_UP not dispatching for custom Sprite

I have created a custom Sprite object which is not dispatching the MouseEvent.MOUSE_DOWN or MouseEvent.MOUSE_UP events. It is properly dispatching MouseEvent.MOUSE_MOVE events.
All event listeners are verified to be registered.
I apologize if this is a common or excessively simple question, but I have spent the last hour Googling and reading StackOverflow for questions or answers that fit my situation and simply have not found one. As far as I know, Sprite is an InteractiveObject and therefore should be dispatching all three of these events rather than only the MouseEvent.MOUSE_MOVE events.
Class Declaration:
import flash.display.*;
import flash.events.*;
import flash.geom.*;
public class CustomSprite extends Sprite {
Object Initialization in main.as
var circle:CustomSprite = new CustomSprite();
circle.graphics.lineStyle(3,0x00FF00);
circle.graphics.beginFill(0x0000FF,.5);
circle.graphics.drawCircle(0,0,50);
circle.graphics.endFill();
circle.x = 100;
circle.y = 100;
Event Listener Registration in Constructor:
addEventListener(MouseEvent.MOUSE_DOWN,mouseDownListener);
if (hasEventListener(MouseEvent.MOUSE_DOWN)) trace("MOUSE_DOWN listener exists");
addEventListener(MouseEvent.MOUSE_UP,mouseUpListener);
if (hasEventListener(MouseEvent.MOUSE_UP)) trace("MOUSE_UP listener exists");
addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveListener);
if (hasEventListener(MouseEvent.MOUSE_MOVE)) trace("MOUSE_MOVE listener exists");
Event Listener Registration Output:
MOUSE_DOWN listener exists
MOUSE_UP listener exists
MOUSE_MOVE listener exists
Listener Functions as Part of CustomSprite Class:
private function mouseDownListener(e:MouseEvent):void {
trace("mouseDownListener");
}
private function mouseUpListener(e:MouseEvent):void {
trace("mouseUpListener");
}
private function mouseMoveListener(e:MouseEvent):void {
trace("mouseMoveListener");
}
Output after hovering over object and clicking several times:
mouseMoveListener
mouseMoveListener
mouseMoveListener
mouseMoveListener
Thanks in advance for any help you can offer - it is greatly appreciated!
What is looks like from the source you have provided is that you aren't adding the event listeners to the circle itself. This snippet I tested worked, provided I don't have your CustomSprite, but just the Sprite.
var circle:CustomSprite = new CustomSprite();
circle.graphics.lineStyle(3,0x00FF00);
circle.graphics.beginFill(0x0000FF,.5);
circle.graphics.drawCircle(0,0,50);
circle.graphics.endFill();
circle.x = 100;
circle.y = 100;
circle.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{
trace("mouseDown");
});
circle.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void{
trace("mouseUp");
});
circle.addEventListener(MouseEvent.MOUSE_MOVE, function(event:MouseEvent):void{
trace("mouseMove");
});

referencing objects in different functions as3

I have an object in my mouse event functions that I want to reference in my time function.
Example, I basically created tiles and have mouse events:
var cell:MovieClip = new Tile();
cell.gotoAndStop(floor1[i][u]);
cell.x = ((u-i)*tileh)+365;
cell.y = ((u+i)*tileh/2)+70;
addChild(cell);
cell.addEventListener(MouseEvent.ROLL_OVER, mouseover);
cell.addEventListener(MouseEvent.ROLL_OUT, mouseout);
cell.addEventListener(MouseEvent.CLICK, mouseclick);
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener);
In the mouse events, I have something called event.currentTarget. Since I have tiles lined up with each other, I wanted to differentiate each individual tile. Thus creating that event.currentTarget. I wanted to use this in my time event, but it isn't recognizing event.currentTarget as an object, rather it's own timer. Is there any way to have the time function recognize the event.currentTarget from the mouse events?
Event.currentTarget is the last object to dispatch that specific event (and Event.target is the original object to dispatch the event). It can be absolutely anything that extends EventDispatcher.
The only way to do what you want is like this:
var currentTile:Tile;
cell.addEventListener(MouseEvent.ROLL_OVER, mouseEventsHandler);
cell.addEventListener(MouseEvent.ROLL_OUT, mouseEventsHandler);
cell.addEventListener(MouseEvent.CLICK, mouseEventsHandler);
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener);
function mouseEventsHandler( e:MouseEvent ):void {
this.currentTile = e.currentTarget as Tile;
}
function timeListener( e:TimerEvent ):void {
this.currentTile.blah.blah();
}
Basically you save the tile that most recently was interacted with into currentTile and then that is what you access in your timeListener.
You should really look through the LiveDocs to get a basic understanding of how events work and possibly look into how scope works as well.
Some explanation:
Your Event-Listener receives an Event-Object. Always. What kind of Event-Object it is depends on the Event. In your MouseListener you receive a MouseEvent, in you TimerListener a TimerEvent and so on.
EVERY Event-Object has two specific attributes.
event.currentTarget
is the Object, which binds the event listener (in your case "cell")
event.target
is the object, which "caused" the Event. If e.g. in you "cell"-MovieClip is another MovieClip called "nucleus" and you click on the the it, event.currentTarget would be "cell", but even.target would be "nucleus".
Since the event-object is a passed as a function parameter, it is destroyed, once the function is finished. If you wand to use parts of it in another function, you need to do it like this
var myCell:MovieClip;
function mouseClick(event:MouseEvent):void{
myCell = event.currentTarget as MovieClip;
}
function timeListener(event:TimerEvent):void{
if(myCell){
///what ever you want to do with it
myCell = null;
}
}
I hope I explained it clearly.
Here's one way you could do this :
enemyMoveTimer.addEventListener(TimerEvent.TIMER, timerListener(cell));
enemyMoveTimer.start();
public function timerListener(cell:MovieClip):Function
{
var doStuffToCell:Function = new Function(e:TimerEvent)
{
trace (cell.x + " : " + cell.y);
// do whatever you want with cell
}
return doStuffToCell;
}
I should note that I don't think it's a good idea to call your handler timerListener, as it's a handler.
Listeners do just that, they listen for an event. A handler, handles an event. The second parameter in the addEventListener method specifies a function to handle the event. Naming your handler timerListener is not a good idea in my opinion, as it's really not that.

ActionScript3, moving objects of type movieclip

Here i am trying to create a new movieclip type object, which is moved when function mvBall is called. When i run the code i get this err: implicit coercion of a value with static type object to a possibly unrelated type flash.display:MovieClip. Later on i want to be able to make the ball bounce back when it colides with another object. I'm new to action script and don't really know how things work so any help would be appreciated. Here's the code:
private function frame(x:Event):void {
var ball:MovieClip = new MovieClip();
ball.addEventListener(Event.ENTER_FRAME, animate);
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(100, 100, 15);
ball.graphics.endFill();
stage.addChild(ball);
}
private function animate(ev:Event):void {
mvBall(ev.target);
}
private function mvBall(mc:MovieClip) {
mc.x += 10;
}
You need to cast the target to MovieClip
private function animate(ev:Event):void {
mvBall(ev.target as MovieClip);
}
With that said it is better to just have one ENTER_FRAME handler and animate your objects in there.
stage.addEventListener(Event.ENTER_FRAME, animate);
private function animate(ev:Event):void
{
mvBall(myBall);
//other object animations
}
You are getting this error because the target property of the Event class is of type object.
In order to not throw the error, you need to cast it as a MovieClip:
mvBall(ev.target as MovieClip);
or
myBall(MovieClip(ev.target));
Something else to consider, is the difference between an Events target and currentTarget properties. If you ball had multiple layers/object inside it (sprites or other movieClips), the target would be whichever one of those sub-elements had the mouse over it during the click. currentTarget refers to the object that you've attached the listener to. In your case they may be the same (if your ball doesn't have any movie clips inside it), but your code could have unexpected results if you have sub-movieClips inside your ball.

Unable to listen for an event dispatched from an embedded swf

I have an as3 class with an embedded swf. I need the embedded swf to dispatch an event and have the as3 class action on that event. This used to work fine when the embedded swf was embedded and had been loaded as an external swf, however now that it's embedded the listener never picks up on the dispatched event.
I've created a simplified example below, the 'onMovieComplete' function is never called.
/* I have an external swf file 'movie.swf' with a simple animation in it.
* When the animation hits a frame (frame 70 in this case) it fires a
* Event.COMPLETE (using:- "this.dispatchEvent(new Event(Event.COMPLETE));" )
*/
package {
public class ExampleSwf extends MovieClip {
[Embed(source="movie.swf")] private var MovieSwf:Class;
private var movie:MovieClipAsset;
public function ExampleSwf() {
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, init);
this.movie = new MovieSwf();
this.addChild(this.movie);
this.movie.addEventListener(Event.COMPLETE, onMovieComplete);
}
private function onMovieComplete(e:Event):void {
var foo:String = "bar";
}
}
}
Does anyone know why the event dispatched from the embedded swf is never picked up by the listener?
Thanks :)
I managed to get this to work by using:
stage.dispatchEvent(new Event(Event.COMPLETE));
In my embedded movie.swf file, and then in my as3 class using:
this.movie.stage.addEventListener(Event.COMPLETE, onMovieComplete);
When you embed the movie, it will be ready by time you are creating the instance and add it to the stage. You do not need to listen for the COMPLETE event.

MouseUpEvent stops working while Dragging MovieClip

There is a mouseUpEvent listener attached to the stage in the main class, while dragging the movieClip the mouseUpEvent doesnot trigger the handler and the movieClip gets sticks to the mouse. While the item is being dragged and the mouse is moved away from the movieClip i.e somewhere not on the item but on the stage the mouseUp is detected.
Edit: Here is the scenario I am using a static (Singleton) class as a movieClip as a "DragManager". Whenever a movieClip has to be dragged it is passed to the DragManager and is added as a child, when a mouseUp from stage is detected another static function of dragManager is called to stop the drag and put the movieClip on the appropriate layer. Here is the static function in the DragManager which is called on MouseDown from variouslayers.
public static function startDragMethod(item:Item):void
{
instance.addChild(item); //This is the instance of the DragManager
var boundArea:Rectangle = new Rectangle(0,0,610,760);
item.startDrag(false,boundArea);
}
In the constructor of the main class I add the eventHandler for the MouseUpEvent
this.addEventListener(MouseEvent.MOUSE_UP,stageMouseUpHandler);
The MouseUpHandler in the main class
private function stageMouseUpHandler(event:MouseEvent):void
{
DragManager.itemMouseUpHandler(event);
}
If there is something wrong with technique please guide me, my goal is to implement drag drop between various layers and with as less coupling as possible.
Well there are many ways to get the task done. Put some condition at your static listener function or when the object is dragged.
like
public static function startDragMethod(item:Item):void
{
instance.addChild(item); //This is the instance of the DragManager
var boundArea:Rectangle = new Rectangle(0,0,610,760);
item.startDrag(false,boundArea);
check = true;
}
private function stageMouseUpHandler(event:MouseEvent):void
{
if(check==true)
{
DragManager.itemMouseUpHandler(event);
check = false;
}
}