Matriz defectuosa para voltear (reflejo de espejo) un MovieClip
-
05-07-2019 - |
Pregunta
Actualmente estoy trabajando en un pequeño y agradable motor de juego 2D en AS3. Incluso puede cargar diferentes clips de películas flash a través de XML para las diferentes animaciones. Una de las funciones también le permite voltear una animación cuando realiza una determinada acción. De esa manera, podría tener 1 animación para la izquierda y la derecha (como de costumbre). Tengo la transformación de la matriz funcionando correctamente; Sin embargo, creo que mi lógica para mover las cosas de un lado a otro es incorrecta. El resultado es que la animación incorrecta se reproducirá en el momento equivocado. Decidí hacer que la animación se reprodujera en función de la velocidad del objeto en movimiento en lugar de la pulsación de teclas, ya que tengo elementos físicos involucrados.
Aquí hay un enlace al juego en su estado actual: http://parrisstudios.com/Game_Design/ gameEngineDemo /
El problema principal es que las animaciones se reproducen en momentos incorrectos o no se reproducen cuando deberían.
Aquí está mi código para voltear (déjame saber lo que piensan): ps: la variable de dirección es la última dirección hacia la que se enfrenta el personaje (izquierda o derecha en este caso, se describe más adelante en el código)
private function drawJumpMode():void {
var change:Boolean = false;
//decide whether to swap graphics or continue playing
if (Math.abs(particleGroup.particles[0].velocity.y) < epsilon && Math.abs(particleGroup.particles[0].velocity.x) < epsilon && direction == "right") {
if (lastClipAction != "stillRight"){
lastClipAction = "stillRight";
change = true;
}
}
else if (Math.abs(particleGroup.particles[0].velocity.y) < epsilon && Math.abs(particleGroup.particles[0].velocity.x) < epsilon && direction == "left") {
if (lastClipAction != "stillLeft"){
lastClipAction = "stillLeft";
change = true;
}
}
else if (particleGroup.particles[0].velocity.y > 0 && Math.abs(particleGroup.particles[0].velocity.x) < epsilon) {
if (lastClipAction != "down"){
lastClipAction = "down";
change = true;
}
}
else if (particleGroup.particles[0].velocity.y < 0 && Math.abs(particleGroup.particles[0].velocity.x) < epsilon) {
if (lastClipAction != "up"){
lastClipAction = "up";
change = true;
}
}
else if (particleGroup.particles[0].velocity.x > 0) {
if (lastClipAction != "right") {
lastClipAction = "right";
direction = "right";
change = true;
}
}
else if (particleGroup.particles[0].velocity.x < 0) {
if (lastClipAction != "left"){
lastClipAction = "left";
direction = "left";
change = true;
}
}
//If the movie clip has changed, swap the old one back into the all clips library and get the new one.
if (change) {
//set flip to false whenever there is a change in movie clip
flipped = false;
//if the movie clip was flipped before, this should flip it
//back to normal
flip();
//remove movie clip from the scene
game.removeChild(playingMovieClip);
//check it back into the movie clip library
allClips.addChild(playingMovieClip);
//add the movie clip into the scene
playingMovieClip = MovieClip(allClips.getChildByName(actionToClip[lastClipAction + "Name"]));
game.addChild(playingMovieClip);
}
//Flip if needed
flip();
//set it to true so that it won't be constantly flipped.
flipped = true;
//set movie clip to be center over the main particle
playingMovieClip.x = particleGroup.particles[0].center.x;
playingMovieClip.y = particleGroup.particles[0].center.y;
}
private function flip():void {
//If a transformation is required, then do so
if (actionToClip[lastClipAction + "H"]=="1" && !flipped){
flipHorizontal(playingMovieClip);
}
if (actionToClip[lastClipAction + "V"]=="1" && !flipped){
flipVertical(playingMovieClip);
}
}
Solución
Creo que el código en cuestión está aquí.
//If the movie clip has changed, swap the old one back into the all clips library and get the new one.
if (change) {
//set flip to false whenever there is a change in movie clip
flipped = false;
//if the movie clip was flipped before, this should flip it
//back to normal
flip();
//remove movie clip from the scene
game.removeChild(playingMovieClip);
//check it back into the movie clip library
allClips.addChild(playingMovieClip);
//add the movie clip into the scene
playingMovieClip = MovieClip(allClips.getChildByName(actionToClip[lastClipAction + "Name"]));
game.addChild(playingMovieClip);
}
//Flip if needed
flip();
El problema es que estás haciendo una doble vuelta aquí. Esto funciona si está de hecho cambiando los clips del cambio. Por ejemplo, si vas de correr derecho a pararte derecho. Salga mal cuando pasas de correr a correr hacia la izquierda. Ya que son el mismo clip que acabas de voltear, terminas haciendo dos giros en esta situación. Esto provoca el comportamiento de moonwalk :-).
Yo sugeriría limpiar esta lógica y proporcionar una manera de restablecer la inversión. En lugar de volver a la orientación original, restablézcala para que pueda garantizar el estado del clip.