简体   繁体   中英

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 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;
        }
    }
    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.

您可以侦听KeyboardEvent.KEY_UP来确定何时释放键,因此可以跟踪哪些键被保留。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM