EaselJS 键盘输入问题

EaselJS keyboard input issue

我在使用 easelJS 时遇到问题,我有一个监听键盘输入的函数,但它不会根据我按下的键更新变量。我在不同的案例中放置了一个 console.log 并且它记录正常但由于某种原因它确实更新了变量。我想我可能不了解它是如何工作的。这是我的代码

            function handleKeyDown(event) {
                switch(event.keyCode) {
                    case 16:
                        sonicSpeed = 15;
                        sonicState = 2;
                        console.log("Shift Key Pressed");
                        break;
                    case 65:
                        sonicState = 1;
                        sonicDirectionXN = true;
                        break;
                    case 68:
                        sonicState = 1;
                        sonicDirectionXP = true;
                        break;
                    case 87:
                        sonicState = 1;
                        sonicDirectionYN = true;
                        break;
                    case 83:
                        sonicState = 1;
                        sonicDirectionYP = true;
                        break;
                }
            }

            if (sonicState == 0) {
                var sonic1 = new createjs.Sprite(spriteSheet1);
            }
            else if (sonicState == 1) {
                var sonic1 = new createjs.Sprite(spriteSheet2);
            }
            else if (sonicState == 2) {
                var sonic1 = new createjs.Sprite(spriteSheet3);
            }

我没有看到您的完整代码,但从外观上看,您遇到了 javascript 异步性质的问题。在您 运行 您的 if 语句之前,您的 handleKeyDown 逻辑没有时间完成,因此您得不到正确的结果。尝试直接在 handleKeyDown 侦听器中创建 Sprite 对象,而不是使其同步;

function handleKeyDown(event) {
    switch(event.keyCode) {
        case 16:
            sonicSpeed = 15;
            sonic1 = new createjs.Sprite(spriteSheet3);
            break;
        case 65:
            sonic1 = new createjs.Sprite(spriteSheet2);
            sonicDirectionXN = true;
            break;
        case 68:
            sonic1 = new createjs.Sprite(spriteSheet2);
            sonicDirectionXP = true;
            break;
        case 87:
            sonic1 = new createjs.Sprite(spriteSheet2);
            sonicDirectionYN = true;
            break;
        case 83:
            sonic1 = new createjs.Sprite(spriteSheet2);
            sonicDirectionYP = true;
            break;
        default: // This is my quess for your sonicstate === 0
            sonic1 = new createjs.Sprite(spriteSheet1);
    }
}

为什么它不起作用

问题是代码没有按照您认为的顺序执行。正如 Felix Kling 在您的 中指出的那样,您的 handleKeyDown 函数中的代码不会立即执行;它在按下某个键时执行。这是实际的执行顺序(假设浏览器没有优化):

  1. handleKeyDown 函数已创建(但未执行)。
  2. sonic1 精灵是根据 sonicState 的值创建的(此时始终为 0,因为 handleKeyDown 没有 运行)。
  3. 用户按下一个键。
  4. handleKeyDown 执行并更改 sonicState。没有其他事情发生,因为函数在 switch 语句之后结束。执行在函数结束时停止。

一种修复方法

您似乎在尝试根据按下的键更改动画序列。你应该能够用一个 SpriteSheet;像这样的东西:

var sonicSpriteSheet = new SpriteSheet({
    images: [myImage],             // You can also use multiple images.
    frames: {width:50, height:50}, // Substitue 50 with your actual frame size.
    animations: {
        sonicState0: [0, 9],       // These are the start and end frame numbers.
        sonicState1: [10, 19],     // Substitute with the actual frame numbers
        sonicState2: [20, 29]      // for your images.
    }
});

然后你可以使用gotoAndPlay来设置正在播放的动画。这允许您重复使用相同的精灵,而不是每次都创建一个新的精灵。

var sonic1 = new createjs.Sprite(sonicSpriteSheet);

function handleKeyDown(event) {
    var sonicState = sonic1.currentAnimation;
    switch(event.keyCode) {
        case 16:
            sonicSpeed = 15;
            sonicState = "sonicState2";
            console.log("Shift Key Pressed");
            break;
        case 65:
            sonicState = "sonicState1";
            sonicDirectionXN = true;
            break;
        case 68:
            sonicState = "sonicState1";
            sonicDirectionXP = true;
            break;
        case 87:
            sonicState = "sonicState1";
            sonicDirectionYN = true;
            break;
        case 83:
            sonicState = "sonicState1";
            sonicDirectionYP = true;
            break;
    }
    if (sonicState != sonic1.currentAnimation) {
        sonic1.gotoAndPlay(sonicState);
    }
}

由于 gotoAndPlay 函数 handleKeyDown 中,它会在您更改 sonicState 后执行。

编辑 - 另一种修复方法

如果您想为每个动画使用单独的 sprite,那么您需要在更改动画时删除旧的 sprite 并添加一个新的。

var sonic0 = new createjs.Sprite(spriteSheet0);
var sonic1 = new createjs.Sprite(spriteSheet1);
var sonic2 = new createjs.Sprite(spriteSheet2);
var sonicState = 0;
stage.addChild(sonic0);

function handleKeyDown(event) {
    var newSonicState = sonicState;
    switch(event.keyCode) {
        case 16:
            sonicSpeed = 15;
            newSonicState = 2;
            break;
        case 65:
            newSonicState = 1;
            sonicDirectionXN = true;
            break;
        case 68:
            newSonicState = 1;
            sonicDirectionXP = true;
            break;
        case 87:
            newSonicState = 1;
            sonicDirectionYN = true;
            break;
        case 83:
            newSonicState = 1;
            sonicDirectionYP = true;
            break;
    }

    if (newSonicState != sonicState) {
        // Remove the old sprite
        stage.removeChild(sonic0, sonic1, sonic2);

        // Add the new sprite
        switch (newSonicState) {
            case 0:
                stage.addChild(sonic0);
                break;
            case 1:
                stage.addChild(sonic1);
                break;
            case 2:
                stage.addChild(sonic2);
                break;
        }
    }
}