CODING ★ DE L'ARCADE A L'ACTION ★

De l'Arcade de l'Action n°31

Je tire ce mois-ci mon chapeau à Robby qui m'a sorti d'un beau pétrin. Comme vous l'avez constaté le mois passé, les forces du CACA m'avaient joué un mauvais tour et grâce au PIPI je suis de retour et sans aucune égratignure.

Vous l'avez remarqué? La vie des rédacteurs à Cent Pour Cent n'est pas de tout repos. Imaginez qu'à l'approche de l'hiver, on doit travailler les fenêtres grandes ouvertes pour ne pas confondre la rédaction avec des toilettes publiques. M'enfin, l'erreur est réparée, les locaux nettoyés et voici tous les listings manquants pour animer vos sprites dans le plus grand délire, en fonction des limites de votre imagination.

Qui plus est, nous allons voir quelques détails qui ne vous paraissent pas très clairs, comme les pointeurs de sprites, les tests de collision et les coordonnées des sprites à l'écran.

UN POINTEUR
VAUT MIEUX
QUE DEUX TU L'AURAS

Bon OK on vous l'a déjà servi à toutes les sauces mais ça fait toujours plaisir de réciter ses classiques.
On avait vu ensemble comment mettre en mémoire des sprites. L'ensemble est, disons, sotcké à partir de l'adresse 10000. Vous avez, supposons, trois sprites.

Le héros, qui fait 6 octets sur 16 lignes, le méchant qui, lui, est plus gros (8 octets sur 20 lignes) ; enfin la balle de votre canon laser à plasma auto refroidissant qui fait 3 octets sur 4 lignes. Ils sont tous sauvés à partir de l'adresse 10000 et dans l'ordre sus-cité.

On calcule, à tête reposée, la taille des chacune des bestioles: le héros fait 6 sur 16, donc 96 octets, le méchant, lui, 160 octets et la balle 12 octets.

Sachant que tous les assembleurs possèdent la mnémonique EQU, il suffit de l'utiliser pour éviter de longs calculs inutiles. En début de programme on donne l'équivalent des adresses de sprtie. Voici la méthode:

ADRESSE EQU 10000
HEROS   EQU ADRESSE
MECHANT EQU HEROS+96
BALLE   EQU MECHANT + 160

A partir de là, on ne travaillera plus qu'avec de simples mots qui seront automatiquement traduits par l'Assembleur. Si après avoir fait ces déclarations, vous utilisez l'adresse MECHANT, le calcul se fera automatiquement.

Exemple: LD HL,MECHANT, fera pointer HL sur la zone mémoire contenant les données du vilain.
De même, pour la longueur et hauteur de chaque sprite, la mnémonique EQU peut être utilisée.

HERO-LON EQU 6
HERO-HAU EQU 16
MECH-LON EQU 8
MECH-HAU EQU 20
BALL-LON EQU 3
BALL-HAU EQU 4

Pour être complet, imaginons le pire. Vous voulez utiliser une seule routine d'affichage pour animer tous les méchants pas beaux de votre méga jeu. Il va de soi que pour rester dans le genre "plus chiant que moi tu meurs", les sprites sont de longueur et de hauteur différentes.

UN PASSE-PARTOUT PAS CHER

Dans un premier temps, on réfléchit à voix haute. Quels sont les paramètres qui différencient les sprites, hum?

Il s'agit de la longueur, la hauteur et de l'adresse d'implantation en mémoire, OK ? On prépare pour cela une table avec toutes les données, à savoir les paramètres de tous les sprites dans un ordre que je vous laisse libre de choisir.

Dans notre exemple, je nommerai le héros, n° 1 , les méchants, n°2 , et la balle, n°3. Voici la tête de ma table.

TABLE DW HEROS
      DB HERO-LON,HERO-HAU
      DW MECHANT
      DB MECH-LON,MECH-HAU
      DW BALLE
      DB BALL-LON,BALL-HAU

Vous constatez que les adresses sont stockées sur 16 bits (DW ou DEFW selon les assembleurs) et les hauteur et longueur sur 8 bits (DB ou DEFB). Je vais vous pondre un petit sous-programme qui, appelé par un CALL, affichera n'importe quel de vos sprites. Pour cela, il suffit de placer dans l'accu le numéro du sprite (de 1 à 3 dan~ notre exemple). Il s'agit d'automodifier le programme d'affichage.

SLA A
SLA A
LD B,0
LD C,A
LD HL,TABLE-4
ADD HL,BC
PUSH HL
POP IX
LD L,(IX + 0)
LD H,(IX + 1)
LD (MODIFI + 1),HL
LD A,(IX + 2)
LD (MODIF2 + 1),A
LD A,(IX+3)
LD (MODIF3+ 1),A
JP AFFICH

Dans toutes les routines d'affichage, on fait pointer un double registre sur les données stockées en mémoire (le plus souvent le registre HL). A cette adresse on place l'étiquette MODIF1, de même pour la longueur on utilise le registre B ou le double registre BC ; c'est à cet endroit précis que l'on placera l'étiquette MODIF2 et MODIF3 pour la hauteur. Regardez bien ce qui su!t a fin de mieux en comprendre le pnncipe.

AFFICH LD DE,ECRAN
MODIFI LD HL,0
MODIF3 LD B,0
BOUCLE PUSH BC
       PUSH HL
MODIF2 LD BC,0
       LDIR

       etc.

J'utilise la méthode la plus simple pour afficher un sprite (pour la suite référez-vous aux précédents articles). En quelques millisecondes, votre routine est automodifiée et devient passe partout le pied quoi!
Un dernier détail auquel il faudra faire très gaffe. Vous travaillez sans filet et gare aux plantages, ne laissez rien au hasard et sauvegardez toujours vos sources avant d'exécuter quoi que ce soit. Compris?

ÇA VA COGNER DUR

Les coordonnées des sprites peuvent vous aider lors des déplacements, tests de collision et plein de trucs sympa du même genre. Supposons que vos déplacements se font à l'octet en largeur et toutes les deux lignes en hauteur. Vous aurez ainsi moins de 80 emplacements par ligne (moins, car il faut retirer la largeur du sprite) et moins de 100 positions en hauteur.

Les coordonnées du sprite en X ont alors de 1 à 76 et en Y de 1 à 184. On garde deux octets pour stocker ces valeurs. A chaque déplacement à droite, on teste si la valeur n'est pas à son maximum, dans ce cas on l'incrémente et autorise le déplacement à droite. Idem pour les déplacements à gauche et en hauteur. Il va de soi qu'avec le principe d'automodification du programme, on peut s'amuser à stocker en lignes les quatre limites de déplacement de nos sprites (XMAX, XMIN, YMAX et YMIN). .

AIE, AIE, AIE, PAS LA TETE

Nous arrivons enfin aux tests de collision. Il existe plusieurs méthodes. La plus simple à comprendre est le test de couleur. On réserve une couleur (pourquoi pas la 15?) et on remplit tous les endroits non accessibles aux sprites avec cette couleur. Avant d'afficher le sprite, on lit les quatre coins du futur emplacement ou, si le coeur vous en dit, la totalité de la surface à afficher. Si un seul octet est égal à 255, on interdit l'affichage. Le principe est simple mais pas vraiment très propre.

Pour rester pro, faisons un peu de maths si vous le voulez bien... Euh non, ne partez pas, juste un tout petit peu, un millième de micro milligramme, OK ?

;
;       BC26 POUR DE
;
BC26    LD   A,D
        ADD  A,8
        LD   D,A
        RET  NC
        LD   BC,&C050
        EX   DE,HL
        ADD  HL,BC
        EX   DE,HL
        RET
,
;       LA SIMPLICITE
,
        LD   DE, ECRAN
        LD   HL, MÉMOIRE
        LD   B,HAUT
BOUC    PUSH BC
        PUSH DE
        LD   BC,LONG
        LDIR
        POP  DE
        CALL BC26
        POP  BC
        DJNZ BOUC
        RET
,
;       MODE XOR
,
        LD   DE, ECRAN
        LD   HL, MÉMOIRE
        LD   B,HAUT
BOUCl   PUSH BC
        PUSH DE
        LD   B,LONG
BOUC2   LD   A, (DE)
        XOR  (HL)
        LD   (DE) ,A
        INC  DE
        INC  HL
        DJNZ BOUC2
        POP  DE
        CALL BC26
        POP  BC
        DJNZ BOUCl
        RET
;
;       PAR OCTET

        LD   DE,ECRAN
        LD   HL,MÉMOIRE
        LD   B,HAUT
BOUC1   PUSH BC
        PUSH DE
        LD   B,LONG
BOUC2   LD   A, (HL)
        AND  A
        JR   Z,SAUT
        LD   (DE) ,A
SAUT    INC  HL
        INC  DE
        DJNZ BOUC2
        POP  DE
        CALL BC26
        POP  BC
        DJNZ BOUC1
        RET
;
;       PAR DERIERE
;
        LD   DE ,ECRAN
        LD   HL, MÉMOIRE
        LD   B,HAUT
BOUC1   PUSH BC
        PUSH DE
        LD   B,LONG
BOUC2   LD   A, (DE)
        AND  A
        JR   NZ,SAUT
        LD   A, (HL)
        LD   (DE) ,A
SAUT    INC  DE
        INC  HL
        DJNZ BOUC2
        POP  DE
        CALL BC26
        POP  BC
        DJNZ BOUC1
        RET

Soit deux rectangles dans un repère orthonormé. Pour les distinguer, on les indicera. 1 pour le premier et 2 pour le second (vous voyez bien que les maths ne sont pas si dures à comprendre).

Les coordonnées à gauche des rectangles sont respectivement X1 et X2, leur largeur est LAR1 et LAR2, les coordonnées en haut sont Y1 et Y2 et les hauteurs HAU1 et HAU2. Faites un petit dessin pour mieux comprendre la suite. Avec quatre opérations des plus élémentaires, nous allons tester si les deux rectangles se chevauchent. Il s'agit de quatre soustractions, si une des conditions n'est pas remplie, il y a collision. Les voici:

X2 - X1 < LAR1
X1 - X2 < LAR2
Y2 - Y1 < HAU1
Y1 - Y2 < HAU2

Dans cet algorithme, si Y2-Y1 est égal ou supérieur à HAU1, il y a collision; cela peut paraître magique, mais croyez-moi ça marche (prenez quelques valeurs et faites des essais pour vous en persuader). Pour transcrire le tout en Assembleur, cela ne devra pas vous poser de gros problèmes, m'enfin voici un exemple pour le premier test. On fait pointer IX sur une table contenant les valeur X1, Y1, LAR1, HAU1. X2,Y2,LAR2 et HAU2.

LD A,(IX+0)   ; X1
ADD A,(IX+2)  ; X1+LAR1
CP (IX+4)     ; X2
RET NC        ; si collision

Et les trois autres...

Avec cette méthode, si votre programme. ne sort pas par les quatre RET NC, vous pouvez être sûr que les deux sprites testés ne se chevauchent pas et vous pouvez tranquillement faire vos déplacements. Il va de soi que si les sprites testés étaient le héros et le gros pas beau de votre jeu, on remplacerait le RET NC par un JP NC,MORT, qui branchera le programme de telle sorte que l'on voie une belle explosion et [out ce qu'il faut pour indiquer au joueur qu'il n'a pas assuré un caramel (en deux mots, il est mort. Pardon, en trois mots).

Voilà, c'est tout pour ce mois-ci. Si vous en voulez encore, continuez à m'écrire et je me ferai un plaisir d'éclaircir vos problèmes. N'oubliez pas que nous avons rendez-vous dans quelques jours aux stands d'Amstrad Expo et que tous les fainéants qui font huit fautes d'orthographe par phrase pourront, de vive voix, me poser toutes les questions imaginables. .

A100% n°31 nov90, p74-75

★ ANNÉE: 1990
★ AUTEUR: Alain Massoumipour

Page précédente : De l'Arcade de l'Action n°30

CPCrulez[Content Management System] v8.7-desktop
Page créée en 114 millisecondes et consultée 1013 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.