10-12 Analyse des fins de tour

10-12-1 Etude du franchissement de la ligne

 

Après avoir regardé si la voiture n’était pas dans le décor, on regarde si elle franchit la ligne d’arrivée (qui est aussi la ligne de départ). Mais ceci ne se fait que si la voiture est en mouvement, autrement dit si sa vitesse n’est pas nulle, ou si les délais de ralentis sont passés. Sinon le programme saute à l’analyse des touches.

 

FINCOURS LD HL,VITESSE          ; HL pointe la vitesse de la voiture

         LD A,(HL)              ; A = vitesse

         OR A                   ; Vitesse nulle?

         JP Z,TOUCHES           ; Oui => TOUCHES

 

         CP 2                   ; Analyse par rapport à Vitesse 3

         JR C,FINCOUR1          ; Vitesse 1 => FINCOUR1

         JR Z,FINCOUR2          ; Vitesse 2 => FINCOUR2

         JP FINCOUR3            ; Vitesse 3 => FINCOUR3

 

FINCOUR1 LD A,(DELAIV1)         ; A = actuel délai de la vitesse 1

         CP 1                   ; Délai = 1? (délai terminé)

         JR Z,FINCOUR3          ; oui => FINCOUR3

         JP TOUCHES             ; Sinon => TOUCHES

 

FINCOUR2 LD A,(DELAIV2)         ; A = actuel délai de la vitesse 1

         CP 1                   ; Délai = 1? (délai terminé)

         JP NZ,TOUCHES          ; non => TOUCHES

 

On regarde ensuite si la voiture se trouve entre les coordonnées YGRMIN et YGRMAX, qui sont les coordonnées de la grille de départ. Ces coordonnées ont été initialisées dans l’intro et servent donc maintenant. L’analyse se fait par soustractions par rapport à la coordonnée Y de la voiture. Si ce n’est pas le cas, le programme saute à l’analyse des touches.

 

FINCOUR3 LD A,(YVOITURE)       

         LD B,A                 ; B = coordonnée Y de la voiture

 

         LD A,(YGRMIN)          ; A = YGRMIN (Ligne la plus haute à l'écran)

         SUB B                  ; A = YGRMIN - YVOITURE

         JP NC,TOUCHES          ; Si Y < YGRMIN => TOUCHES

 

         LD A,(YGRMAX)          ; A = YGRMAX (Ligne la plus basse à l'écran)

         SUB B                  ; A = YGRMAX - YVOITURE

         JP C,TOUCHES           ; Si Y > YGRMAX => TOUCHES

 

Si YGRMIN ≤ YVOITURE ≤ YGRMAX alors on teste la coordonnée X. Mais il y a un problème : la vitesse de la voiture. Pour les vitesses 1 à 3, la voiture se déplace de pixel en pixel. Mais pour la vitesse 5, elle se déplace tous les 3 pixels, on ne peut donc pas tester une coordonnée X précise. Comme pour les Y, il faut donc tester un écart compris entre XGR – 1 et XGR + 1 (XGR étant la coordonnée X de la grille de départ). On commence par XGR – 1, puis on incrémente de 1 jusqu’à XGR + 1.

 

         LD DE,(XVOITURE)       ; DE = coordonnée X de la voiture

         LD HL,(XGR)            ; HL = coordonnée X de la grille de départ

         PUSH HL

         DEC HL                 ; HL = XGR - 1

         XOR A                  ; Carry = 0

         SBC HL,DE              ; HL <= (XGR-1) - XVOITURE

         JP Z,FINCOUR6          ; X voiture = XGR-1 => FINCOUR6

         POP HL

         PUSH HL

         XOR A                  ; Carry = 0

         SBC HL,DE              ; HL <= XGR - XVOITURE

         JP Z,FINCOUR6          ; X voiture = XGR => FINCOUR6

         POP HL

         INC HL                 ; HL = X + 1

         XOR A                  ; Carry = 0

         SBC HL,DE              ; HL <= (XGR+1) - XVOITURE

         JP Z,FINCOUR6          ; X voiture = XGR+1 => FINCOUR6

 

Mais il y a un autre problème lié à la vitesse de la voiture. C’est que quand la vitesse de la voiture est inférieure à 4, elle se déplace par pas de 1 pixel. Donc à ce moment, le test est validé 3 fois de suite. Ainsi il ne suffit pas, car sinon les 3 tours seraient validés en 1 fois. Donc tant que la voiture se trouve sur la grille, on met la variable DRAPGR à 1 si elle est dans le bon sens (voir plus bas). Et si la voiture ne se trouve est sortie de la limite de XGR + ou – 1 et que cette variable est à 1, alors un tour est passé. On remet alors cette variable à 0 et le nombre de tours est décrémenté. Mais attention, si la voiture était dans le mauvais sens (DRAPGR = 2), alors on rajout un tour.

 

         LD A,(DRAPGR)          ; A = drapeau de franchissement de ligne

         OR A                   ; Drapeau = 0?

         JP Z,TOUCHES           ; oui => TOUCHES

         DEC A                  ; Drapeau = 1 (ligne franchie dans le bon sens)?

         JR Z,FINCOUR4          ; oui => FINCOUR4

        

         XOR A                  ; ligne franchie dans le mauvais sens

         LD (DRAPGR),A          ; Drapeau remis à 0

         LD A,(TOURS)           ; A = nombre de tours restant

         INC A                  ; Tours + 1

         LD (TOURS),A           ; nombre de tours mémorisé

         JP FINCOUR5

 

FINCOUR4 LD (DRAPGR),A          ; Drapeau remis à 0

         LD A,(TOURS)           ; A = nombre de tours restant

         DEC A                  ; Tours - 1

         LD (TOURS),A           ; nombre de tours mémorisé

 

Dans tous les cas on affiche le nombre de tours. Si en plus il est égal à 0, on saute à GAGNE.

 

FINCOUR5 LD HL,&C322            ; HL pointe le chiffre des tours à l'écran

         CALL AFFICHE           ; Affiche le nombre de tours

         OR A                   ; Nombre de tours = 0?

         JP NZ,TOUCHES          ; non => TOUCHES

         JP GAGNE               ; oui => gagné!

 

Si les coordonnées X et Y correspondent, c’est que la voiture se trouve sur la grille. C’est à ce moment que DRAPGR est placé soit à 1, soit à 2. Ce qui fait la différence, c’est l’angle de la voiture. En effet, on ne va quand même pas enlever un tour si la voiture par en sens inverse ! car sinon il suffit de faire 2 petits aller retours sur la ligne pour gagner. Donc si la voiture est dans le bons sens, alors DRAPGR = 1, sinon il est égale à 2. Les angles sont numérotés comme suit :

 

 

 

L’angle de départ est soit 0 soit 4. Donc les sens admis sont soient (7, 0, 1) pour l’angle 0, soient (3, 4, 5) pour l’angle 4. Tout autre angle est alors considéré comme le sens contraire (y compris 2 et 6). Comme pour les X, on commence par ANGLEDEP + 1, puis ANGLEDEP puis ANGLEDEP – 1. Dans ce dernier cas, on veille bien à ce que –1 redonne 7 par un AND.  

 

FINCOUR6 LD A,(ANGLE)           ; A = angle de la voiture

         LD B,A

 

         LD A,(ANGLEDEP)        ; A = angle de départ

         INC A                  ; A + 1 pour analyse +1, 0 et -1

         LD C,B                 ; C = angle de la voiture

         CP C                   ; angle = angle de départ + 1?

         JR Z,FINCOUR7          ; oui => FINCOUR7

         DEC A                  ; A = angle de départ + 0

         CP C                   ; angle = angle de départ?

         JR Z,FINCOUR7          ; oui => FINCOUR7

         DEC A                  ; A = angle de départ - 1

         AND %00000111          ; Pour le 7

         CP C                   ; angle = angle de départ - 1?

         JR Z,FINCOUR7          ; oui => FINCOUR7

 

         LD A,2                 ; Indique grille franchie dans le mauvais sens

         LD (DRAPGR),A          ; Drapeau de grille franchie mis à jour

         JP TOUCHES             ; Puis on passe aux touches

 

FINCOUR7 LD A,1                 ; Indique grille franchie dans le bon sens

         LD (DRAPGR),A          ; Drapeau de grille franchie mis à jour

         JP TOUCHES             ; => TOUCHES

 

 

10-12-2 Gagné !

 

Si les 3 tours ont été franchis (TOURS = 0), alors c’est gagné. On dessine donc le rectangle vert entouré de blanc, puis on affiche « GAGNE ! » pendant 2 secondes.

 

GAGNE    CALL BOITE             ; Dessin de la boite de dialogue

         LD A,18                ; LOCATE 18,12 pour affichage

         CALL &BB6F             ; du texte

         LD A,12

         CALL &BB72

         LD HL,TEXTE1           ; Affichage de "GAGNE !"

         CALL PRINTF

 

         LD A,100

         CALL TEMPO             ; Tempo de 2 secondes (100/50èmes)

 

Mais on ne s’arrête pas là. En effet, il faut maintenant regarder si le joueur a fait le meilleur temps de la course. Les temps sont placés en mémoire de la manière suivante :

 

TEMPS    DS 3                   ; Temps dans la partie en cours = &xx m &xx s &xx

TEMPS1   DS 3                   ; Meilleur temps de la partie 1 (en BCD)

TEMPS2   DS 3                   ; Meilleur temps de la partie 2 (en BCD)

TEMPS3   DS 3                   ; Meilleur temps de la partie 3 (en BCD)

 

NCOURSE est le n° de la course actuelle (1, 2 ou 3). Donc l’adresse mémoire du meilleur temps de la course actuelle est :

 

HL = TEMPS + 3 x NCOURSE

 

C’est ce qu’on calcule ici :

 

         LD A,(NCOURSE)         ; A = n° de la course courante

         LD B,A

         SLA A

         ADD B               

         LD E,A

         LD D,0                 ; DE = 3 x n° de course

         LD HL,TEMPS            ; HL pointe les temps

         ADD HL,DE              ; HL pointe le temps du n° de course

         PUSH HL               

 

On commence ensuite par comparer les minutes (TEMPS et HL + 0). Si les minutes de TEMPS sont inférieures aux meilleures minutes contenue dans HL, alors le joueur a fait le meilleur temps. Sinon on regarde les secondes puis les centièmes. Si le temps est supérieur, on revient simplement à l’initialisation générale avant intro (INITVAR).

 

         LD A,(TEMPS)           ; A = minutes de la partie gagnée

         LD B,(HL)

         CP B

         JR C,GAGNE3            ; minutes gagnées < meilleures minutes? => GAGNE3

         JR Z,GAGNE1            ; minutes égales? => GAGNE1

         JP INITVAR             ; Pas le meilleur temps => INITVAR

 

GAGNE1   LD A,(TEMPS+1)         ; A = secondes

         INC HL

         LD B,(HL)

         CP B

         JR C,GAGNE3            ; secondes gagnées < meilleures secondes? => GAGNE3

         JR Z,GAGNE2            ; secondes égales? => GAGNE2

         JP INITVAR             ; Pas le meilleur temps => INITVAR

 

GAGNE2   LD A,(TEMPS+2)         ; A = centièmes

         INC HL

         LD B,(HL)

         CP B

         JP NC,INITVAR          ; temps égaux ou supérieurs => INITVAR

 

S’il y a meilleur temps, celui-ci est mémorisé, puis on affiche « MEILLEUR TEMPS ! » pendant 2 secondes avant de reboucler à INITVAR.

 

GAGNE3   POP DE                 ; DE pointe le meilleur temps de la course courante

         LD HL,TEMPS            ; HL pointe le temps gagné

         LD BC,3                ; 3 nombres à mémoriser

         LDIR                   ; mémorisation du meilleur temps

 

         LD A,13                ; LOCATE 13,12 pour affichage

         CALL &BB6F             ; du texte

         LD A,12

         CALL &BB72

         LD HL,TEXTE2           ; Affichage de "MEILLEUR TEMPS!"

         CALL PRINTF

         LD A,100

         CALL TEMPO             ; Tempo de 2 secondes (100/50èmes)         

         JP INITVAR

 

 

<< RETOUR  ---  SUITE : Gestion du clavier et du joystick >>