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
函数中的代码不会立即执行;它在按下某个键时执行。这是实际的执行顺序(假设浏览器没有优化):
handleKeyDown
函数已创建(但未执行)。
sonic1
精灵是根据 sonicState
的值创建的(此时始终为 0,因为 handleKeyDown
没有 运行)。
- 用户按下一个键。
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;
}
}
}
我在使用 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
函数中的代码不会立即执行;它在按下某个键时执行。这是实际的执行顺序(假设浏览器没有优化):
handleKeyDown
函数已创建(但未执行)。sonic1
精灵是根据sonicState
的值创建的(此时始终为 0,因为handleKeyDown
没有 运行)。- 用户按下一个键。
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;
}
}
}