La propriété sprite().quad 



 

Ah ! the quad of sprite... La propriété the quad of sprite fut tout de suite repérée par les aficionados comme LA grande nouveauté de D7. j'en connais qui lui font faire de la 3D ! Quad c'est une liste de quatre points, coordonnées horizontale et verticale des coins d'un bitmap. Ces coins peuvent désormais être déplacés indépendamment l'un de l'autre. Regardons ça...

 

Pour réaliser d'abord cette mini animation aux curseurs déformants on a commencé par placer sur la scène notre logo (piste 1), sous lui un acteur forme QuickDraw étiré horizontalement sur 100x1 pixels (la glissière), enfin un bitmap curseur. on a attaché à ce dernier le comportement suivant afin de le transformer en curseur (un classique)

property pDecalageH, pN, pDebutH

on beginSprite me
pN = the currentSpriteNum
pDebutH = sprite(pN - 1).locH + 50
-- 50 c'est la largeur de la glissière divisée par deux,
-- c'est le milieu, la position initiale du curseur

 sprite(pN).constraint = pN -1
-- Rappel : la glissière est au dessous donc piste pN - 1
end

Le gestionnaire beginSprite on le voit, initialise seulement les valeurs des propriétés.

on mouseDown
 pDecalageH = the mouseH - sprite(pN).locH
-- classique : on mesure d'abord l'écart du bitmap à la souris
-- pour éviter un saut lorsqu'il la suit (2 lignes en dessous)

 repeat while the stilldown
  sprite(pN).locH = the mouseH - pDecalageH
  updateStage
  
-- dans une boucle, on doit forcer Director à rafraîchir l'écran
  x = (sprite(pN).locH - pDebutH)/2.5
   -- tout est là : la position du curseur (relativement à sa position initiale pDebutH)
  -- est divisée par 2,5 parce que

   -- avec 100 px de jeu, on obtient 40 étapes
   -- de -20 a + 20
  sendSprite(1, #transformationDe, x)
   -- on envoie enfin l'info au logo piste 1
 end repeat
end

Chaque déplacement de notre curseur envoie donc le message "transformationDe" au logo piste 1. Afin que ce bitmap sache quoi faire d'une telle instruction, nous lui associons le comportement suivant :

property pNum
property pCoinHautGauche, pCoinHautDroite, pCoinBasGauche, pCoinBasDroite

on beginSprite me
  pNum = the spriteNum of me
  pCoinHautGauche = sprite(pNum).quad[1]
  pCoinHautDroite = sprite(pNum).quad[2]
  pCoinBasDroite = sprite(pNum).quad[3]
  pCoinBasGauche = sprite(pNum).quad[4]
end

Les quatre propriétés pCoinHautGauche , Droit, etc. n'ont d'autre fonction que de nous faciliter la tâche. Elles ne servent à rien d'autre qu'à décomposer la liste quad en unités plus manipulables. On notera au passage l'ordonnancement inhabituel des points dans la liste quad. Ainsi l'expression "getAt(the quad of sprite n, 3) - en nouvelle notation "sprite().quad[3]" - retourne les coordonnées du point inférieur droit.

 

 

Il faut finalement ajouter au comportement le gestionnaire qui permettra à notre bitmap de se transformer en fonction de la valeur transmise par le curseur horizontal.

on transformationDe me, valeur
   a = point ( getAt(pCoinHautGauche, 1), (getAt(pCoinHautGauche, 2) - valeur) )
   d = point (getAt(pCoinBasGauche , 1), (getAt(pCoinBasGauche, 2) + valeur))
   b = point ( getAt(pCoinHautDroite, 1), (getAt(pCoinHautDroite, 2) + valeur) )
   c = point ( getAt(pCoinBasDroite, 1), (getAt(pCoinBasDroite, 2) - valeur) )
   sprite(pNum).quad = [a, b, c, d]
end

 

Évidemment ça donne envie de faire de la 3D mais là, il faudra peut-être étudier les équations de la VRML ... En attendant voilà comment réaliser l'animation plus haut qui a du épuiser les ressources mémoire de votre navigateur.

 

 

Ici, on a simplement placé le logo de qui vous savez plusieurs fois sur la scène et on lui a chaque fois attaché un comportement analogue au suivant (ici pour un mouvement vers la gauche).

 property pA, pB, pC , pD, pN 

on beginSprite me
  pN = the spriteNum of me
  leCentre = sprite(pN).loc
  sprite(pN).quad = [leCentre, leCentre, leCentre, leCentre]
  --- le logo commence sa carrière minuscule au centre
  pA = sprite(pN).quad[1]
  pB = sprite(pN).quad[2]
  pC = sprite(pN).quad[3]
  pD = sprite(pN).quad[4]
-- les propriétés A, B, C.. ne sont que
-- des moyens commodes de nommer chaque coin
end

on prepareFrame me
 if getAt(pB, 1) < 0 then
    
-- si le logo est sorti de la zone visible,
    -- c'est à dire si la coordonnée horizontale
    -- de son coin supérieur gauche est > 0 alors
    -- on le ramène tout entier au centre de la scène

    leCentre = point(160, 120)
    sprite(pN).quad = [leCentre, leCentre, leCentre, leCentre]
    -- on met à jour les propriétés pA, pB, ... c'est-à-dire chaque coin
    pA = sprite(pN).quad[1]
    pB = sprite(pN).quad[2]
    pC = sprite(pN).quad[3]
    pD = sprite(pN).quad[4]
  else
    pA = pA - point(4,4)
    pB = pB - point(2,2)
    pC = pC - point(2,-2)
    pD = pD - point(4,-4)
   -- c'est ici que l'on donne le mouvement
   -- les valeurs sont un peu plus importantes pour
   -- les coins extérieurs (gauches ici) afin de créer
   -- l'effet de perspective
   sprite(pN).quad = [pA, pB, pC, pD]
  end if
end