Bonsoir à tous !
Nous nous étions quittés sur le problème de l'animation. Quelques exemples avaient été portés à votre attention, mais chacun comportait des défauts. Nous avions cependant proposé des exemples quelque peu fluides, mais dans graphisme simple (carrés,...).
En fait, je n'ai pu contourner aucune de ces difficultés, mais il semble, à en lire ce qui est écrit sur la toile, que nous ne soyons pas les seuls. Un contournement possible serait de faire appel à des bibliothèques externes (comme l'exemple de Chronoklazm en Opengl). Je suis trop nul pour cela, alors je persévère.
A l'heure actuelle, je suis bien loin du double buffering, mais un pas décisif dans la synchronisation entre le balayage et l'affichage vient d'être fait. il n'est pas de moi, vous vous en doutez, mais il mérite attention. Pour vous en persuader, voici un petit exemple de code dans lequel nous allons mettre en compétition un canvas dans lequel ont été synchronisés l'affichage et le balayage et un où c'est un buffer simple qui est créé. Je tiens à dire que je ne comprends pas forcément tout, mais vous peut-être.
;; les librairies habituelles
(require(lib "mred.ss""mred" )
(lib"class.ss" )
(lib "thread.ss" ))
;; step-time: contrôle la vitesse de l'animation
(define step-time 0.01)
;;la taille du bitmap
;;contrôle la taille de l'animation et de l'offscreen buffer (?)
(define bitmap-size 100)
;;ici, on s'assure de ne pas dessiner l'image en meême temps que nous la rafarîchissons
(define drawing-mutex (make-semaphore 1))
;;l'animation
(define (animate)
(update-state-variables); ce sont les variables du "monde" créé (en gros, la trajectoire)
(call-with-semaphore ;; là, je laisse les experts comprendre
drawing-mutex
(lambda()
(draw-animation bdc)))
(queue-callback
(lambda()
(send ani-canvas on-paint)
(send buf-canvas on-paint)
))
(sleep step-time)
(animate))
;les variables de l'animation
(define sign 1)
(define step 50)
;;offscreen buffer et son drawing context (j'arrive pas à traduire)
(define bm(make-object bitmap% bitmap-size bitmap-size))
(define bdc(make-object bitmap-dc% bm)) ;;change les variables du "monde"
(define(update-state-variables)
(set! step(+ step sign))
(cond
[(= step 0)
(set! sign 1)]
[(= step bitmap-size)
(set! sign -1)]))
;;dessine l'état courant des variables de l'animation
(define (draw-animation dc)
(send dc clear)
(sleep (/ step-time 3))
(send dc draw-rectangle (quotient step 2)
(quotient step 2)
(quotient step 2)
(quotient step 2)))
(define f(instantiate frame% ()
(label "essai" )))
(define ani-canvas(instantiate canvas% ()
(parent f)
(min-width bitmap-size)
(min-height bitmap-size)
(paint-callback ;c'est par là que ça se passe
(lambda(b dc)
(call-with-semaphore
drawing-mutex
(lambda()
(send dc draw-bitmap bm 0 0)))))))
(define buf-canvas(instantiate canvas% ()
(parent f)
(min-width bitmap-size)
(min-height bitmap-size)
(paint-callback
(lambda (b dc)(draw-animation dc)))))
(send f show #t)
(thread animate)
|
Alors? Bien entendu, l'auteur en sera remercié.
Les saccades que vous pouvez remarquer sont, à mon avis, un problème d'optimisation du code. Il doit y avoir qq part saturation de la mémoire. On peut donc encore faire mieux.
Dans cette optique, deux voies s'offrent à nous: le double buffering (un volontaire ) ou alors, j'ai cru lire que l'on pouvait ne rafraîchir qu'une partie de l'image (à voir).
Maintenant, vous pouvez tester avec des images plus jolies. Il vous suffit de les déclarer ici:
;;offscreen buffer et son drawing context (j'arrive pas à traduire)
-->(define image(make-object bitmap% "votre_image_de_fond" ))
-->(define fond(make-object bitmap% "votre_objet_qui_se_deplace" ))
(define bm(make-object bitmap% bitmap-size bitmap-size))
(define bdc(make-object bitmap-dc% bm)) |
et d'en demander l'affichage comme cela:
(define (draw-animation dc)
(send dc clear)
(sleep (/ step-time 3))
(send dc draw-bitmap fond 0 0 'solid) (send dc draw-bitmap image (quotient step 2)(quotient step 2) 'solid)) |
On désactive le buf-canvas qui ne nous sert plus à rien: donc on vire le (define buf-canvas) sans oublier d'effacer aussi l'appel qui lui est fait dans la fonction (animate).
A bientôt. Et n'hésitez surtout pas si vous pouvez nous aider.