Page 1 sur 1

Problème vitesse d'animation sprite !!! HELP !

Publié : sam. 21/avr./2007 13:22
par Fig
J'ai commencé un jeu en 3D isometrique, j'ai un problème avec les animations... Elles ne se jouent pas à la même vitesse en fonction de l'emplacement sur la carte (ou en fonction d'autre chose, je n'arrive pas a determiner quoi). :?

Essayez ce code et observez les arbres... ils devraient bouger tous au même rythme ( a savoir un sprite toute les 700 boucles...) :roll:

Quelqu'un a t il une explication ???!!! :!: 8O

Re: Problème vitesse d'animation sprite !!! HELP !

Publié : sam. 21/avr./2007 14:07
par Backup
Fig a écrit :J'ai commencé un jeu en 3D isometrique, j'ai un problème avec les animations... Elles ne se jouent pas à la même vitesse en fonction de l'emplacement sur la carte (ou en fonction d'autre chose, je n'arrive pas a determiner quoi). :?

Essayez ce code et observez les arbres... ils devraient bouger tous au même rythme ( a savoir un sprite toute les 700 boucles...) :roll:

Quelqu'un a t il une explication ???!!! :!: 8O

http://fig77.free.fr/test.zip
peut etre en utilisant les timers ? 8O (bref le multitache !)


voici un exemple d'utilisation des timer !

t'as qu'a mettre tes anim dans une procedure


  Procedure TimerProc(hwnd.l, uMsg.l, idEvent.l, dwTime.l)
     Select uMsg
         Case #WM_TIMER
             Select idEvent
                 Case 1
                     Debug "--------------------1 seconde"
                     ; Ici, le code à executer toutes les secondes
                 Case 2
                     Debug "0.2 secondes"
                     ; Ici, le code à executer toutes les 200 millisecondes
                 Case 3
                     Debug "-------------------------------------------3 secondes"
                     ; Ici, le code à executer toutes les 3 secondes
             EndSelect
     EndSelect
EndProcedure


If OpenWindow (0, 100, 100, 100, 100, #PB_Window_SystemMenu , "" )
    Handle = WindowID (0)
    
     SetTimer_ (Handle, 1, 1000, @TimerProc()) ; envoie un evenement toutes les 1000 millisecondes
     SetTimer_ (Handle, 2, 200, @TimerProc()) ; envoie un evenement toutes les 200 millisecondes
     SetTimer_ (Handle, 3, 3000, @TimerProc()) ; envoie un evenement toutes les 3000 millisecondes
    
     Repeat
     Until WaitWindowEvent () = #PB_Event_CloseWindow
EndIf

Publié : sam. 21/avr./2007 14:30
par Fig
Hum... Mes animations ne s'incrémentent qu'a leur affichage a l'écran, à condition donc qu'elles soient dans les limites de l'ecran visible...

Ca signifie donc qu'il faut que je lance l'affichage de l'écran toute les x millisec et non a chaque tour de boucle... (?!??!!)

Comment se fait il que chaque tour de boucle n'ait pas un temps d'éxécution constant ?? (quasi constant, du moins rien de perceptible dans l'incrémentation d'une variable). En effet, je n'ai aucun test "if" qui aiguillonne le code sur une série d'instructions gourmandes en temps d'execution et qui expliquerait que parfois l'incrémentation soit considérablement ralentit...

Bon, je vais appliquer cette méthode pour voir ce que ça donne, merci :P

Publié : sam. 21/avr./2007 15:57
par Backup
Je suis desolé, je t'ai proposé cette solution
sans avoir pris le temps de regarder ton code :oops:

peut etre qu' effectivement cette solution n'est pas adapté a ton code !! :D

ou alors déclanche le timer seulement si sprite present dans l'ecran .. :D

Publié : sam. 21/avr./2007 16:18
par Thyphoon
Perso j'ai rencontré le même genre de problème pour la création de mon jeu. voici comment je procède pour jouer l'animation
(je viens de faire le code a main levé sans testé , c'est pour montrer l'idée apres faut adapter a ton code)

Code : Tout sélectionner

#AnimArbre=10

Anim=#AnimArbre

if ElapsedMilliseconds()>NextImagetImage(Anim) ; Si le temps est écoulé 
  Image(Anim)=Image(Anim)+1 ;On incrémente l'animation
  NextImagetImage(Anim)=ElapsedMilliseconds()+100 ;on initialise le compteur pour la prochaine image (au lieu de 100 on peut avoir une variable pour avoir une durée différente pour chaque image)
  if Image(Anim)>ImageMax(Anim) ; si on est arrivé a la fin de l'animation 
   Image(Anim)=1 ; on revient au debut
  endif
endif
DisplaySprite(ImagetoSprite(Anim,Image(Anim)),x,y)
Avec ce code a partir du moment ou un element est affiché l'animation est joué ! Mais là tout les arbres sont synchro...

Publié : sam. 21/avr./2007 17:40
par Fig
OK, Thyphoon je vais adopter cette solution je pense.
Mais je ne comprend toujours pas d'où viens le problème.


Merci à tous deux :wink:

Publié : sam. 21/avr./2007 17:58
par Thyphoon
Fig a écrit :OK, Thyphoon je vais adopter cette solution je pense.
Mais je ne comprend toujours pas d'où viens le problème.


Merci à tous deux :wink:
De rien c'est pas grand chose...
J'ai regardé un peu ton code mais j'ai pas trouvé ou était géré l'animation
Parcontre j'ai vu quelques trucs...

Je te conseille de regrouper les StartDrawing StopDrawing tu gagnera en FPS.
Autre chose je te conseille mais ça c'est mon avis perso d'autre te diront peut être le contraire... de decouper ton programme en plusieur fichier... plus facile (je trouve pour travailler sur un truc précis)
Exemple
Main.pb
Map.pb
gestionperso.pb
animation.pb

Mais en tout cas c'est un bon debut ... :)

Publié : sam. 21/avr./2007 19:03
par Fig
je prend note de tes conseils qui sont bon sans aucun doute/
pour les startdrawing je vais les regrouper... Mais quand je vire la synchro, en FPS je suis déja assez haut étant donné que je n'affiche que les tiles et les sprites présent à l'écran (maximum environ 400 selon la resolution) :wink:

J'essaye d'organiser mes sprites pour le moment... Voila le type d'organisation pour laquelle j'ai opté:

exemple personnage Fermier


Avec un masque binaire je peux changer de sprite, l'orientation du personnage ou l'activité... avec une incrémentation je peux avancer l'animation et la remettre a zero avec un masque binaire sans test donc.

ex:
Les sprites du fermier marchant vers le bas sont : 35072.bmp à 35080.bmp


l'affichage se fait ici pour un arbre:

Code : Tout sélectionner

If affichage(e)\perso>#nbelement
          If ElapsedMilliseconds()>tempo:arbre(affichage(e)\perso-#nbelement)\spritecourant+1:tempo=ElapsedMilliseconds()+200:EndIf
            arbre(affichage(e)\perso-#nbelement)\spritecourant & %11111111111111111111111111110111
            DisplayTransparentSprite(arbre(affichage(e)\perso-#nbelement)\spritecourant,TileposX-25,TileposY-170);affiche arbre
         EndIf
      EndIf
:D

Merci pour l'encouragement