Bubbles (pour buller avec Tcl)

 

24-08-2004, ulis. Un petit jeu original au look bubble.

22-10-2004. Pour répondre à la demande populaire j'ai rajouté la possibilité de détruire les bulles orphelines. Attention, le jeu est différent et devient plus facile.

ENGLISH: By popular demand I added the ability to destroy the orphan bubbles. Caution! The game is far more easier.


Pourquoi ?


Comment ?

Attention : mathématique !

Le point délicat est de trouver rapidement les collisions :

La trajectoire de la bulle est une droite d'équation y = ax + b.

Le coefficient directeur a est égal à la tangente de l'angle alpha que fait la droite avec l'axe des x.

Il y a collision si une bulle se trouve en partie dans l'espace balayé par la bulle qui est envoyée.

Dans ce cas, son centre est situé au plus à une distance 2d (mesurée horizontalement) du centre de la bulle qui est envoyée.

Cette distance d est égale au produit du rayon par le sinus de l'angle alpha.

D'où la méthode :

On calcule l'équation de la trajectoire de la bulle envoyée (coefficients a et b).

On calcule la valeur d.

On prend l'ordonnée ym du centre d'une bulle.

On calcule l'abscisse x du centre de la bulle envoyée lorsqu'elle passe sur l'horizontale (d'équation ym).

On compare le xm du centre de la bulle considérée avec x - 2d et x + 2d.

S'il est dans l'intervalle, il y a collision.

Attention : programmation !

Si le code du jeu n'est pas superbement structuré (il a été fait à la va-vite, en une dizaine de jours), il contient un certain nombre de techniques simplificatrices intéressantes pour les jeux :

Les sprites

Une seule image, grise, a servi pour les différentes tailles et couleurs de bulles. L'image a été dupliquée et redimensionnée puis sauvée en fichier. Une image tcl utilisant le fichier a permis de récupérer les data correspondant. Sur les trois composantes RGB (identiques) une seule a été conservée dans un tableau et a permis de restituer 8 couleurs différentes (C 0 0, C C 0...).

Menu/Options

Pour simplifier le menu a été regroupé avec les options. Les paramètres d'options sont sauvegardés sous forme d'un script qu'il suffit de sourcer.

Scores

Les scores ont été sauvegardés sous forme d'une liste de listes des informations à afficher. Le score et le temps restant sont affichés en permanence sur des afficheurs 7 segments qu'il est facile de faire clignoter.

Animation

L'animation est réduite à la trajectoire de la bulle envoyée et à l'effacement progressif des bulles détruites. Cet effacement progressif est réalisé en affichant des bulles de plus en plus petites (toujours le même modèle).

Asynchronisme

Comme plusieurs évènements peuvent arriver en même temps (tir, collision ou rebond et time out) un statut global a permis de synchroniser les différents modules.


    ###############################
    #
    #   Bubbles
    #
    set version 1.1
    #
    #   Copyright ulis, 2004
    #
    #   Licence NOL
    #
    # -----------------------------
    # v 1.0.3
    #         corrected ghost bubble at slot 0 0
    # v 1.1
    #         option to destroy orphan bubbles
    ###############################

  # ####################
  # Documentation
  # ####################
  # compile:
  #   use freewrap (http://sourceforge.net/projects/freewrap/)
  # install:
  #   put the executable in your path
  # use:
  #   run & play
  # ####################

    # ===========
    # package
    # ===========

    package require Tk
    catch { console hide }

    # ===========
    # images
    # ===========

    set images(8) \
    {
      00 00 00 52 f7 00 00 00
      00 52 bd c6 c6 c6 52 00
      00 52 8c 94 94 94 8c 00
      52 6b 84 8c 8c 8c 7b 63
      52 84 b5 ce ce c6 a5 52
      00 84 bd e7 e7 d6 a5 00
      00 52 94 c6 ce b5 52 00
      00 00 00 52 84 00 00 00
    }
    set images(16) \
    {
      00 00 00 00 00 00 c0 c0 c0 c0 00 00 00 00 00 00
      00 00 00 c0 c0 ef ff f7 f7 f7 ff a5 c0 00 00 00
      00 00 a5 a2 e7 de de de de de de d6 ce a0 00 00
      00 a0 a0 bd bd bd c6 c6 c6 c6 c6 bd bd a3 9a 00
      00 92 9a a5 a5 a5 a5 ad ad a5 a5 a5 a5 ab 8a 00
      00 92 90 94 9c 94 94 94 94 94 94 8c 8c 83 82 00
      80 a2 8a 8b 84 84 84 8c 8c 8c 84 84 7b 63 8a 80
      80 aa 6b 7b 84 8c 8c 8c 8c 8c 8c 84 7b 73 73 80
      80 c3 73 8c 9c a5 ad ad ad ad ad a5 94 84 7b 80
      80 c3 84 9c b5 c6 ce ce ce ce c6 bd a5 8c 73 80
      00 aa 84 a5 c6 d6 de e7 e7 e7 d6 c6 ad 8c 73 00
      00 94 84 a5 bd d6 e7 e7 e7 e7 d6 bd a5 84 8a 00
      00 a0 8b 94 b5 ce de e7 e7 de ce b5 94 73 90 00
      00 00 a0 73 94 b5 c6 ce ce c6 b5 94 73 ad 00 00
      00 00 00 a0 9c 84 a5 ad ad a5 8c 73 90 00 00 00
      00 00 00 00 00 00 80 80 80 80 00 00 00 00 00 00
    }
    set images(24) \
    {
      00 00 00 00 00 00 00 00 00 7c 46 2e 2d 45 7b 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 73 56 71 8e 9a 9a 8e 70 55 73 00 00 00 00 00 00 00
      00 00 00 00 00 90 43 8c db fc ff ff ff ff fb dc 8c 43 8f 00 00 00 00 00
      00 00 00 00 6c 45 cc fa ee e8 e6 e6 e6 e7 e7 ee fa cd 45 6c 00 00 00 00
      00 00 00 6f 3a c4 e0 d2 d5 d7 d8 d8 d8 d8 d7 d5 d2 e1 c3 39 70 00 00 00
      00 00 96 2e 86 cc be c3 c4 c5 c5 c5 c6 c5 c5 c5 c4 bf cc 86 2e 96 00 00
      00 00 41 47 95 b1 ae b1 b2 b3 b3 b4 b4 b3 b3 b2 b1 ae b1 94 47 41 00 00
      00 81 3c 4f 88 9f 9d a0 a1 a2 a3 a4 a4 a3 a2 a1 a0 9d 9f 88 50 3d 82 00
      00 55 4a 52 74 8f 8d 91 93 94 94 94 94 94 94 92 91 8e 8e 75 52 4b 4f 00
      8e 4c 52 59 64 7e 83 86 88 8a 8a 8b 8b 8b 8a 89 87 84 7f 65 59 55 43 c1
      63 4e 58 60 68 74 80 84 86 87 88 88 88 88 88 86 84 80 74 68 61 5a 49 8c
      50 52 5e 68 73 7b 83 88 8c 8d 8e 8d 8d 8e 8e 8c 87 82 7a 72 68 5e 51 64
      53 57 64 71 7f 8a 92 99 9e a0 a0 a0 a0 a0 a0 9d 98 91 87 7c 70 64 55 66
      68 59 6a 7a 8a 98 a3 ad b2 b4 b5 b5 b5 b5 b4 b1 ab a0 93 86 77 69 53 8e
      93 5e 6f 82 95 a7 b6 c0 c7 ca cb cc cc cb c9 c5 bd b0 a1 8f 7c 6c 53 c2
      00 69 6e 87 9c b1 c1 ce d5 da dc dd dd dc d9 d3 c9 ba a7 94 7f 69 61 00
      00 91 64 88 9d b2 c5 d4 dd e3 e6 e7 e7 e6 e2 d9 cd bb a7 91 7e 5d 8d 00
      00 00 64 80 97 ad c1 d1 dc e3 e7 e8 e8 e5 e0 d5 c6 b4 9e 89 75 5d 00 00
      00 00 a4 69 8f a4 b9 cb d8 e0 e5 e7 e6 e2 da cd bd aa 93 81 5e a1 00 00
      00 00 00 8e 73 99 ad c0 ce d8 de e0 df da d1 c3 b1 9c 8a 66 88 00 00 00
      00 00 00 00 90 76 99 ae bc c8 ce d1 d0 ca c0 b2 9f 8a 69 89 00 00 00 00
      00 00 00 00 00 ab 7c 8b a3 b3 ba bd bc b6 ac 9a 80 72 a6 00 00 00 00 00
      00 00 00 00 00 00 00 a0 89 8b 96 9b 9a 92 85 83 9d 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 c7 9d 86 85 9c c6 00 00 00 00 00 00 00 00 00
    }
    set images(32) \
    {
      00 00 00 00 00 00 00 00 00 00 00 00 b0 79 52 41 41 52 79 b0 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 d8 8e 58 49 55 61 66 66 61 54 48 57 8e d8 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 84 3e 51 91 c9 e6 f1 f5 f5 f1 e6 c9 91 51 3e 83 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 c0 4c 45 a6 ed fe fc f7 f5 f4 f4 f5 f8 fc fe ed a6 45 4c c0 00 00 00 00 00 00
      00 00 00 00 00 a4 3c 5c d5 f6 e9 e5 e7 e8 e8 e9 e9 e8 e8 e6 e5 e9 f6 d5 5c 3c a4 00 00 00 00 00
      00 00 00 00 a4 3a 5c d0 e4 d7 db dc dd dd de de de dd de dd dd db d7 e4 d0 5c 3a a4 00 00 00 00
      00 00 00 c0 45 4b a9 d8 ca d0 d0 d1 d1 d2 d2 d2 d2 d2 d2 d1 d1 d0 d0 cb d8 a9 4b 45 c1 00 00 00
      00 00 00 53 48 6a c2 bf c2 c3 c4 c5 c5 c6 c7 c6 c6 c6 c6 c5 c5 c4 c3 c2 c0 c2 6b 48 53 00 00 00
      00 00 87 45 50 80 b8 b2 b5 b6 b8 b9 ba ba ba bb bb bb ba ba b8 b8 b7 b5 b2 b8 7f 52 45 87 00 00
      00 d7 4c 54 53 80 ab a6 aa ac ad af af af b0 b0 b0 b0 af af ae ad ac aa a7 ab 81 54 54 4d d8 00
      00 92 44 59 58 78 9d 9c 9e a1 a3 a4 a4 a5 a6 a7 a6 a6 a5 a5 a4 a2 a1 9f 9c 9d 78 59 5a 44 93 00
      00 68 4f 5c 5f 6c 90 94 96 99 9b 9c 9d 9d 9e 9e 9e 9e 9e 9e 9c 9b 99 97 94 91 6e 60 5d 50 64 00
      b0 56 57 5f 65 6a 7f 8e 8f 92 94 96 97 97 98 98 98 98 98 97 96 95 92 8f 8f 80 6b 66 60 59 4d b0
      83 55 5b 63 6a 70 77 87 8c 90 92 94 95 96 96 96 96 95 96 96 94 93 90 8d 87 78 71 6a 64 5f 4b ba
      65 57 5f 68 70 77 7d 83 8d 91 93 95 96 97 97 96 97 97 97 97 95 93 91 8c 83 7e 77 70 68 61 52 88
      58 5a 64 6d 75 7e 86 8d 93 97 9a 9d 9e 9e 9f 9e 9e 9e 9e 9e 9d 9a 97 93 8c 85 7e 76 6d 64 58 6f
      5a 5c 67 71 7c 86 90 98 9f a4 a7 a9 ab ab ab ab ab ac ab ab a9 a6 a2 9d 96 8e 85 7b 71 68 5a 70
      6a 5e 6b 78 83 90 9a a4 ac b2 b6 b8 b9 ba ba bb ba bb ba b9 b8 b5 b0 a9 a1 97 8c 81 76 6b 59 89
      87 61 6e 7c 8a 98 a4 b0 ba c1 c5 c7 c9 ca ca ca ca ca c9 c8 c6 c2 bd b6 ab 9f 93 86 79 6d 56 b9
      b2 66 6f 80 90 a0 ae bb c7 ce d2 d6 d7 d8 d8 d8 d9 d8 d7 d6 d3 d0 c9 c0 b5 a7 99 89 7b 6e 5b b0
      00 77 6c 82 93 a4 b4 c2 d0 d8 dd e0 e2 e3 e4 e5 e5 e4 e2 e1 de d9 d2 c8 ba aa 9b 8a 7c 67 72 00
      00 9b 65 83 94 a6 b7 c7 d5 de e4 e8 ea ec ec ec ec ec ea e8 e4 df d7 cb bc ab 9a 89 7b 60 9a 00
      00 d8 6a 7e 91 a3 b4 c5 d4 e0 e6 eb ee f0 f0 f0 f0 f0 ee eb e7 e0 d6 c8 b8 a7 96 84 75 63 d8 00
      00 00 97 6d 8c 9d af c0 cf dc e6 ec f0 f1 f2 f3 f3 f1 ee eb e5 dd d1 c1 b1 9f 8e 80 65 93 00 00
      00 00 00 72 80 95 a7 b9 c9 d8 e3 eb f0 f1 f3 f3 f2 f1 ed e9 e2 d7 c9 b9 a8 96 87 74 6b 00 00 00
      00 00 00 c8 72 8b 9d b0 c1 cf dc e5 ec ef f2 f2 f1 ef eb e4 da ce bf af 9e 8c 7d 67 c6 00 00 00
      00 00 00 00 b0 71 8f a2 b3 c2 d0 da e2 e8 ea eb eb e7 e2 da cf c2 b2 a1 90 81 65 ac 00 00 00 00
      00 00 00 00 00 b0 78 8e a4 b3 c1 cc d5 db df e0 df db d5 cc c1 b3 a3 94 7f 6d ad 00 00 00 00 00
      00 00 00 00 00 00 c8 82 88 a0 b0 bb c4 cb d0 d1 d0 cd c5 bc b2 a3 93 7b 77 c5 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 a1 85 8e 9f ae b5 b9 bb ba b7 b1 a7 97 85 7d 9c 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 d8 ae 93 8c 92 9b 9d 9c 98 8f 88 8f aa d8 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 dc bb 98 8d 8c 97 bb dc 00 00 00 00 00 00 00 00 00 00 00 00
    }
    set images(40) \
    {
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ce 9e 7a 5c 52 52 5d 7a 9d ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 de a6 6e 4d 42 42 44 44 44 44 41 42 4d 6e a5 de 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 d9 89 49 34 4e 79 a0 ba c6 cc cc c6 b9 a0 79 4d 35 49 89 d9 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 9c 49 37 69 b4 e7 fd fe fe fe fe fe fe fe fe fd e7 b4 69 36 48 9c 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 6e 37 53 b0 f1 fd f5 f0 ee ee ef ef ef ef ef ee f0 f5 fd f1 af 53 37 6d 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 cb 57 3a 67 d5 f5 e8 e5 e7 e9 e8 e9 e9 ea e9 ea e9 e9 e8 e7 e5 e8 f6 d5 68 3b 57 cb 00 00 00 00 00 00
      00 00 00 00 00 cd 4e 41 64 d5 e7 da df df df e0 e0 e0 e0 e1 e1 e0 e1 e0 df e0 df df da e7 d5 65 40 4e cd 00 00 00 00 00
      00 00 00 00 00 56 45 54 be dc d0 d5 d6 d6 d6 d7 d7 d7 d7 d8 d8 d7 d7 d7 d6 d7 d5 d5 d5 d0 dc bd 54 45 56 00 00 00 00 00
      00 00 00 00 6d 45 4b 88 d3 c6 ca cb cb cc cd cd cd cd cd cd cd ce cd ce cc ce cc cc cb ca c6 d3 87 4b 45 6c 00 00 00 00
      00 00 00 97 3f 53 53 ad c1 bd c0 c1 c1 c3 c3 c4 c4 c5 c4 c5 c5 c5 c4 c4 c3 c4 c2 c1 c1 c0 bd c1 ad 54 53 3f 97 00 00 00
      00 00 d8 4d 50 50 65 b1 b3 b4 b5 b7 b8 b9 ba ba bb bb bb bc bc bb bb bb ba b9 b9 b9 b7 b6 b5 b3 b2 66 51 50 4d d8 00 00
      00 00 89 43 56 53 6b ab aa ab ad ae af b0 b1 b2 b2 b2 b3 b3 b3 b3 b3 b2 b2 b1 b1 af af ad ac aa ab 6b 53 57 45 89 00 00
      00 d9 52 50 57 57 6a a0 a0 a2 a3 a5 a7 a8 a9 a9 aa aa ab ab aa aa aa aa a9 a9 a8 a7 a6 a4 a2 a0 9f 6a 57 57 50 52 db 00
      00 a0 45 57 59 5c 66 92 99 9a 9b 9e 9f a1 a1 a1 a2 a3 a3 a3 a3 a3 a3 a3 a2 a1 a0 9f 9e 9d 9a 98 93 66 5d 5a 57 45 a3 00
      00 75 4a 59 5c 62 64 82 93 92 96 97 99 9b 9b 9c 9c 9c 9d 9d 9d 9e 9d 9e 9d 9b 9a 99 98 96 92 94 83 65 62 5d 5b 4d 73 00
      ca 5c 52 5c 5f 64 68 74 8b 8e 90 91 93 95 96 97 97 98 98 99 99 98 98 97 97 97 96 93 92 90 8d 8c 74 69 65 60 5c 54 53 00
      9a 55 56 5e 63 68 6e 71 7f 8b 8c 8f 91 93 94 95 96 96 96 96 97 96 96 96 95 94 94 92 90 8d 8b 7f 72 6e 69 63 5e 5a 49 d4
      7c 54 5a 60 66 6c 72 77 7c 85 8d 8f 92 94 94 95 96 96 96 96 96 96 96 95 96 94 93 92 8f 8c 85 7c 78 73 6e 68 62 5d 4c ac
      62 57 5d 64 6b 71 77 7d 82 87 8c 91 93 95 97 98 97 98 99 98 98 98 99 98 98 97 96 93 91 8d 86 82 7e 77 72 6c 64 5e 53 82
      59 58 5f 68 6f 76 7d 83 89 8f 93 97 9a 9c 9e 9f 9f 9f 9f 9f 9e 9f a0 9e 9f 9e 9c 99 97 93 8e 88 83 7c 76 6f 68 61 56 73
      5a 5a 62 6b 73 7b 83 8b 92 98 9d a1 a5 a7 a9 aa aa aa aa ab aa aa ab a9 aa a8 a6 a3 a0 9b 96 90 89 82 7b 73 6b 63 58 73
      65 5c 65 6e 78 81 8a 93 9a a1 a8 ac b0 b2 b4 b5 b6 b5 b6 b6 b6 b6 b6 b5 b4 b3 b2 ae ab a5 9e 97 8f 87 7f 76 6d 65 58 82
      80 5e 67 72 7c 87 91 9a a3 ab b3 b8 bd bf c0 c1 c2 c2 c3 c2 c2 c3 c2 c1 c1 bf bd ba b5 b0 a8 9f 96 8d 83 7a 70 68 54 ac
      9d 61 68 75 80 8b 97 a1 ac b5 be c3 c7 ca cc cd ce ce ce ce ce cf ce cd cc ca c8 c4 bf b8 b0 a6 9c 92 86 7c 71 68 55 d2
      c8 6a 68 77 83 91 9c a8 b4 be c7 cd d1 d5 d7 d8 d9 d9 da da da d9 d9 d8 d7 d5 d2 ce c8 c0 b8 ad a1 95 89 7d 73 66 60 00
      00 81 63 79 85 92 9f ad b9 c4 cf d5 d9 dc de e0 e2 e3 e3 e3 e3 e3 e2 e1 df dd da d5 cf c7 bb af a3 97 8a 7e 74 61 7c 00
      00 a7 60 78 85 93 a2 af bc c8 d2 db e0 e4 e6 e8 e9 ea ea eb ea ea e9 e8 e6 e3 df db d3 cb be b1 a4 97 8a 7c 73 5b a7 00
      00 d9 6b 75 83 92 a1 b0 bd c9 d4 de e3 e7 eb ed ee ee ef ee ee ee ed ec e9 e7 e2 dc d4 ca bd b0 a2 95 87 7a 6d 66 da 00
      00 00 96 69 81 8e 9d ab ba c6 d2 dc e4 e9 ed ef f0 f1 f1 f0 f1 f0 f0 ee ea e7 e3 db d1 c5 b9 ab 9d 8f 81 78 61 93 00 00
      00 00 d8 6c 7a 89 98 a7 b5 c3 cf d9 e3 e9 ec ef f0 f2 f3 f3 f2 f2 f0 ed ea e6 e0 d7 cc c0 b3 a5 97 8a 7d 70 66 d7 00 00
      00 00 00 a1 69 85 91 a0 af bd c9 d5 df e6 ec ef f0 f3 f3 f3 f2 f1 f0 ec e9 e3 db d2 c6 b9 ac 9e 91 83 79 60 9d 00 00 00
      00 00 00 00 87 76 8c 99 a8 b7 c3 cf da e3 e8 ee f0 f1 f3 f3 f2 f1 ef eb e7 e0 d6 cb bf b2 a4 96 89 7e 6a 81 00 00 00 00
      00 00 00 00 00 7a 7c 90 9d ac bb c7 d2 db e2 e8 ec ef f0 f0 f0 ee eb e6 df d7 cd c2 b4 a9 9a 8c 82 6f 71 00 00 00 00 00
      00 00 00 00 00 cf 74 7f 93 9f af bb c7 d0 d8 df e3 e7 e9 e9 e8 e6 e3 de d6 cd c2 b7 aa 9d 8e 84 73 6b cd 00 00 00 00 00
      00 00 00 00 00 00 cd 7e 7f 95 a0 ad ba c5 cd d4 d9 dd de e0 df dc d8 d3 cb c3 b8 ab 9d 90 86 72 74 cb 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 8d 7c 93 a0 ab b6 c0 c7 cd d1 d3 d4 d3 d0 cc c6 bf b6 aa 9d 94 85 70 85 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 aa 80 88 99 a6 ae b6 bc c0 c3 c4 c3 c1 bd b6 af a6 9c 8f 7e 76 a6 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 d7 a0 86 89 95 a1 a8 ac ae af af ac a9 a3 9b 8f 81 7f 9c d6 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 db b7 98 89 8a 91 97 97 97 95 8e 87 86 95 b5 db 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cd ad 92 8f 8e 91 ac cd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    }
    set images(bg) \
    {
      #8ede8e
      #8bbb8b
      #81b181
      #8ccc8c
      #8bdb8b
      #8fcf8f
      #87c787
      #8bcb8b
      #8ddd8d
      #8cbc8c
    }

    # ===========
    # procs
    # ===========

    # -----------
    # create the bubble images
    # -----------
    proc CreateImages {} \
    {
      Trace 1 "CreateImages"
      for {set d $::Size} {$d > 0} {incr d -8} \
      {
        # create images
        array unset datas
        for {set n 0} {$n < 8} {incr n} \
        { image create photo img$d-$n }
        # compute data
        set data $::images($d)
        set ndx -1
        for {set i 0} {$i < $d} {incr i} \
        {
          array unset rows
          set first 0
          set last 0
          for {set j 0} {$j < $d} {incr j} \
          {
            set c [lindex $data [incr ndx]]
            set cc [scan $c %x]
            set c2 [format %2.2x [expr {round($cc * 0.5)}]]
            set c3 [expr {round($cc * 1.25)}]
            if {$c3 > 255} { set c3 255 }
            set c3 [format %2.2x $c3]
            lappend rows(0) #${c}${c}${c}   ; # white
            lappend rows(1) #${c}0000       ; # red
            lappend rows(2) #00${c}00       ; # green
            lappend rows(3) #${c}${c}00     ; # yellow
            lappend rows(4) #00${c}${c}     ; # indigo
            lappend rows(5) #${c}00${c}     ; # violet
            lappend rows(6) #${c}${c2}00    ; # orange
            lappend rows(7) #${c2}${c2}${c2}; # gray
          }
          for {set n 0} {$n < 8} {incr n} \
          { lappend datas($n) $rows($n) }
        }
        # put images data
        for {set n 0} {$n < 8} {incr n} \
        { img$d-$n put $datas($n) }
        # set transparency
        catch \
        {
          set ndx -1
          for {set i 0} {$i < $d} {incr i} \
          {
            for {set j 0} {$j < $d} {incr j} \
            {
              set c [lindex $data [incr ndx]]
              if {$c == 0} \
              {
                for {set n 0} {$n < 8} {incr n} \
                { img$d-$n transparency set $i $j 1 }
              }
            }
          }
        }
      }
      # create background
      image create photo imgbg -width 1000 -height 1000
      imgbg put $::images(bg) -to 0 0 1000 1000
    }
    # -----------
    # init the game dialog
    # -----------
    proc CreateDialog {} \
    {
      Trace 1 "CreateDialog"
      # create background
      # create digits areas
      catch { destroy .f1}
      frame .f1
      canvas .f1.bg -width 1000 -height 1000 -bd 0 -highlightth 0
      .f1.bg create image 0 0 -anchor nw -image imgbg
      place .f1.bg -in .f1 -relx 0 -rely 0
      CreateDigitsCanvas $::StepDisplay ::Step
      CreateDigitsCanvas $::ScoreDisplay ::Score
      CreateDigitsCanvas $::GrandScoreDisplay ::GrandScore
      button $::OptionsButton -width 10 -text Options -command Options -relief groove -padx 5 -pady 5
      grid  $::StepDisplay \
            $::ScoreDisplay \
            $::GrandScoreDisplay \
            $::OptionsButton \
        -padx 10 -pady 5
      grid .f1 -row 0 -sticky ew
      # create game area
      CreateBubblesCanvas
      # center
      CenterDialog .
    }
    proc CreateDigitsCanvas {canvas variable} \
    {
      # create canvas
      set size $::CanvasSize($canvas)
      canvas $canvas -bg gray85 -relief sunken \
        -width [expr {$size * 20 + 10}] -height 32 \
        -bd 1 -highlightth 0 -selectborderwi 0
      # create digits
      set x 10
      set y 5
      for {set i 0} {$i < $size} {incr i} \
      {
        CreateDigit $canvas $i $x $y
        incr x 20
      }
      set ::CanvasValue($canvas) 0
      # link variable
      trace add variable $variable write [list SetNumber $canvas $variable ""]
    }
    proc CreateBubblesCanvas {} \
    {
      # create frame
      catch { destroy .f2}
      frame .f2
      canvas .f2.bg -width 1000 -height 1000 -bd 0 -highlightth 0
      .f2.bg create image 0 0 -anchor nw -image imgbg
      place .f2.bg -in .f2 -relx 0 -rely 0
      # create count down canvas
      canvas $::TimeDisplay -relief sunken \
        -width 21 -height $::Height \
        -bd 1 -highlightth 0 -selectborderwi 0
      $::TimeDisplay create rectangle 1 1 20 $::Height \
        -outline "" -fill green -tags used
      $::TimeDisplay create rectangle 1 1 20 0 \
        -outline "" -fill red -tags left
      # create game area
      canvas $::BubblesDisplay -bg gray75 -relief sunken \
        -width [expr {$::Width + 1}] -height $::Height \
        -bd 1 -highlightth 0 -selectborderwi 0
      $::BubblesDisplay config -scrollregion [list 0 0 $::Width $::Height]
      $::BubblesDisplay xview scroll 1 uJL