Before getting to the specific key handling for the game, let's first talk about how to generally handle keyboard input within Director. Loosely speaking, there are three ways to monitor the keyboard from Lingo: primary event handlers, behaviors attached to sprites, and the behaviors that are attached to frames. Let's first look at behaviors attached to either sprites or to a frame, and the events you can use within them.
The reason we're starting with behaviors is because of Director's event hierarchy. Normally, behaviors attached to sprites will receive an event first, followed by behaviors attached to frames, and then any handlers within movie scripts. However, this can be overridden using a primary event handler, as you will see in the next section.
There are several handlers and methods with which you can determine what key, or keys, are being pressed. Whenever a key is pressed Director sends a keyDown event. When a key is released, a keyUp event is generated. If you have handlers in place, the events will be captured. Otherwise they will travel down the hierarchy until they are captured or they fall through the bottom.
Assuming there is a handler in place to capture the event, you still need a way to determine which actual key is being pressed. For this, Director offers several different methods; which one you use will depend on your need.
Examine the following code example:
on keyDown me trace(_key.key) trace(_key.keyCode) trace(_key.keyPressed()) end
Here, whenever a key is pressed, three pieces of data will be traced out to the Message window. Note that all three items are based on Director's new Key object, which is accessed from the _key property.
_key.key This property returns the ANSI (American National Standards Institute) value assigned to the key.
_key.keyCode This property returns the numerical value of the key, not the ANSI value.
_key.keyPressed() This method is unique in how it works, which makes it particularly suited for our needs. Using the method as shown here will result in the ANSI value of the key being traced. But you can also use keyPressed() to determine if a particular key is being pressed by giving the method the key code of the key. As an example, look at the following:
on keyDown me trace(_key.keyPressed(124)) end
In this form, the keyPressed() method will return either true or false, indicating whether the particular key (124 is the right arrow key) is being pressed. Don't worry about how to get the codes to use. In the next part of this lesson you will create a small tool MIAW that you can use to find keyboard key data.
Using the keyPressed() method is a great way to find out if a particular key is being depressed, but using it as shown will only allow you to check if a single key is being pressed. This is because the method is placed within a keyDown handler, which is only executed when a key is pressed. In some applications, especially games, you will want to see if multiple keys are being pressed at one time. This can be done by getting rid of the keyDown handler, and placing the keyPressed() method within an enterFrame or exitFrame handler instead. This is exactly what you will do later in this lesson, when you add the player's ship to the game.
One limitation of trying to handle keyboard input within a sprite script is that only field and text sprites are able to process key events. Trying to enter text into a bitmap sprite doesn't really make sense, so Director won't process key handlers within behaviors attached to other kinds of sprites. This can be remedied by placing the key-handling Lingo within a frame behavior, or by using a primary event handler if you only need to check for single key presses.
Using Primary Event Handlers
Normally, Director's event hierarchy dictates the path an event takes through the system starting at the sprite level and then going to the member, the frame and on down to the movie script level. When an event handler for the event is found, the event is handled, and it stops. However, by defining a primary event handler, you are able to essentially re-order the hierarchy so that a key or mouse press is trapped by the primary event handler first, before any other handlers have a chance to catch it. And unlike typical event handlers that stop an event after handling it, a primary event handler will handle the event and then pass it on, placing it back into the regular hierarchy. Using a primary event handler is a good way to allow specific keys to be checked for immediately and everywhere within your movie. For instance, checking for quit, or something that needs to be available at all times such as a help panel, can easily be handled by using a primary event handler. Let's see firsthand how a primary event handler works.
Handling Special Keys
You might have noticed while running the primary event handler test movie that no key code appeared in the Message window when you pressed keys such as Shift or Ctrl/Command. You didn't notice? Trust methey didn't appear. This is because these are modifiers for the rest of keys on the keyboard and as such they don't have their own key codesnone that are available for our use, anyway.
In order to know if the user is pressing these special keys you need to use the following properties of the Key object:
_key.shiftDown returns true if Shift is being pressed.
_key.optionDown returns true when Alt is pressed in Windows, or Option is pressed on the Macintosh. In Windows this will only return true if another key in addition to Alt is pressed.
_key.commandDown returns true when the Ctrl key is pressed in Windows, or the Command key is pressed on the Macintosh.
_key.controlDown Similar to commandDown, but in Windows only. It's best to just ignore controlDown and use commandDown, as it works cross platform.
To test for these keys you use the same method as for the regular keys. Because these keys don't create a keyDown event when pressed, you can use the keyDown handler to test for key combinations like Ctrl+P and others. For instance, the following code placed in a keyDown handler would run the doPrint() handler whenever the Ctrl+P key combo was pressed:
on keyDown me if _key.commandDown and _key.key = "p" then doPrint() end if end
There is one small issue you should be aware of. Within the authoring environment Director itself will receive Ctrl/Command and Alt/Option key presses and not let them through to Lingo. This is only when in authoring, though; you can rely on these methods to work in a projector.
In order to make use of keys like the arrow keys, backspace, etc., you will need to use their key code values. To make it quick and easy to get these values many developers create a small utility tool that can be accessed at anytime when in Director.