La raquette c'est 5 ou 7 caractères contigus à afficher. Il en sort une propriété intéressante : je n'ai pas besoin de coordonnées X et Y. En effet, la position m'est donnée directement par son adresse en VRAM (qui commence en $D000) et comme la ligne 23 (40 caractères en largeur) est comprise ente $D398 et $D3C0, je peux me limiter à considérer l'octet de poids faible de cette adresse pour confiner la raquette dans une intervalle légèrement plus petite en magnitude que ]$98, $B6[ (la magnitude est de 30 et non 40 caractères lors du jeu).
Pour bouger il me suffit d'incrémenter ou de décrémenter le poids faible de son adresse en restant dans l'intervalle adaptée à la dimension de la raquette. Pour gérer le rebond de la balle, je teste d'abord si la position Y de la balle est 23 et si c'est le cas, je vérifie que le poids faible de l'adresse calculée de la balle est dans l'intervalle des poids faibles min et max de l'adresse de la raquette.
Ça fonctionne bien mais il y a un hic : il y a 50 images par seconde, donc 50 déplacements de la raquette par seconde ! j'ai beau appuyé et relâché le plus court possible, ma raquette bouge pas moins de deux caractères.
Pour m'assurer que la boucle de jeu reste simple, j'ai décidé de rajouter une "vitesse" et une "accélération" à la raquette. A 50 FPS, n'espérez pas quelque chose de fluide à cause de la représentation en caractère : il s'agit de permettre faire le mouvement de 1 caractère immédiat avec une accélération exponentielle pour embrayer sur un déplacement rapide en touche continue.
Comment ? je procède comme si j'avais un nombre fixe 16.8 au lieu de 16.0 initialement. La partie fractionnaire ne sert pas de position mais de valeur initiale de "vitesse". Il sera toujours 128 sans déplacement, de 0 à l'amorce de déplacement à gauche et de 255 à droite. L'accélération est également initialisée au changement de direction à une valeur arbitraire (actuellement 00011111b - plus elle est petite, plus la raquette mettra du temps à rentrer en vitesse optimale après le déplacement initial).
Voici comment j'incrémente/décrémente la position de la raquette avec une pseudo vitesse et une pseudo accélération :
Code : Tout sélectionner
RACKET_ACCEL EQU 00011111b ; valeur la plus grande qui me permet un déplacement de 1 caractère sans artefacts par la suite
...
@1: JR Z,@0f ; direction positive, on saute car c'est déplacement à gauche là
LD A,(DE) ; DE contient l'adresse de l'octet "vitesse" de la raquette
move_racket_laccel: ; accélération à gauche
SUB RACKET_ACCEL ; ici, on devrait avoir un nombre de type -((2^n)-1)
DEC A ; mais on veut faire -(2^n) !
LD (DE),A ; mise à jour de la vitesse
LD BC,0 ; joie du Z80 avec ses limitations en 16-bit
SBC HL,BC ; met à jour l'addrese de position de la raquette
LD A,L ; mais à ce niveau seul le poids faible compte
move_racket_posmin:
CP RACKET_POSITION_MIN+3 ; "leftmost" position?
JR Z,@2b
LD (racket_new_position),HL ; Met à jour la position à raquette
LD HL,move_racket_laccel+1 ; accélère "exponentiellement" la vitesse à gauche
SLL (HL) ; multiplie par 2 et rajoute 1 en bit 0 et cape la valeur à 255 !
RET ; c'est fini
@0: LD A,(DE)
move_racket_raccel: ; même chose mais à droite !
ADD A,RACKET_ACCEL ; ici, on devrait avoir un nombre de type +(2^n)-1
INC A ; mais on veut faire +(2^n) !
LD (DE),A
LD BC,0
ADC HL,BC
LD A,L
move_racket_posmax:
CP RACKET_POSITION_MAX-2 ; "rightmost" position?
JR Z,@2b
LD (racket_new_position),HL
LD HL,move_racket_raccel+1 ; accélère "exponentiellement" la vitesse à droite
SLL (HL) ; multiplie par 2 et rajoute 1 en bit 0 et cape la valeur à 255 !
RET