Il ne nous reste plus que le tir à implémenter et notre exemple de shoot ‘em up sera terminé.
Le principe est simple, une fois que la touche ESPACE sera appuyée, on va déclencher le tir et indiquer qu’il faut déplacer le laser en activant une variable indbal
(indicateur de balle tirée), pendant ce déplacement du laser on va surveiller 2 choses :
Dans le cas 1, si le cas arrive c’est le déclenchement de l’explosion et le jeu recommence.
Dans le cas 2, si cela arrive on remettra on fera disparaitre le laser et on remettra indbal en l’état intial pour permettre à nouveau de tirer.
Voici ce que donne l’algorithme que l’on codera ensuite :
![orga](/tuto asm 01/11/images/1.png?classes=shadow)
Comme on a initialisé le jeu avec toutes les variables à 1, si la touche espace n’est pas appuyée dans la boucle principale du programme, elle ignorera les 2 autres conditions (indbal et indcol égales à zéro).
Si on appuie sur la touche espace, on déclenche le tir au niveau des coordonnées de la fusée et on change la variable indbal qui servira à :
TIRBAL
).FEU
).La routine FEU:
Comme on vient de tirer : indbal=0 maintenant
Et la boucle principale appelle la routine de déplacement de la balle (ou du laser si vous préférez).
Cette routine ne fait que :
DEPBAL:
)Elle appelle donc 3 fois DEPBAL
sinon le déplacement d’un pixel serait trop lent à l’affichage.
Puis elle active un registre existant du MSX (en VRAM) qui surveille si des SPRITES entrent en collision. Ce registre est consulté via un CALL 318
.
Si parmi les 8 bits qui composent ce registre, le bit 5 est à 1 alors c’est qu’il y a collision.
Du coup, on met à jour une variable à nous que l’on a appelé indcol
et qui nous permettra de déclencher l’explosion dans la boucle principale.
Voici le code :
Cette routine ne fait que déplacer le sprite laser d’un pixel vers le haut et vérifie si le laser est arrivé à lextrémité haute de l’écran (Y=0).
Si c’est le cas, il faut que le laser soit réinitialisé, donc caché de l’écran et à disposition pour un nouveau tir.
Pour cela on change les coordonnées du sprite laser et on repasse indbal
à 1 via une sous-routine HAUT:
Voici le code :
La boucle principale teste à chaque fois si indcol=0 (une collision a eu lieu).
Elle appelle alors la routine EXPLO:
i qui va produire une explosion.
Le mode écran est tout d’abord réinitialisé en mode 3 (multicouleur), les tables de la VRAM sont remplies avec des valeurs aléatoires qui affichera des carrés de toutes les couleurs, ce processus est appelé plusieurs fois et la routine finie par appeller la routine DEBUT:
qui fait recommencer le jeu avec des variables remises à 1.
et voici :
Il ne nous reste plus qu’à compléter la boucle principale pour tester la touche espace (lignes 27 à 30 du code ci-dessous) et tester les variables (lignes 10 à 17 du code ci-dessous).
DEBUT: ; c’est ici que débute le programme !!! call INIT ; on appelle le sous-prog INIT BOUCLE: ; c’est la boucle principale du programme !!! call DEPENV ; on appelle le déplacement de l’envahisseur call DELAI ; on appelle le sous-prog DELAI afin de ralentir l’exécution ld a,[indcol] ; on charge la valeur de indcol dans a inc a ; on fait un calcul sur a dec a jp z,EXPLO ; si a=0 alors on appelle EXPLO ld a,[indbal] ; on charge la valeur de indbal dans a inc a ; on fait un calcul sur a dec a call z,TIRBAL ; si a=0 alors on appelle TIRBAL ld a,8 ; on teste la touche gauche = ligne 8 de la matrice du clavier call 321 ; (bios) SNSMAT retourne dans la valeur de la ligne 8 bit 4,a ; bit teste la colonne 4 (0=pressé 1=non pressé) call z,FUSGAU ; si résultat=0 on va au sous-prog FUSGAU (déplacer à droite) call DELAI ; on ralenti l’exécution ld a,8 ; la touche droite est aussi sur la ligne 8 de la matrice call 321 ; on appelle le bios pour qu’il donne la valeur de la ligne 8 bit 7,a ; la colonne 7 est testée (0=pressé 1=non pressé) call z,FUSDRO ; si résultat=0 on va au sous-prog FUSDRO (déplacer àgauche) ld a,8 ; on teste la touche espace=ligne 8 de la matrice du clavier call 321 ; on appelle le bios pour qu’il donne la valeur de la ligne 8 bit 0,a ; la colonne 0 est testée (0=pressée) call z,FEU ; si résultat=0 on va au sous-prog FEU (déclenchement laser) call DELAI ; on ralenti l’exécution jp BOUCLE ; on redémarre la boucle principale
Comme d’habitude je vous donne le code final mis à jour à compiler et à vérifier avec votre émulateur :