Attaching Event Handlers to Dynamic Clips


As I have already mentioned, we can use function reference properties to assign event handler scripts to dynamically attached clips. Table 4.1 is a complete list of the event handlers that can be attached to a dynamic clip instance.

 
Table 4.1: Dynamic Event Handlers

Property

Description

MovieClip.onData

Called when you load data into a clip and it finishes loading

MovieClip.onKeyDown

Called when the user presses a key on the keyboard and MovieClip has focus

MovieClip.onEnterFrame

Called once each frame that the clip exists on the stage

MovieClip.onLoad

Called when the clip is first loaded onto the stage

MovieClip.onUnload

Called when the clip is unloaded from the stage

qMovieClip.onMouseDown

Called when the mouse button is pressed anywhere on the stage

MovieClip.onMouseUp

Called when the mouse button is released anywhere on the stage

MovieClip.onMouseMove

Called when the mouse was moved since the last frame

MovieClip.onPress

Called when the mouse button is pressed and the mouse pointer is over the clip

MovieClip.onRelease

Called when the mouse button is released and the mouse pointer is over the clip

MovieClip.onReleaseOutside

Called when the mouse button is pressed over the clip and then released outside the clip

MovieClip.onDragOut

Called when the user's mouse is clicked on the clip and then dragged out without releasing

MovieClip.onDragOver

Called when the user's mouse is clicked outside the clip and then dragged over without releasing

MovieClip.onRollOut

Called when the mouse button is not pressed and the mouse pointer moves from over the clip to elsewhere

MovieClip.onRollOver

Called when the mouse button is not pressed and the mouse pointer moves from elsewhere to over the clip

MovieClip.onKeyUp

Called when the user releases a key on the keyboard and MovieClip has focus

MovieClip.onKillFocus

Called when focus is removed from the clip

MovieClip.onSetFocus

Called when the clip is given focus

As you can probably tell by the names , these handlers match up with the ones used on author-time instantiated clips. In fact, every handler that you can attach to an author-time clip is duplicated by one of the dynamic handlers in Table 4.1. Additionally, some dynamic handlers have no duplicate for author-time clips, which allows us more flexibility by using the dynamic handlers. That, plus the fact that we can consolidate our script with them, makes these handlers very nice indeed. Before we look at some of the handlers in detail, we need to talk about the scoping rules in Flash again.

Scoping Rules for Dynamic Event Handlers

Defining our event handlers for dynamic clips in frame 1 of the main timeline is a useful technique. It will save us a great deal of time and confusion when our games become complicated. However, it does introduce one additional complexity to our lives: the scope rules. Here's how the scope rules work.

The scope of a function is defined to be the timeline that the function is defined in. That means that the clip to which the function is attached does not define the scope of a function. As an example, declare a variable inside a function that is attached to an event handler of a movie clip; the variable will exist in the main timeline and not in the clip to which the function is attached. This means that the use of the this reference is required when attaching event handlers dynamically. We can no longer assume that a property such as _xscale will automatically refer to the _xscale of the clip we want. Instead, we must explicitly use the this keyword; otherwise , Flash will think we are talking about the _xscale property of the main timeline.

This can be confusing and takes some getting used to. The reason things are this complex has to do with backward compatibility with older versions of Flash. The result is that you must be careful when attaching event handlers dynamically that you define your functions to refer to the correct clip. This is generally accomplished with the this reference.

If this doesn't completely make sense, don't worry about it. In the next section, we'll see our first example, and I'll explain this scoping concept again then.

The onEnterFrame Handler

This one is easy. You've already seen it many times. The onEnterFrame handler is called once every frame that the clip exists on the stage. Let's look at a simple example:

 attachMovie("ball"," ball1", 1); ball1.onEnterFrame = function(){     this._xscale += this.change++; } 

We are simply treating the onEnterFrame property of the ball1 instance as a function reference and assigning it the value of some function we define. But notice that we are using the this keyword to refer to the _xscale property and the change variable. That's required now because if we don't explicitly refer to this, Flash assumes we mean the local scope of the function, which is the timeline that the function was defined on. In this case, that would be the main timeline. If we didn't explicitly use the this keyword in this example, the main movie would be scaled up instead of the ball clip.

If we wanted to give the same handler to several different clips, we could define the function once and assign it multiple times. The following is an example of one way to do this:

 attachMovie("ball"," ball1", 1); attachMovie("ball"," ball2", 2); ball2._y += 100; function ballEnterFrameFunction (){     this._xscale += this.change++; } ball1.onEnterFrame = ballEnterFrameFunction; ball2.onEnterFrame = ballEnterFrameFunction; 

The output can be seen in Figure 4.6.

click to expand
Figure 4.6: You can define a function once and then attach it to multiple clips. Because the clips use the this keyword, each is affected by its own handler.

In this code, we first create two new ball instances and then shift the second one down a bit. We then define a function called ballEnterFrameFunction . This function is assigned to the onEnterFrame property of both ball clips. Notice also that in the body of the function, the this reference is used when scaling the clip up. That way, each ball scales itself up in its own onEnterFrame handler. Let's see an example of another way to do the same thing:

 attachMovie("ball"," ball1", 1); attachMovie("ball"," ball2", 2); ball2._y += 100; ball1.onEnterFrame = function(){     this._xscale += this.change++; } ball2.onEnterFrame = ball1.onEnterFrame; 
Note  

Notice that when we are referring to a function (to assign it to a handler like onEnterFrame = foo; ), we do not use the parentheses when calling it. If we want to invoke (call) the function, we use the parentheses.

Notice that everything is the same except that instead of using the temporary reference ballEnterFrameFunction , we simply defined the function when we attached it to ball1 . To get a copy for ball2 , we assigned the function from ball1 's copy.

In general, I prefer the first method. That's because sometimes ball1 might have been removed when it's time to create ball32 . If we try to assign ball32 's onEnterFrame handler from the handler of a clip that has been removed, ball32 receives an empty handler and we have a problem. For that reason, I generally define an event handler that will be common to more than one clip by using a temporary function reference with a well- chosen name , such as ballEnterFrameFunction .

Caution  

You can create a function without using a name (an anonymous function), but you must always maintain a reference to it. If you name a function, as in function foo(){}, you can always refer to it with its name foo .

The onLoad Handler

You might find this amusing, but at this point, the onLoad handler does absolutely nothing for us. This is where the comedy comes in. The reason is that by the time we have attached a clip and are ready to set its onLoad property to some function, the clip has already been loaded. In other words, by the time we define the onLoad event, the load has already been done. Funny, eh?

In the future when we start working with prototypes , they will allow us to create a kind of template clip from which all others will be created. When we do this, the onLoad will work because it will be known to Flash before the clip is attached.

The onUnload Handler

Unlike onLoad , the onUnload handler can be of some current use to us. As you might suspect, this handler is called whenever its clip is removed from the stage, either directly through a removeMovieClip call, or implicitly through having its parent removed. The onUnload handler is generally used to clean up anything that needs to be cleaned when a clip is removed. I don't often have a use for this handler, but occasionally it comes in handy.

Tip  

You can also use the onUnload handler on a manually instantiated clip (dragged from library to stage). If you have a keyframe in which the clip that has onUnload attached leaves the stage, the handler will be called.

The onData Handler

One of the great things that Flash allows us to do is to load data on the fly. We can get our movies to do a great many things in terms of communicating data between the user's computer and the Web server that is hosting our games. We'll see both of these in action in later chapters in the form of the loadVariables and loadMovie functions. The problem that arises with this technique is that when you load data from the server, it often takes many frames for the data to load. You won't be able to display or use the data until it's loaded, which means that your movie will be many frames past the load function when it finally finishes loading. To get around this, Flash will communicate the completion of a load through the onData event. If the movie clip you are loading into has an onData event handler defined, it will be run. That way you won't try to use a movie clip that is being loaded into before the load has completed. We'll see examples of this in future chapters.

The Mouse Handlers

This set of handlers is responsible for dealing with mouse events. Mouse handlers are called when the mouse performs an action, such and clicking or moving. The important thing to realize is that these handlers are different from the handlers such as onPress and onRelease , which are discussed later. Those handlers are only called when the mouse does something above them. But these three mouse handlers ” onMouseUp , onMouseDown , and onMouseMove ”are called no matter where the mouse is and they are designed to trap all mouse events. If you have a movie clip, and it needs to react to the mouse regardless of where the mouse is located on the stage, the mouse handlers are the handlers for you. Let's take a look at them individually.

The onMouseDown Handler

As you might expect from the name, this event handler is called when the mouse button is pressed down anywhere on the stage. It works like any other event handler; you simply attach a function to it after the clip has been instantiated (attached), and Flash takes care of the rest. We used this handler in Chapter 3, but let's look at another example here:

 attachMovie("ball"," ball",1); ball.onMouseDown = function(){     trace("mouse button was pressed, its location at that time was:");     trace(_root._xmouse + "," + _root._ymouse); } 

If you test this script, you'll see, as in Figure 4.7, that it prints each time the user presses down on the mouse, giving the current position of the mouse at the time. If you press and hold the mouse button, you might notice that the message is output when the button goes down, which leads us to our next handler, which does the opposite .

click to expand
Figure 4.7: The onMouseDown handler is called whenever the user clicks the mouse, no matter where on the stage the mouse is located.

The onMouseUp Handler

In contrast to our previous handler, the onMouseUp handler is called when the mouse button is released . It is often more convenient to know when the button is released rather than when it is pressed. For example, you might be creating a game in which the user presses the mouse down and moves it. When the user releases the mouse button, the distance from the original location is used as some factor in the result ”perhaps the velocity of some projectile. In this case, you would use both handlers to test for the down event and the up event. An example follows :

 attachMovie("ball"," ball",1); ball.onMouseUp = function(){     trace("mouse button was released, its location at that time was:");     trace(_root._xmouse + "," + _root._ymouse); } 

The output of this example can be seen in Figure 4.8.

click to expand
Figure 4.8: The onMouseUp handler is called whenever the user releases the mouse, regardless of where on the stage the mouse is located.

Again, if you test the movie and then press and hold the button, you should notice that the message is not printed. After you release the button, it will be.

The onMouseMove Handler

The final handler in this group is onMouseMove . As its name implies, this handler is called whenever the mouse has changed position since the last frame. You might be thinking, "That sounds like it'll happen quite often," and you would be correct. When you set up the onMouseMove handler, it will be getting called more often than not. Because of that, it's not the most commonly used handler, but it does have some application from time to time. Let's have a look at it in action. Notice how often the code is called as you test the following script. Compare your results with Figure 4.9.

click to expand
Figure 4.9: The onMouseMove handler is called whenever the user moves the mouse, regardless of how far it moved, where it is located on the stage, or if the mouse buttons are up or down.
 attachMovie("ball"," ball",1); ball.onMouseMove = function(){     trace("mouse moved again! ("+ _root._xmouse + "," + _root._ymouse+")"); } 

At this point, we've discussed many of the handlers in Table 4.1. We're next going to talk about the set of handlers that have to do with buttons. That will leave out a few handlers, including the focus and keyboard handlers. Those will be discussed later in the book on a need-to-use basis.




Macromedia Flash MX 2004 Game Programming
Macromedia Flash MX 2004 Game Programming (Premier Press Game Development)
ISBN: 1592000363
EAN: 2147483647
Year: 2004
Pages: 161

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net