AS3 Keyboard Control
I've got an as3 function that controls a movie clip with the keyboard:
package {
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;
public class Main_Character_Two extends MovieClip
{
var vx:int;
var vy:int;
public function Main_Character_Two()
{
init();
}
function init():void
{
//initialize variables
vx = 0;
vy = 0;
//Add event listeners
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
}
else if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
}
else if (event.keyCode == Keyboard.UP)
{
vy = -5;
}
else if (event.keyCode == Keyboard.DOWN)
{
vy = 5;
}
}
function onKe开发者_如何学PythonyUp(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP)
{
vy = 0;
}
}
function onEnterFrame(event:Event):void
{
//Move the player
player.x += vx;
player.y += vy;
}
}
}
This works ok but the main problem is that when you press the right key (and hold it down) then press the left key, the character will move to the left but when you release the left key (with the right key still held down) the character just stops. How can I make it so the character starts moving to the right again in this situation (if Im still holding the right key after Ive released the left key)
Thanks
You could put your 'player' positioning code into an Event.ENTER_FRAME
loop and use KeyboardEvent.KEY_DOWN
and KeyboardEvent.KEY_UP
to set booleans and position the player in the loop like:
var leftIsPressed:Boolean = false; var rightIsPressed:Boolean = false; var upIsPressed:Boolean = false; var downIsPressed:Boolean = false; var speed:Number = 5; var vx:Number = 0; var vy:Number = 0; stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler); function keyDownHandler(e:KeyboardEvent):void { switch(e.keyCode) { case Keyboard.LEFT : leftIsPressed = true; break; case Keyboard.RIGHT : rightIsPressed = true; break; case Keyboard.UP : upIsPressed = true; break; case Keyboard.DOWN : downIsPressed = true; break; } } function keyUpHandler(e:KeyboardEvent):void { switch(e.keyCode) { case Keyboard.LEFT : leftIsPressed = false; break; case Keyboard.RIGHT : rightIsPressed = false; break; case Keyboard.UP : upIsPressed = false; break; case Keyboard.DOWN : downIsPressed = false; break; } } function enterFrameHandler(e:Event):void { vx = -int(leftIsPressed)*speed + int(rightIsPressed)*speed; vy = -int(upIsPressed)*speed + int(downIsPressed)*speed; player.x += vx; player.y += vy; }
[EDIT] Added a more detailed example.
Of course in this case, if both left and right keys are pressed, this would result in a 0
offset.
You can listen to KeyboardEvent.KEY_UP
to determine when a key has been released, so you can track which keys are being held.
The KeyboardEvent.KEY_DOWN
event is only fired when a key goes from being in the "up" state to being in the "down" state, so your character stops after you lift your finger from the LEFT key because no new KEY_DOWN
event has been triggered that would cause the character to move.
You might be able to accomplish what you're after by adding a KeyboardEvent.KEY_UP
event that checks to see if any of the other arrow keys are being held down when the event fires, but you'd probably need to refactor your current code to avoid repeating yourself.
Understanding this phenomenon requires a basic understanding of the Event model, which keyboard input is based upon. It works differently in AS3 than it does in AS2.
When you press a key, an event is fired to call a function - but it is only fired once, when the key is pressed. The event handlers don't check whether the key is held down. (Try adding 5 to your object's x/y value instead of your vx in your onKeyDown function; you'll find that your character only moves when you press a key, not while you hold it.)
Similarly, when you released a key, an event is fired to call a function - but it is only fired once, when the key is actively released. No events are fired when the key is just sitting there.
Building upon this...can you find the source of your current problem?
function onKeyUp(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
}
else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP)
{
vy = 0;
}
}
If you didn't find it, it's this block.
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
}
This statement tells your program to set velocity equal to zero if either the right or the left keys are pressed. However, since Flash only checks for a keypress when you first press the key, holding down a key will not trigger your onKeyDown function. Hence, if you hold both left and right, and let one go, you're setting your velocity to zero.
Corey has the logical solution here, and there are some other reasons that you'll want to use a toggled boolean value to check keyboard input (the main reason is that you won't get any repeat delay).
I hope this answer cleared it up for you a little - a little knowledge can lead to great things. Good luck.
精彩评论