Le feux d'artifice Lingo 

 

 

 

Économiseur d'écran ou décors stellaire d'un jeu d'action... en tous cas notre animation ne pèse pas lourd (6 Ko). Il faut dire que sa distribution ne contient qu'un seul acteur bitmap 1 bit de 4 pixels !

 

 

Un seul acteur et aussi... un peu de Lingo.

Commençons. On dispose notre acteur fusée 90 fois sur la scène. Le principe de l'animation que l'on doit leur donner et le suivant : Initialement regroupés, les sprites doivent s'éloigner en des directions opposées et s'estomper afin de simuler un éclatement. Nos fusées se verront toutes attacher le même comportement. On y déclare d'abord leur propriétés communes. Parmi celles-ci, deux incréments de déplacement (pPasHorizontal, pPasVertical) qui déterminent l'orientation ou l'angle de chaque fusée lors de l'explosion. Si le pasHorizontal est identique au pas vertical, l'orientation est de 45°.

 

C'est en modifiant de façon aléatoire ces valeurs lors de l'instanciation que nous obtiendrons que chaque sprite parte dans un sens différent. Une dernière propriété pMouvement servira de "flag" ou d'indicateur afin de distinguer les sprites immobiles (pMouvement = false).

Le comportement attaché à chacun des 90 sprite est rédigé ainsi :

property pPosH, pPosV, pPasHorizontal, pPasVertical, pMouvement

on beginSprite me
   pMouvement= false
end

Le gestionnaire "initialisationDe" sera envoyé à chaque sprite afin d'amorcer un éclatement. Et ce, seulement si nécessaire (if pMouvement=true). Deux paramètres devront être passés au gestionnaire : un lieu de regroupement (début de l'explosion) et une couleur.

 

on initialisationDe me, ou, quelCouleur
   if pMouvement then exit
   -- on arrête là si le sprite est déjà en mouvement sinon :

   pMouvement= true
  sprite (the currentSpriteNum ).loc = ou
  pPosH = sprite (the currentSpriteNum ).loc[1]
  pPosV = sprite (the currentSpriteNum ).loc[2]
  sprite(the currentSpriteNum).foreColor = quelCouleur
  sprite(the currentSpriteNum).blend =100

Afin de simuler un réel éclatement, les sprites doivent s'estomper peu à peu. Nous utiliserons pour cela la propriété "blend". On doit aussi donner aléatoirement une direction dans l'espace à chacun d'entre eux. Ici un petit rappel de mathématique est toujours utile : La position horizontale d'un point sur un cercle est égale au cosinus de l'angle multiplié par le rayon. Illustration.

 

Malheureusement, lingo ne parle qu'en degrés radians 360° = ¹*2 radians. Nous effectuons une petite conversion.

x = random(360)
  -- on choisit un angle quelconque
  x = x* pi()/20
  -- en radians

  -- et nous calculons en conséquence le pas.
-- la fonction random() permet de modifier le rayon
-- du cercle fictif et ainsi de faire aller notre fusée plus ou moins loin.

pPasHorizontal = cos(x) * random(8)
pPasVertical = sin(x) * random(8)

end

 

Afin que les sprites soient animés après initialisation, nous ajoutons à leur comportement un gestionnaire prepareFrame. Rappelons que ce gestionnaire sera appelé continûment à chaque nouveau tableau ou frame.

on prepareFrame me
  if not pMouvement then exit
  -- on arrête là si le sprite doit rester immobile
 -- c'est le cas avant instanciation ou à la fin du mouvement


  if sprite(the currentSpriteNum).blend > 5 then
   -- s'il est encore visibles seulement, on le déplace d'un incrément
  pPosH = pPosH + pPasHorizontal
  pPosV = pPosV + pPasVertical
  sprite(the currentSpriteNum).loc = point(pPosH, pPosV)
   -- et on les estompe un peu (blend - 3)
  sprite(the currentSpriteNum).blend = sprite(the currentSpriteNum).blend - 3

else

  -- s'il est inutile de le déplacer alors
  -- on place le sprite hors la scène

  sprite(the currentSpriteNum).loc = point(-50,-50)
  -- et on indique sa disponibilité pour une nouvelle instanciation (
  pMouvement = false
 end if
end

 

Chaque sprite est donc doté d'un gestionnaire prepareFrame qui le déplace si nécessaire, c'est à dire si sa propriété pMouvement est égale à false. Encore faut-il, pour que notre feux d'artifice commence, que cette propriété soit changée répétitivement. C'est sur le script de tableau cette fois que nous plaçons le code requis. Parce qu'il s'agit d'éviter un mouvement trop "mécanique", la fonction random va être fortement sollicitée.

 

on prepareFrame
if random(2) - 1 then exit
-- Grâce à cette ligne, le gestionnaire
-- ne sera pas toujours exécuté
-- mais seulement aléatoirement
-- Rappel : 0 est équivalent à false

On souhaite animer un premier groupe de 20 sprites. Il nous faut juste pour cela leur faire parvenir un message d'initialisation (qui ne sera exécuté que s'il y a lieu - voir plus haut). L'instruction "initialisationDe" - on l'a vu - requiert deux arguments, un lieu de départ et une couleur.

Le lieu de départ doit être situé dans les limites de la scène et même mieux, dans une zone plus réduite.

x = random(260)+20
-- ainsi x est compris entre 20 et 280 (la scène fait 320 pixels de large)
y = random(180)+10
endroit = point(x,y)

couleur = random(175)
-- on dispose de 255 couleurs dans la palette mais les dernières références
-- donnent des couleurs trop sombres pour notre but.

repeat with n = 1 to 20
  sendSprite(n, #initialisationDe, endroit, couleur)
end repeat

En l'état notre script peut être testé déjà. Mais nous voulons que de temps en temps, d'autres groupes de sprites soient également animés. On reprend donc le même code en le modifiant un peu.

if random(2) - 1 then exit
-- Grâce à cette ligne, la suite du gestionnaire
-- ne sera pas toujours exécuté

x = random(260)+20
y = random(180)+10
couleur = random(175)
repeat with n = 21 to 30
   sendSprite(n, #initialisationDe, point(x,y), couleur)
end repeat

if random(2) - 1 then exit

--- un paquet de 40 sprites de même couleur (le bouquet ?)
x = random(280)+10
y = random(180)+10
couleur = random(175)
repeat with n = 51 to 90
   sendSprite(n, #initialisationDe, point(x,y), couleur)
end repeat

if random(2) - 1 then exit

x = random(260)+20
y = random(180)+10
couleur = random(175)
repeat with n = 31 to 40
   sendSprite(n, #initialisationDe, point(x,y), couleur)
end repeat

x = random(260)+20
y = random(180)+10
couleur = random(175)
repeat with n = 41 to 50
   sendSprite(n, #initialisationDe, point(x,y), couleur)
end repeat

end

 

on exitFrame
   go the frame
end