0

キーがダウン状態とアップ状態の間で切り替わったことを検出できるようにしようとしています。UP状態に戻る前に、キーが1フレーム離されたことを表示する必要があります。

必要に応じて、さらに情報やコードを追加できます。前もって感謝します。

package engine 
{
import flash.display.Stage;
import flash.events.KeyboardEvent;


/**
 *  Input Manager
 */
public class Input 
{
    static private const UP         : uint = 0;
    static private const PRESS      : uint = 1;
    static private const HELD       : uint = 2;
    static private const END_PRESS  : uint = 3;

    static private const START_PRESS:uint = 9999;


    static private var keys     : Vector.<uint>;
    static private var active   : Vector.<KeyState>;



    static public function init( stage:Stage ):void 
    {
        stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
        stage.removeEventListener( KeyboardEvent.KEY_UP,   onKeyUp );   

        keys    = new Vector.<uint>(255);   // state of all keys
        active  = new Vector.<KeyState>();      // only keys in a state other than up
        //time    = new Vector.<Time>();

        stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
        stage.addEventListener( KeyboardEvent.KEY_UP,   onKeyUp );  
    }


    /// Flash Event: A key was just pressed
    static public function onKeyDown( e:KeyboardEvent ):void
    {
        // If the system is sending another key down event, but the key is marked
        // as being in some other state than down; ignore it.
        if ( keys[ e.keyCode ] != UP )
            return;

        keys[ e.keyCode ] = START_PRESS;

        var keyState:KeyState = new KeyState( e.keyCode, Time.frameCount );
        active.push( keyState );
    }

    /// Flash Event: A key was raised
    static public function onKeyUp( e:KeyboardEvent ):void
    {

        keys[ e.keyCode ] = UP

        // Loop through all active keys; there is a slight chance that
        // more than one entry for a key being "down" snuck in due to
        // how Flash / OS handles input.
        var keyState:KeyState;
        for ( var i:int = active.length - 1; i > -1; i-- )
        {

            keyState = active[i];               // get next keystate in active list
            if ( keyState.code == e.keyCode )   // if the code matches
                active.splice( i, 1 );          // remove
        }
    }

    /// Call this once per frame
    static public function update():void
    {
        var code    :uint;
        var keyState:KeyState;

        // Go through all the inputs currently mark as being active...
        for ( var i:int = active.length - 1; i > -1; i-- )
        {
            keyState = active[i];
            code = keyState.code;

            // If a key is pressed and it's the frame after it was pressed,
            // change the state.
            if ( keys[code] == PRESS && keyState.frame < Time.frameCount )
            {
                keys[code] = HELD;
                continue;
            }

            // If a press is just starting, mark it as started and update
            // the frame for the press to be this frame.
            if ( keys[code] == START_PRESS )
            {
                keys[code] = PRESS;
                keyState.frame = Time.frameCount;
            }

        }

    }

    /// Has a key just been pressed in this frame?
    static public function getKeyDown( code:uint ):Boolean
    {
        return keys[ code ] == PRESS;
    }

    /// Is a key in state other than being "up"?
    static public function getKey( code:uint ):Boolean
    {
        return keys[ code ] == HELD;
    }

    static public function getKeyRelease( code:uint ):Boolean
    {
        return keys[ code ] == END_PRESS;
    }
}
}


internal class KeyState
{
public var code :uint;
public var frame:uint;

/// CTOR
function KeyState( code:uint, frame:uint ) :void
{
    this.code   = code;
    this.frame  = frame;
}
}
4

1 に答える 1

0

フレーム内で何かを実行したいので、 Event.ENTER_FRAME リスナーを使用する必要があります。このようにして、「離したばかり」のキーを「アップ」状態に正しくリセットできます。この場合、次のようにします。

static public function onKeyUp( e:KeyboardEvent ):void
{
    keys[ e.keyCode ] = END_PRESS;
    // I'm not sure why you need other checks in here, add them if you like
}

static public function onEnterFrame( e:Event ):void
{
    for (var i:int=keys.length-1; i>=0;i--) if (keys[i]==END_PRESS) {
        keys[i]=UP;
        // do whatever you need with i'th key, as this will be the "just released" key.
    }
}

更新: 既に基本的なエンター フレーム手順があり、押した状態と保持状態に関するメカニズムの一部が既にあるため、このサイクルをその手順に簡単に追加できます。

于 2012-10-06T05:20:39.490 に答える