Matrice défectueuse pour retourner (réflexion miroir) un MovieClip
-
05-07-2019 - |
Question
Je travaille actuellement sur un joli petit moteur de jeu 2D en AS3. Vous pouvez même charger différents clips Flash via XML pour les différentes animations. L'une des fonctionnalités vous permet également d'inverser une animation lorsque vous effectuez une action donnée. De cette façon, vous pourriez avoir une animation pour les deux gauches et droites (comme d'habitude). La transformation de la matrice fonctionne correctement. Cependant, je pense que ma logique pour faire basculer les choses est incorrecte. Le résultat est que la mauvaise animation sera lue au mauvais moment. J'ai décidé de faire jouer l'animation en fonction de la vitesse de l'objet en mouvement plutôt que de la pression des touches car des éléments de physique sont impliqués.
Voici un lien vers le jeu dans son état actuel: http://parrisstudios.com/Game_Design/ gameEngineDemo /
Le problème est principalement que les animations sont lues à des moments incorrects ou ne le sont pas quand elles le devraient.
Voici mon code pour le retournement (laissez-moi savoir ce que vous en pensez): ps: la variable de direction est la dernière direction à laquelle le personnage fait face (à gauche ou à droite dans ce cas, il est décrit plus tard dans le code)
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);
}
}
La solution
Je pense que le code en question est ici.
//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();
Le problème est que vous faites un double retournement ici. Cela fonctionne si vous modifiez des clips à partir du changement. Par exemple, si vous allez de droite à droite. Ça va mal quand on passe de droite à gauche. Puisqu'ils sont le même clip retourné, vous finissez par faire deux retournements dans cette situation. Cela provoque le comportement de Moonwalk: -).
Je suggérerais de nettoyer cette logique et de fournir un moyen de réinitialiser le retournement. Au lieu de revenir à l'orientation d'origine, rétablissez-la pour pouvoir garantir l'état du clip.