views:

530

answers:

2

I am a beginner in Flash Actionscript 3.0 programming. I am trying to create smooth keyboard controls for player movement in a game.

I'm currently using addEventListener(KeyboardEvent.KEY_DOWN) listening for a keyboard key press and then within the handler function moving a graphic by adding a number to its .x or .y property.

This creates a slow, sluggish jerk at the beginning. I know there's a smoother, more responsive way to do this but have no idea where to begin. Any help would be appreciated!

A: 

Where are you placing the listener? Is it in the application, or in the sprite that is supposed to move? Does the sprite have the focus when you are pressing the key?

Also, in adding the event listener, are you using capture? That is, are you setting the 3rd argument to true, as in

addEventListener(KeyboardEvent.KEY_DOWN, yourHandler, true)

If you use capture, which is how you have to do it if the App itself is listening for the event, then you will get a certain amount of latency, and this latency will be greater the more complex the interface is. If those events have to work their way up a vast hierarchy, this could be noticeable. If there are many sprites, this can exacerbate the problem.

What you can do is have the sprite that has the focus dispatch a custom event which a controller class listens to for each sprite. The controller class will have a handler that moves the event.currentTarget however you plan to have it done.

Also read up about custom events and how to use the SystemManager to add and remove listeners dynamically: http://livedocs.adobe.com/flex/3/langref/index.html.

Robusto
+1  A: 

For smooth keys I would suggest using either a Timer or onEnterFrame to poll for keys often enough to get smooth controls. It will get the job done, but at a certain expense. If you've got the rest of the logic all fine, this should fit in ok:

var key:int = NaN;

stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress,false,0,true);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease,false,0,true);
this.addEventListener(Event.ENTER_FRAME,update,false,0,true);

function onKeyPress(event:KeyboardEvent):void {
    key = event.keyCode;
    event.stopPropagation();
}
function onKeyRelease(event:KeyboardEvent):void {
    key = NaN;
    event.stopPropagation();
}
function update(event:Event):void{
    if(key) trace(key);
}

I make sure the event doesn't bubble by stopping it's propagation, and it's set on the stage which should be the topmost level, event wise. Also I'm using the key only the key is down, otherwise I ignore it in the enterFrame handler.

HTH, George

George Profenza
Do this. To be clear, the problem with the questioner's version is, you're only moving when a key actually gets pressed, so it moves once when you first press the key, and then only moves further when the OS starts issuing repeated events due to the key being held down. You don't want the character to move *when* a key is pressed, you want it to move on frame updates *while* a key is pressed, so the movement should take place in an ENTER_FRAME handler, not a keypress handler.
fenomas