Inertie Lingo 

 

 

Patience ! Allez ! 8O Ko le ShockWave à télécharger, C'est promis, on ne vous le fera plus ! C'est qu'il pèse lourd le bitmap de notre praxinoscope 48 pixels * 5200 pixels ! Ce poids est d'autant plus regrettable que dans cette version ShockWave il manque singulièrement de réactivité ! pourtant, il fallait bien vous le montrer pour vous donner envie de le refaire avec nous...

 

Préparation de l'image (Adobe Premiere et le format FilmStrip)

Adobe Première est le premier logiciel mis en œuvre ici car c'est lui qui va nous permettre de générer cette grande image ou bande de film. Dans un nouveau projet au réglages indifférents on importe un élément que l'on place sur le montage. On n'oublie pas alors d'étirer la bande mauve de définition de la zone de travail à l'aplomb des images à extraire. Soyons modestes ici car à trop en vouloir on risque de générer une bande de film d'une longueur ingérable. Une durée de 3 ou 4 seconde semble un bon compromis.

 

 

Dans le menu Fichier de Premiere, on appelle Exportation puis Vidéo. Le dialogue de paramètrage apparaît alors avec en haut son menu pop-up. L'article général nous permet de choisir le format d'export Filmstrip :

 

L'article réglage vidéo du même pop-up, nous permet de réduire les dimensions d'export (minimum 32x32 pixels). Il semble évident que nous ne pouvons demander à Director d'animer une bande d'image trop lourde. Nous choisissons une petite taille- 48 x 36 pixels - et surtout mais toujours dans le but d'alléger le fichier généré, nous autorisons le logiciel à ne garder qu'une image sur 3 en définissant une cadence finale de 10 images par secondes (notre source NTSC contient 30 ips; avec une élément PAL/SÉCAM à 25 ips, on choisira plutôt 12,5 ips). On peut dès lors procéder à l'enregistrement du document.

 

 

Filmstrip c'est ce format qui permet d'amener une séquence d'images vidéo dans Photoshop. La séquence se présente comme une bande de film sur laquelle on peut intervenir à loisir , dessiner (Rotoscoping) ou de manière plus générale mettre ne œuvre tous les outils de Photoshop calques compris ! Plus fort, Photoshop nous facilite une intervention image après image : les touches MAJ et pageUp/pageDown permettent de faire défiler régulièrement la bande et de replacer ainsi le pointeur exactement au même endroit sur chaque image. Seuls impératifs : si l'on veut pouvoir réimporter la séquence dans première après retouche dans Photoshop, il ne faut pas l'avoir redimensionnée ni recadrée.

 

 

Nous avons importé la séquence dans Photoshop pour la convertir en 256 couleurs (Menu Image/modes/couleurs indexées). La puissance des machines actuelles fait souvent oublier cette simple étape. Pourtant en 256 couleur notre images pèsera exactement 3 fois moins lourd qu'en RVB et demandera moins de travail à Director !

 

Création de l'animation Director

On importe l'image dans le logiciel auteur et on la place sur un piste du scénario. Un script associé au frame ou tableau permet d'immobiliser la lecture en faisant boucler l'animation.

on exitFrame
     g o the frame
end

C'est maintenant à l'image sur la scène (sprite) qu'il faut associer un comportement permettant de la faire glisser. Nous souhaitons qu'il soit possible de la lancer plus ou moins vite mais nous souhaitons aussi qu'un mouvement naturel l'anime et qu'après un certain temps elle ralentisse puis s'arrête complètement. Nous devons rédiger un script qui simule l'inertie d'un mouvement naturel !!!

On sélectionne le sprite entier dans le scénario et dans D7, l'on demande l'ouverture de l'inspecteur de comportement par un cllic sur l'icône losange en haut à gauche du scénario. Le bouton "+" nous permet d'attacher un nouveau comportement au sprite. Après que Director nous a demandé son nom, nous cliquons dans la fenêtre de l'inspecteur de comportement sur l'icône d'une page en haut à droite pour accéder à l'éditeur de script.

NOTE : Le script que nous allons rédiger utilise pleinement le nouvelle notation et l'orientation objet des behaviours de D7, les utilisateurs de la version 5 toutefois pourront facilement adapter ce code à leur environnement.

Un comportement véritable ou behavior c'est un script que l'on peut associer identiquement à plusieurs sprites afin qu'ils se comportent chacun de la même façon. Écrire un behaviour ou comportement c'est donc rédiger un code valable pour un ou pour plusieurs sprites, pour tout sprite. Pas question donc de coder "en dur" les constantes numéro de piste, position, etc... car on s'interdirait alors d'attacher ce comportement à un autre sprite. Et si nous souhaitions animer un deuxième bitmap sur la scène ? Il faudrait alors rédiger un autre script.

De fait, les amateurs de POO ne seront pas déroutés si nous commençons notre code par une déclaration des propriétés globales de chaque objet sprite. Les sprite subsistant et leurs propriétés avec eux, les propriétés nous épargnent d'avoir à utiliser des variables globales.

Notre script de comportement commence ainsi :

 

property pNumero
property pPositionV
property pLieuDuDebutDuCliquerGlisser
property pDecalageV, pVitesse, pMoiCliqué

on beginSprite me
  pNumero = the spriteNum of me
end

 

Notez bien que l'on s'interdit tout usage de valeur absolue. Notre comportement pourra être attaché à toute sprite à venir. pNumero représente sous une notation courte le numéro de la piste sur laquelle le sprite se trouve. Lors de l'instanciation automatique de l'objet sprite, on enregistre ce numéro dans une propriété nommée pNumero.

Passons aux chose importantes. Afin d'obtenir un lancer "naturel" du bitmap nous devons tenir compte de la vitesse avec laquelle l'utilisateur glisse pour lancer. Pour connaître cette vitesse nous nous proposons de mesure la distance parcourue par la souris dans un cycle, c'est-à-dire entre l'appui sur la souris où prise en main du bitmap et l'événement prepareFrame qui, DANS DIRECTOR 7, le suit immédiatement. Donc, nous notons la position de la souris au début du lancer (propriété pLieuDuDebutDuCliquerGlisse). Classique : on note la distance du pointeur de souris au point de référence du sprite (pDecalageV) car s'il faut déplacer le sprite en même temps que la souris, il ne faut pas le mettre exactement à la position de la souris. L'utilisateur ne pose pas forcément sa souris au milieu du bitmap !

 

on mouseDown me

pLieuDuDebutDuCliquerGlisser = the mouseV
pDecalageV = pLieuDuDebutDuCliquerGlisse - sprite(pNumero).locV
pMoiCliqué = true

end

 

La propriété pMoiCliqué n'est qu'un flag, un indicateur permettant de savoir à tout instant si l'utilisateur fait glisser le bitmap, auquel cas on doit l'accompagner, où s'il a lâché la souris auquel cas on doit s'enquérir de la vitesse à donner au bitmap. Cette propriété sera discriminante pour le gestionnaire d'animation on prepareFrame (voir plus bas).

 

on mouseUp me
    pMoiCliqué = false
end

on mouseUpOutSide me
   pMoiCliqué = false
end

 

L'événement prepareFrame, rappelons le est sous D7 envoyé aux sprites, c'est donc lui que nous interceptons ici - dans notre script de comportement - pour animer la bande de film. Toujours sous D7, prepareFrame est émis dès après le mouseDown.

Deux cas peuvent se présenter : L'utilisateur enfonce le bouton de la souris ou il le relâche (La propriété "pMoiCliqué" est true ou false)

Maintenant, s'il maintient le bouton enfoncé ce peut-être pour lancer le film ou bien pour l'arrêter. Dans ces deux cas, nous devons en permanence déplacer le bitmap proportionnellement mais surtout noter la vitesse du mouvement qu'il impose à la souris afin de pouvoir réagir lors qu'il relâchera le bouton. La vitesse de son déplacement c'est, nous l'avons dit , le nombre de pixels parcourus dans un cycle, entre le mouseDown et le prepareFrame suivant puis entre deux prepareFrame. Nous écrirons pour gérer ce premier cas :

  if pMoiCliqué then

   pPositionV = the mouseV - pDecalageV
   pVitesse = the mouseV - pLieuDuDebutDuCliquerGlisse

En réinitialisant la position de la souris enfoncée afin de refaire un calcul de vitesse au prochain cycle (au prochain prepareFrame ). L'utilisateur peut ainsi faire varier la vitesse de son glisser. C'est la dernière impulsion qui nous donnera finalement la vitesse du lancer.

    pLieuDuDebutDuCliquerGlisse = the mouseV
    ...

Deuxième cas, l'utilisateur a relâché la souris. pour épargner Director, on ne doit se soucier de déplacer le sprite que si la vitesse finalement enregistrée (la distance parcourue par la souris entre deux prepareFrame ) n'est pas nulle. On écrira:

else if abs(pVitesse) > 0 then

pPositionV = sprite(pNumero).locV + pVitesse

 

Que faut-il penser de ce script finalement :

 

on prepareFrame me
pPositionV = sprite(pNumero).locV

  if pMoiCliqué then

    pPositionV = the mouseV - pDecalageV
    pVitesse = the mouseV - pLieuDuDebutDuCliquerGlisse
      pLieuDuDebutDuCliquerGlisse = the mouseV

else if abs(pVitesse) > 0 then

   pPositionV = sprite(pNumero).locV + pVitesse

  end if

sprite(pNumero).locV = pPositionV

end

 

La dernière instruction repositionne le sprite à chaque cycle, à une distance équivalente à celle déjà parcourue lors de l'impulsion initiale. l'utilisateur aura alors la joie de voir qu'il peut lancer plus ou moins fort le sprite mais bien-sûr... il ne pourra le lancer qu'une fois puisqu'un fois sur sa lancée, rien ne l'arrête plus !

On doit ici restreindre les mouvement du sprite de deux façons, d'abord on doit veiller à ce qu'il ne sorte pas de la scène. Il sort de la scène par le bas par exemple, dès lors que sa position (sprite().locV) est supérieure à la moitié de sa hauteur.

 

 

Si lors de son déplacement, il vient à sortir des limites de la scène il convient de l'y repositionner immobile. Un test de ce genre exige que l'on se connaisse la hauteur de la scène (hauteurDeLaScene) :

hauteurDeLaScene = getAt(the stage.rect, 4) - getAt(the stage.rect, 2)

case true of

(pPositionV > (sprite(pNumero).height )/2 ) :
pPositionV = (sprite(pNumero).height)/2   

(pPositionV < hauteurDeLaScene - (sprite(pNumero).height)/2) :
pPositionV = hauteurDeLaScene - (sprite(pNumero).height)/2

    otherwise : nothing
end case

 

Puis, après nous être assurés qu'il ne sortira pas de la scène, on doit s'occuper de ralentir progressivement le sprite afin que son mouvement ne dure pas éternellement.

 if abs(pVitesse) > 0 then

    case true of

(pVitesse > 0):
pVitesse = pVitesse - 1

(pVitesse < 0):
pVitesse = pVitesse + 1

end case

 

Réécrivons maintenant le gestionnaire prepareFrame sans le tronquer.

 

on prepareFrame me
  pPositionV = sprite(pNumero).locV

  if pMoiCliqué then

     pPositionV = the mouseV - pDecalageV
     pVitesse = the mouseV - pLieuDuDebutDuCliquerGlisse
     pLieuDuDebutDuCliquerGlisse = the mouseV

 else if abs(pVitesse) > 0 then

   pPositionV = sprite(pNumero).locV + pVitesse

   case true of       --- décélération
     (pVitesse > 0):
        pVitesse = pVitesse - 1

    (pVitesse < 0):
      pVitesse = pVitesse + 1
   end case
 end if

hauteurDeLaScene = getAt(the stage.rect, 4) - getAt(the stage.rect, 2)

case true of
(pPositionV > (sprite(pNumero).height )/2 ) :
   pPositionV = (sprite(pNumero).height)/2
      -- bloqué contre le bord haut de la scène

(pPositionV < hauteurDeLaScene - (sprite(pNumero).height)/2) :
   pPositionV = hauteurDeLaScene - (sprite(pNumero).height)/2 
     -- bloqué contre le bord bas de la scène

   otherwise : nothing
end case

   sprite(pNumero).locV = pPositionV    -- déplacement "réel" du sprite
end

 

Depuis Director 7, Lingo accepte deux syntaxes ou notation. C'est la nouvelle notation qui est utilisée ici. Héritée du basic Mac et d'HyperTalk, l'ancienne notation devrait peu à peu devenir obsolète.