Click to See Complete Forum and Search --> : [F9] EnterFrame Keys
mr_malee
07-10-2006, 03:16 AM
just wondering how to detect keyPresses on a EnterFrame function not a KeyboardEvent, this doesn't work anymore:
Key.isDown(Key.RIGHT)
i've imported flash.ui.Keyboard and tried getting the key presses like this:
var key:Keyboard = new Keyboard()
if(key.RIGHT){
//do something
}
but it don't work. Can't seem to find a solution within the reference because it only deals with KeyboardEvents.
Any help?
tonypa
07-10-2006, 05:07 AM
From ActionScript 2.0 Migration table:
http://livedocs.macromedia.com/flex/2/langref/migration.html
Key class isDown() and isToggled() methods are removed for security reasons. You must use KeyboardEvent.
Fall_X
07-10-2006, 05:17 AM
You can, however, mimic Key.isDown yourself.
Use keyboard events to fill up an array with the keycode as indexes. Set these values to true when the key is pressed, otherwise set them to false. Then create a function isDown in the same class, and make it check the array.
You could try using static functions to mimic it completely, but I'm not sure how/if you could add event listeners without creating an instance. Might be simple, but can't test it at the moment.
Can you have a static constructor (or whatever) to do things like this on a class-level?
mr_malee
07-10-2006, 05:21 AM
man, something that was so easy to do has now become (not really hard) but painfull.
:sigh:
thanks again
Fall_X
07-10-2006, 05:23 AM
It's not that hard, you can probably knock up a replacement in 10 minutes or less, and then reuse it in other projects.
Fall_X
07-10-2006, 05:40 AM
Here's something you can use to get you started. I haven't tested it, I coded in notepad, because I don't have access to flash at the moment.
package {
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.KeyboardEvent;
class MyKey
{
private static var downArray:Array=[];
private static var pressedArray:Array=[];
private static var stg:Stage;
public static function set stage(value:Stage) {
if(stg) {
stg.removeEventListener(KeyboardEvent.KEY_DOWN,key DownHandler);
stg.removeEventListener(KeyboardEvent.KEY_UP,keyUp Handler);
}
stg=value;
stg.addEventListener(KeyboardEvent.KEY_DOWN,keyDow nHandler,false,0,true);
stg.addEventListener(KeyboardEvent.KEY_UP,keyUpHan dler,false,0,true);
}
public static function isDown(keyCode:int):Boolean {
// can't just return downArray[int] because it can be undefined or null,
// and we want to return a boolean
if(downArray[keyCode]) {
return true;
}
return false;
}
public static function isPressed(keyCode:int):Boolean {
// this one will only return true once per key
// which is handy in some cases, when you don't want to repeat an action
// if the key stays pressed
if(pressedArray[keyCode]) {
delete pressedArray[keyCode];
return true;
}
return false;
}
private static function keyDownHandler(event:KeyboardEvent):void {
downArray[event.keyCode as int]=true;
pressedArray[event.keyCode as int]=true;
}
private static function keyUpHandler(event:KeyboardEvent):void {
delete downArray[event.keyCode];
delete pressedArray[event.keyCode];
}
}
}
Fall_X
07-22-2006, 05:49 PM
I updated the code above to something that actually works, lol. You'll have to set the static variable "stage" to the current stage in order to make it work - ie :
MyKey.stage=this.stage; // needed only once
if(MyKey.isDown(38)) {
trace("up");
}
I wish there was some way to get the stage reference automatically, but I doubt there is.
Edit : but setting MyKey.stage is something you have to do only once in your project, so it's not that big a deal.
tonypa
08-08-2006, 07:16 AM
Moved to AS3 forum.
WarpZone
08-24-2007, 11:14 AM
Okay, I noticed this thread but I can't get it to work.
I'm using Fall_X's first post as an AS file called "MyKey.AS," and I'm tyring to put his second post into my flash's main timeline. It's not working.
Also, why is the instance name the same as the class name? Both are called MyKey. I thought that was bad. I tried changing the instance name to something else (I briefly considered myMyKey :P ) , like this:
import MyKey;
var keyDownListener:MyKey = new MyKey()
keyDownListener.stage=this.stage; // needed only once
if(keyDownListener.isDown(38)) {
trace("up");
}
in my main timeline, but it's still not working. :( MyKey.as currently resides in the same directory as my fla file. If this is wrong, please explain how to fully set up a test case that uses your new MyKey class, including which file each block ot text goes in and the whole body of the test case text, because obviously I don't know what the heck I'm doing when it comes to OOP.
Thanks in advance. :/
WarpZone
08-26-2007, 04:09 AM
Okay, for the record, I was finally able to get it working. Here's my solution, a FULL example with results you can SEE.
I think my main mistake was that I didn't understand how AS files tie in to the main FLA. I'm still kinda confused, but this is what works:
Enter the following code into an AS file called Key.as:
I used senocular's custom key class for this:
// Key.as
package {
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
/**
* The Key class recreates functionality of
* Key.isDown of ActionScript 1 and 2. Before using
* Key.isDown, you first need to initialize the
* Key class with a reference to the stage using
* its Key.initialize() method. For key
* codes use the flash.ui.Keyboard class.
*
* Usage:
* Key.initialize(stage);
* if (Key.isDown(Keyboard.LEFT)) {
* // Left key is being pressed
* }
*/
public class Key {
private static var initialized:Boolean = false; // marks whether or not the class has been initialized
private static var keysDown:Object = new Object(); // stores key codes of all keys pressed
/**
* Initializes the key class creating assigning event
* handlers to capture necessary key events from the stage
*/
public static function initialize(stage:Stage) {
if (!initialized) {
// assign listeners for key presses and deactivation of the player
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.DEACTIVATE, clearKeys);
// mark initialization as true so redundant
// calls do not reassign the event handlers
initialized = true;
}
}
/**
* Returns true or false if the key represented by the
* keyCode passed is being pressed
*/
public static function isDown(keyCode:uint):Boolean {
if (!initialized) {
// throw an error if isDown is used
// prior to Key class initialization
throw new Error("Key class has yet been initialized.");
}
return Boolean(keyCode in keysDown);
}
/**
* Event handler for capturing keys being pressed
*/
private static function keyPressed(event:KeyboardEvent):void {
// create a property in keysDown with the name of the keyCode
keysDown[event.keyCode] = true;
}
/**
* Event handler for capturing keys being released
*/
private static function keyReleased(event:KeyboardEvent):void {
if (event.keyCode in keysDown) {
// delete the property in keysDown if it exists
delete keysDown[event.keyCode];
}
}
/**
* Event handler for Flash Player deactivation
*/
private static function clearKeys(event:Event):void {
// clear all keys in keysDown since the player cannot
// detect keys being pressed or released when not focused
keysDown = new Object();
}
}
}
Next, enter the code below into the main timeline of your FLA, and save both the FLA and the AS file to the same folder.
(Note: The timer is set up to fire 50 times per second, so you may want to set your FLA's FPS to 50 before you run this code. I think it will still work at a lower frame rate, but I haven't experimented with it yet!)
// Initialize main game timer
var gameTimer:Timer = new Timer(20);//20 ms = 1/50 second!
gameTimer.addEventListener(TimerEvent.TIMER, gameMainLoop);
gameTimer.start();
//Main game loop
function gameMainLoop(event:TimerEvent):void {
var timer:Number = event.target.currentCount;//Saves us from having to type this every time we want to know the current time.
Key.initialize(stage);
if (Key.isDown(Keyboard.LEFT)) {
// Left key is being pressed
trace("LEFT");
}
//trace("tick");
}
Now just run the FLA, and hit the left arrow key. You should get lots of traced messages.
What I find weird is, you don't have to do a var MyKey:Key=New Key or anything like that. You also don't need to include or import your AS file in order to be able to access the class from within your flash file. All the other examples I've ever seen about using a custom class involved importing and including the AS files, in order to gain access to the class. Oh well, I'm sure I'll figure it out eventually.
flashkit.com
Copyright WebMediaBrands Inc., All Rights Reserved.