我在使用easylJS时遇到问题,我有一个监听键盘输入的函数,但它不会根据我击中的键来更新变量。我在不同情况下放置了一个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);
            }

最佳答案

为什么不起作用

问题在于代码未按照您认为的顺序执行。正如Felix Kling在您的other question中指出的那样,handleKeyDown函数中的代码不会立即执行。按下键时执行。这是实际的执行顺序(假设浏览器未进行任何优化):


handleKeyDown函数已创建(但未执行)。
sonic1 sprite是根据sonicState的值创建的(由于handleKeyDown尚未运行,因此此时始终为0)。
用户按下一个键。
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设置正在播放的动画。这使您可以重复使用相同的Sprite,而不是每次都创建一个新的Sprite。

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


由于gotoAndPlayhandleKeyDown函数内部,因此它将在更改sonicState之后执行。

编辑-修复它的另一种方法

如果要为每个动画使用单独的精灵,则需要在更改动画时删除旧的精灵并添加一个新的精灵。

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

10-06 08:15