Почему это не работает
Проблема заключается в том, что код не выполняется в порядке, вы думаете, что это. Как указал Феликс Клинг в вашем other question, код внутри вашей функции handleKeyDown
не выполняется немедленно; он выполняется при нажатии клавиши. Вот фактический порядок выполнения (при отсутствии оптимизации браузером):
handleKeyDown
Функция создана (но НЕ выполнена).
sonic1
sprite создается на основе значения sonicState
(что является ВСЕГДА 0 на данный момент, так как handleKeyDown
не запущен).
- Пользователь нажимает клавишу.
handleKeyDown
выполняет и изменяет sonicState
. Ничего другого не происходит, потому что функция заканчивается после инструкции switch
. Выполнение останавливается в конце функции.
Один из способов исправить это
Похоже, что вы пытаетесь изменить последовательность анимации на основе ключа, которая была нажата. Вы должны сделать это с помощью одного SpriteSheet
; Somthing так:
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.
Edit - Другой способ это исправить
Если вы хотите использовать отдельные спрайты для каждой анимации, то вам нужно удалить старый спрайт и добавить новый, когда вы изменяете анимацию.
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;
}
}
}
Есть ли причина, по которой ваше условие 'if (sonicState == 0)' находится за пределами функции? –
Да, это только начало кода, и я хочу, чтобы он обновлял будущее движение только с помощью тикера, иначе я бы разместил его внутри функции – Jeff
Хорошо. Похоже, у вас есть какая-то проблема с областью, хотя мне нужно больше узнать о вашем коде, прежде чем я смогу предложить правильное решение. –