TODO: moving Bilou through the animation isn't the right way to go. Maybe "delay x" in the animation sequence to have the next frame triggered only when we move to the next pixel would be betterFaire marcher un personnage est loin d'être une tâche facile et en particulier, ça demande une synchronisation parfaite entre le déplacement du sprite et son animation. Le moindre décalage et le joueur aura l'impression que le personnage "glisse" sur le sol au lieu de marcher. En clair, le pied en contact avec le sol doit rester au même endroit par rapport au sol jusqu'à ce qu'il se lève. Ce genre de défaut était assez fréquent dans les jeux de mon enfance (hein, Eric ;). Une manière assez simple d'y remédier est évidemment de faire courir le personnage, de préférence "à la supermario"
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKkOKnYBxpAovf71cw78y57pDCCd1VTHA7BPHoAfU8O6D82AQdsWd3QjkadJOa8mw5NuEcXfOk02gB6OUaJ-gpoQGBFk3wUQkqdwZjBxNxB_dhwmtvMfxMCv_d1gKAoKZL4_x2_g/s200/mario_walkleft.gif)
C'est Pierrick qui m'a donné la solution a mon problème en racontant comment du temps du CPC il faisait faire des sauts "réalistes" à son petit bilou en modifiant la durée d'affichage à chaque emplacement vu qu'il lui était impossible de placer le bilou (eh oui, c'était lui) entre deux tiles (pas de sprites en CPC basic ?). Plutôt que de chercher midi à 14 heures (du genre "modifier la vitesse d'écoulement du temps pour que Bilou coure plus vite"), j'ai juste changé l'interprétation de "
move x y
" en "ne passe à l'étape d'animation suivante qu'une fois que le contrôleur aura 'accumulé' le décalage suffisant. Traduit en code, ça donne :inline bool trymove(int dx, int dy) { forcechecks=false; if (selfmove) { int cflags = cast==HERO?F_PLAYERTHRU:F_MONSTERTHRU; bool notyet = (dx>0 && cdata[4]<dx) || (dx<0 && cdata[4]>dx) || (dy>0 && cdata[5]<dy) || (dy<0 && cdata[5]>dy); if (notyet) return false; if (cando(dx,dy, cflags)==cflags) { x+=dx; cdata[4]-=dx; y+=dy; cdata[5]-=dy; return true; } else { cdata[4]=0; cdata[5]=0; return setstate(state->dochecks(x>>8,y>>8,world, cdata)); } } else { x+=dx; y+=dy; return true; } }
- selfmove est défini par état : true pour monter à l'échelle, false pour tomber, etc.
cdata[STEPX]
et[STEPY]
accumule les valeurs decdata[XSPEED]
etcdata[YSPEED]
(vitesses définies par le contrôleur) en mode "selfmove" (normalement, on a directementx+=cdata[0]
)trymove(dx,dy)
est appelé lorsqu'une étape d'animation utilse la commande "MOVE"- condloop et check permettent de vérifier les testpoints sur des frames données (p.ex. quand le personnage a de nouveau les pieds au sol).
cdata[]
)will thus be used to accumulate some intended move until that "step" size becomes large enough for the move x y
instruction found in the animation list. The trymove(dx, dy)
tells whether such a move is possible right now or must wait until more motion has been accumulated.
1 comment:
Juste un hic: c'est incompatible avec la gestion des pentes. Il me faudra modifier la commande "move x,y" des animations de manière à permettre "move 1,*" (déplace d'un seul pixel en X, et d'autant que tu peux en Y) qui conduirait à un appel du genre:
trymove(command.x, cdata[5])
Post a Comment