CODING ★ COURS DE GRAPHISME ANIMATION MULTI-SPRITES ★

Graphic - 16 - Animation Multi - Sprites (SOS Programmeurs)
CHAPITRE 1 : CREATION DES TABLES DE GESTION ET SOUS ROUTINES

Installez vous confortablement car cette suite de chapitres sera plutôt longue et les listings bien garnis . Les principes de bas sont assez simples mais leur application demande beaucoup de programmation .

Tout d'abord posons le problème de l'animation successive de plusieurs sprites :

La première chose qui vient à l'esprit concerne les coordonnées écran de ceux-ci , VISAD et COINBD seront différents pour chaque dessin à afficher donc modifiés à chaque changement de dessin et il faudra donc garder en mémoire les adresses d'affichage de tous les sprites en cours . Il n'est pas non plus question de voir tout l'ensemble se déplacer dans une même direction alors il faudra aussi mémoriser le sens de déplacement de chacun d'eux . Nous avons conservé le nom de DIRJOY pour cet octet bien que le joystick n'entre pas en jeu dans nos exemples .

Ceci va nous conduire à créer une table de données qui permettra de stocker en permanence ces 2 informations et le programme fonctionnera comme ceci :

1 : On prend les adresses d'affichage du 1er sprite dans la table ainsi que la direction dans laquelle il se deplace .
2 : On calcule le déplacement .
3 : On met les nouvelles adresses d'affichage dans la table pour le prochain tour .
4 : On affiche le sprite .
5 : On pointe sur les adresses d'affichage du sprite suivant et on recommence en 2
6 : Quand toute la série des sprites à été affichée on recommence en 1 .
Puisque nous devons obligatoirement utiliser une table de mémorisation , faisons les choses à fond en l'utilisant pour gagner du temps lors de l'exécution du programme . On ajoute 2 octets à cette table qui contiendra l'adresse des données de chaque sprite , on économisera ainsi l'appel traditionnel à FINDSP ce qui est un gain appréciable .

Pour des applications plus sophistiquées , un octet nommé STATSP sera le bienvenu . Son contenu nous dira si le sprite en cours exige un traitement particulier ou non . Bien que nous ayons déjà stocké l'adresse du sprite , conserver aussi son numéro NUMSP sera utile lorsque nous aborderons les tests de collision . Ce numéro permettra en effet de savoir rapidement quel sprite
rencontre quel autre .

Pour conclure , on ajoute encore 2 octets , HSP et LSP qui contiendront les dimensions du sprite en cours . Ces 2 données étant invariables dans nos exemples ils ne seront jamais utilisés mais imaginez que les sprites utilisés soient de taille différente et cela devient indispensable . Mieux vaut prévenir que guérir ...

Si nous avons bien compté , il faudra réserver une zone de 11 octets par sprite qui contiendra dans l'ordre :

ADSP1 DW 0 ;Adresse du 1er sprite (2 octets)
VISAD1 DW 0 ;Adresse d'affichage du 1er sprite (2 octets)
COINBD1 DW 0 ;Coin oppose en bas a droite 1er du sprite (2 octets)
DIRJOY1 DB 0 ;Direction du 1er sprite (1 octet)
STATSP1 DB 0 ;Etat du 1er sprite (1 octet)
NUMSP1 DB 0 ;Numero du 1er sprite necessaire pour certains tests (1 octet)
HAUTSP1 DB 0 ;Taille du 1er sprite . 2 octets inutilises dans nos exemples .
LENSP1 DB 0
;
ADSP2 DW 0 ;Adresse du 2ème sprite (2 octets)
VISAD2 DW 0 ;Adresse d'affichage du 2ème sprite (2 octets)
COINBD2 DW 0 ;Coin oppose en bas a droite du 2ème sprite (2 octets)
DIRJOY2 DB 0 ;Direction du 2ème sprite (1 octet)
STATSP2 DB 0 ;Etat du 2ème sprite (1 octet)
NUMSP2 DB 0 ;Numero du 2ème sprite necessaire pour certains tests (1 octet)
HAUTSP2 DB 0 ;Taille du 2ème sprite . 2 octets inutilises dans nos exemples .
LENSP2 DB 0
;

Etc .......
Cela nous fera pour 25 sprites , 25*11 octets soit 275 octets . Il ne reste plus pour gérer cette table qu'à créer un pointeur 16 bits POINTSP qui mémorisera en permanence le début de l'un des 25 zones de 11 octets à utiliser .

Pour la gestion de ces tables , on pourrait prélever directement les données à partir de ce pointeur mais ce type de gestion est plutôt lourd .
Nous avons plus élégant à proposer :

On rajoute une zone de 11 octets (Encore !) ces 11 octets seront les seuls directement accessibles par les routines d'animation du programme . Il suffira de pointer dans la table de 275 octets la zone de 11 octets à utiliser par le programme et de la recopier par LDIR . Lorsque tout sera fini , on prendra la zone des 11 octets du programme pour la remettre dans la table comme ceci :

1 : Pointer la zone de 11 octets table voulue .
2 : La copier par LDIR dans les 11 octets programme .
3 : Memoriser le pointeur .
4 : Déplacer , animer , tester , etc ... Aura pour effet de modifier le contenu des 11 octets programme sans toucher aux 11 octets table .
5 : On recopie par LDIR dans la zone table les 11 octets programmes mis à jour .
Reste une décision à prendre : Comment initialiser la table ? On peut y- placer directement les données en écrivant directement en RAM .

 Ex : ADSP1 DW #9C44
   VISAD1 DW #C000
   COINBD1 DW #D053
   DIRJOY1 DB %0101
   STATSP1 DB #FF
   NUMSP1 DB 1
   HAUTSP1 DB 0
   LENSP1 DB 0
;
   ADSP2 DW #9D50
   VISAD2 DW #D034

   ETC ...Non seulement c'est fastidieux mais de plus difficile à modifier et de surcroît il faudrait calculer préalablement toutes les valeurs ce qui n'est pas vraiment simple !

On préfèrera créer des tables qui initialiseront la table , cela prend de la place en RAM et impose une section d'initialisation assez longue mais à le mérite de laisser le soin des calculs à votre CPC . Vous pourrez aussi modifier rapidement une valeur qui ne vous plait pas !

Nous ajouterons la table : LISTSP qui contiendra une suite de 25 numéros de sprites correspondant à ceux que l'on veut voir à l'écran . ADSP sera calculée depuis ce numéro .

LISTDIR : 25 octets où l'on mettra les 25 directions d'origine pour chaque sprite .

LISTSTA : 25 octets de statut pour les sprites , tous à #FF dans nos exemples .

LISTADV : 50 octets qui détermineront la 1ère position d'affichage des 25 sprites . COINBD sera calculé d'après cette valeur .

La section de programme qui effectue la recopie de ces octets dans la zone sprites sera une excellente occasion de revoir les systèmes d'adressage du cours assembleur de SOS5 .

Le programme qui suit déplace successivement 25 sprites et impose un changement de direction lorsque l'un d'entre eux touche la bordure . Pour déterminer la nouvelle direction , nous avons utilisé une routine d'interruption en détournant le vecteur #38 vers une routine créée à cet effet . La mise en œuvre est des plus simple , au lieu de mettre un RET (#C9) en #38 , on met l'adresse 16bits de la routine à exécuter en #39 et le cycle d'interruption ne se souciera plus que de notre routine .

La routine COMPTE est extrèmement simple puisqu'elle se contente d'incrémenter régulièrement un compteur de 0 à 25 et de recommencer dès que le maximum de 25 est atteint . Ce qu'il faut en revanche savoir , c'est que cette routine est activée tous les 1/300s. et ceci QUOIQUE FASSE LE PROGRAMME PRINCIPAL ! Ce qui revient à dire que les registres qu'elle emploie se retrouvent modifiés . Ainsi :

LD A,12
LD (CASE),A
Le cycle d'interruption peut se déclencher entre ces 2 instructions et dans ce cas , ce n'est pas 12 qui sera chargé dans CASE mais la valeur mise dans A par la routine sous interruption COMPTE . Il faut donc impérativement préserver tous les registres utilisés par COMPTE et les restituer en sortie . De plus toute routine appelée par un cycle d'interruption doit commencer par DI et se finir par EI ce qui évite qu'une routine d'interruption soit elle même interrompue par une autre ...

Dernier détail , lorsque vous mettez au point un programme utilisant cette astuce , pensez à prévoir un point de sortie qui restaure les interruptions ou alors , ne mettez ces routines en place qu'en dernier ! Un retour au basic ou dans un programme assembleur avec les interruptions bloquées ou détournées est assez peu désirable !

CHAPITRE 2 : 1ER PROGRAMME SECTION INITIALISATION

Voici enfin le programme promis ! Les sous routines et la section initialisation sont communes à tous les exemples ultérieurs , vous ne la reverrez plus dans les exemples suivants .

;
;- ANIM3.MAX -
;
;- 1 / Animation automatique de 25 sprites -
;- Tests de sortie d'ecran et changement de direction si sortie d'ecran -
;- Utilise une table en mode 0 ou TOUS LES SPRITES SONT DE TAILLE IDENTIQUE -
;
  ORG 35000
  JP DEBUT
;
;- Section EQUate -
;
HSP  EQU #0A04     ;Largeur & hauteur du sprite
HSP1 EQU #0903     ;Largeur-1 & hauteur-1 du sprite
HSP2 EQU #0A     ;Hauteur du sprite
LSP  EQU 4       ;Largeur du sprite
LSP1 EQU 3       ;Largeur-1 du sprite
TOTSP EQU 40      ;Nombre d'octets par sprite
NBSP EQU 27      ;Nombre de sprites
TABLSP EQU 40000     ;Adresse de chargement de la table
ADINK EQU NBSP*TOTSP+TABLSP+4 ;Formule qui donne la table des encres
;
NBTOANI EQU 25 ;Nombre de sprites a animer
;
;- Section variables -
;
ADPROV DW 0 ;Adresse écran provisoire pour diagonale
OLDADV DW 0 ;Adresse écran avant déplacement
OLDCOIN DW 0 ;Memorisation de COINBD
OLDVISU DW 0 ;Memorisation de VISAD
POINTSP DW 0 ;Memorisation de l'adresse des parametres du sprite en cours
;
;- Parametres du sprite en cours (11 octets) -
;
ADSP DW 0 ;Adresse du sprite choisi
VISAD DW 0 ;Adresse d'affichage du sprite choisi
COINBD DW 0 ;Coin oppose en bas a droite du sprite choisi
DIRJOY DB 0 ;Direction du sprite en cours
STATSP DB 0 ;Etat du sprite
NUMSP DB 0 ;Numero du sprite necessaire pour certains tests
HAUTSP DB 0 ;2 octets inutilises ici . Si l'on utilise une table ou les
LENSP DB 0 ;sprites sont de taille differente on y mettra les dimensions
;    ;du sprite en cours
;
;- Table de gestion de 25 sprites a animer , 11 octets par sprite -
;
LIST
ZONESPT DS 275 ;275 octets pour la table de gestion des sprites
NOLIST
;
;- Tables pour initialisation de la table des 25 sprites a animer -
;
LISTSP DB 01,02,01,03,04,05,06,07,08,09,10,11,12,13,14,14,15,18,18,19,20,20
  DB 21,21,22
LISTDIR DB %1010,%1000,%0110,%1010,%0010,%1010,%0110,%0010,%0110,%0010
  DB %1001,%0101,%0110,%0010,%0100,%0010,%0101,%0101,%1001,%0101
  DB %0001,%1000,%0100,%1000,%0101
LISTSTA DB #FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF
  DB #FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF,#FF
  DB #FF,#FF,#FF,#FF,#FF
LISTADV DW #C010,#E842,#D876,#F893,#C0A5,#C0C7,#F0C1,#C032,#F0A4,#C145
  DW #E145,#C184,#E940,#E987,#C1A9,#F1D8,#C240,#E278,#F284,#FB15
  DW #C422,#CCA1,#C46A,#DCBF,#C500
;

 Ici figurent les sous routines essentielles qu'utiliseront tous nos exemples .

;
;- Sous routines specifiques a l'animation multi sprites -
;
;Remettre le pointeur au debut de la table gestion et initialiser le
;compteur de boucle B
INIANIM LD HL,ZONESPT ;Pointer sur le debut de la table gestion
  LD (POINTSP),HL ;et ranger le pointeur
  LD B,NBTOANI  ;Nombre a afficher
  RET
;
;- Copier 11 octets de la table gestion dans la zone programme -
;
TRANSP PUSH BC    ;Passer les parametres du sprite au programme
  LD HL,(POINTSP) ;Recopier la zone pointee dans la zone
  LD DE,ADSP   ;de 11 octets utilisable par le programme
  LD BC,11
  LDIR    ;Après LDIR , HL pointe sur le 1er octet de la zone
  LD (POINTSP),HL ;de 11 octets suivante , il est donc pret a
  POP BC    ;l'emploi .
  RET
;
;- Copier les 11 octets de la zone programme dans la zone table gestion -
;
;Il faut noter que cette routine est TOUJOURS appelee après TRANSP , le
;pointeur POINTSP pointe donc la zone suivante . Pour remettre les donnees a
;la même place dans la table de gestion , on reculera ce pointeur de 1 pour
;viser le dernier octet de la zone de 11 et on fera le transfert du dernier
;vers le 1er octet avec LDDR .
;
SPTRANS PUSH BC    ;Ranger les nouveaux parametres du sprite
  LD DE,(POINTSP) ;dans la table
  DEC DE
  LD BC,11
  LD HL,LENSP
  LDDR
  POP BC
  RET
;
;- Routine pour changement de direction -
;
;La valeur du compteur variera tous les 1/300s. La routine CHDIR pointera sur
;le 1er octet de la liste des 25 directions utilisees et ajoutera la valeur
;du compteur a ce pointeur ce qui permettra de fixer une nouvelle direction
;de maniere sinon aleatoire mais du moins difficilement previsible .
;
COMPTE DI    ;L'incrementation de ce compteur est provoque
  PUSH AF   ;par le detournement du vecteur #38 des interruptions
  LD A,(CPTDIR) ;du Z80 .
  INC A
  CP 26
  JR C,NORAZD
  XOR A
NORAZD LD (CPTDIR),A
  POP AF
  EI
  RET
;
CHDIR LD A,(CPTDIR) ;Change la direction du sprite en cas de necessite
  LD HL,LISTDIR ;Adresse de deépart de la table des directions
  LD B,0   ;possibles a laquelle on ajoute la valeur donnee
  LD C,A   ;par le cycle d'interruptions
  ADD HL,BC
  RET
;
CPTDIR DB 0 ;Contiendra valeur de 0 a 25 donnee par le cycle d'interruption
;
AD38 DB 0
ADR39 DW 0
;
;Ici commence le programme proprement dit .
;
;- Initialiser encres -
;
DEBUT LD HL,ADINK ;Adresse des encres table de sprites donnee par EQU
  XOR A
FIXINK INC A   ;Initialiser les encres
  LD B,(HL)
  LD C,(HL)
  ;BIT 7,B
  JR NZ,FININK
  PUSH AF
  PUSH HL
  CALL #BC32
  POP HL
  INC HL
  POP AF
  JR FIXINK
;
;- Ranger les adresses des sprites , leur direction et leur statut -
;
FININK LD IX,ZONESPT ;Adresse table gestion des sprites
  LD IY,LISTSP ;Adresse des numéros a animer
  LD B,NBTOANI ;Nombre a animer
;
FINDSP LD A,(IY+0) ;Numero du sprite demande
  LD (IX+8),A ;Ranger
  LD HL,TABLSP+4 ;TABLSP+4 est l'adresse ou commence le 1er sprite
;        ;Defini par EQU
LOOKSP DEC A    ;Ceci est l'equivalent de FINDSP adapte au besoin
  JR Z,ESTFIND ;de ce programme .
  LD DE,TOTSP ;Nombre d'octets occupes par 1 sprite defini par EQU
  ADD HL,DE  ;Pointer le debut du suivant
  JR LOOKSP
;
ESTFIND LD (IX+0),L ;Ranger l'adresse de visualisation dans la table
  INC IX   ;en pensant a l'inversion LSB/MSB
  LD (IX+0),H
  INC IX   ;Pointer 11 octets plus loin dans la table
  INC IX   ;pour le sprite suivant
  INC IX
  INC IX
  INC IX
  LD A,(IY+25) ;Octet direction
  LD (IX+0),A ;ranger
  INC IX
  LD A,(IY+50) ;Octet statut
  LD (IX+0),A ;ranger
  INC IX
  INC IX
  INC IX
  INC IX
  INC IY
  DJNZ FINDSP
;
;- Ranger les adresses visu et coinbd -
;
  LD IX,ZONESPT+2 ;Adresse table gestion des sprites pour VISAD
  LD IY,LISTADV ;Adresses de 1er affichage
  LD B,NBTOANI ;Nombre a animer
;
NXTADV LD L,(IY+0) ;Prendre adresse visu dans la table LISTAD
  INC IY
  LD H,(IY+0)
  INC IY
  LD (IX+0),L ;On range VISAD dans la table de gestion
  INC IX
  LD (IX+0),H
  INC IX
;
FINDCOIN PUSH BC   ;On calcule COINBD pour chaque sprite
  LD BC,HSP1
;
  PUSH BC
  LD B,0
  ADD HL,BC
  POP BC
COIN CALL ADINF
  DJNZ COIN
  POP BC
;
  LD (IX+0),L ;On le range
  INC IX
  LD (IX+0),H
  INC IX   ;et on pointe sur la suite
  INC IX
  INC IX
  INC IX
  INC IX
  INC IX
  INC IX
  INC IX
  DJNZ NXTADV
;

STOP CONSEIL ! Si vous modifiez ce listing ou en écrivez un autre , ne rédigez que cette section du programme , mettez un RET ici , et listez la mémoire à partir de l'adresse ZONESP pour voir si les paramètres sont corrects et aux bons endroits dans la table ! L'erreur la plus courante est d'inverser poids fort et poids faible dans un adressage 16 bits !

CHAPITRE 3 : SECONDE PARTIE DU 1ER PROGRAMME

On commence par attendre un peu puis on modifie le vecteur d'interruption du Z80 . Ceci fait on affiche nos 25 sprites pour la 1ère fois . Pour ce 1er affichage , la direction est remise à 0 car aucun déplacement n'a encore été effectué et ADPROV , OLDADV ne sont pas initialisées . Faute de cette précaution , la sortie de AFFISP mettrait une série de 0 dans une zone stratégique du CPC .

;
  LD BC,#4000
WAITCOU DEC BC   ;Attendre un peu avant de bloquer les interruptions
  LD A,B
  OR C
  JR NZ,WAITCOU
;
MODI38 DI    ;Annuler detourner le cycle normal des interruptions
  LD HL,(#39) ;vers la routine COMPTE
  LD (ADR39),HL
  LD HL,COMPTE
  LD (#39),HL
  LD A,(#38) ;Sauver le contenu originel de la case #38
  LD (AD38),A
  EI
;
;- Effectuer 1er affichage -
;
  CALL INIANIM ;Retour ,HL pointe ADSP , B=Nombre a animer et
NXTAFF PUSH BC   ;HL est copie dans POINTSP
  CALL TRANSP ;Copie 11 octets sprite en zone prog.et avance pointeur
  XOR A   ;Mettre direction a 0 pour affichage
  LD (DIRJOY),A
  CALL AFFISP ;Afficher
  POP BC
  DJNZ NXTAFF
;

On commence la boucle d'animation par le test de SPACE .

;
;- Boucle d'animation des 25 sprites -
;
RECOM DI    ;Test direct de SPACE presse
  PUSH BC
  LD BC,#F792
  OUT (C),C
  LD BC,#F645
  OUT (C),C
  LD B,#F4
  IN A,(C)   ;SPACE ? Oui si #7F
  EI
  CP #7F
  POP BC
  JR NZ,NOQUIT
;
  DI
  LD HL,(ADR39) ;Si SPACE presse restaurer interruptions
  LD (#39),HL ;et fini
  LD A,(AD38)
  LD (#38),A
  EI
  RET
;
NOQUIT CALL INIANIM ;Remettre pointeur en debut de ZONESP et compteur a 25
;
;- Boucle pour deplacer un sprite -
;
NXTANIM CALL TRANSP  ;Passer les parametres du sprite en cours
  PUSH BC   ;au programme
;
  LD HL,(VISAD) ;Recopier les adresses initiales pour pouvoir
  LD (OLDVISU),HL ;annuler un mouvement prevu mais impossible .
  LD HL,(COINBD)
  LD (OLDCOIN),HL
;
  LD A,(DIRJOY) ;Si DIRJOY=0 le sprite est temporairement coince
  JR Z,NOAFF   ;on ne le reaffiche donc pas .
;
  DI     ;Mettre le cycle d'interruption en route faute de
  PUSH AF   ;quoi , COMPTE qui determine le changement de
  LD A,(AD38)  ;direction serait inactif et les sprites resteraient
  LD (#38),A   ;coinces en fin de course !
  POP AF
  EI
;
  ;RRC A    ;Routines de déplacement comme dans SOS6
  PUSH AF   ;Si le changement de direction est invalide
  CALL C,ENHAUT ;apres l'un des 4 CALL on resortira en NXTVERT
  POP AF    ;grace a un petit tripotage du pointeur de pile .
;
  ;RRCA
  PUSH AF
  CALL C,ENBAS
  POP AF
;
  ;RRCA
  PUSH AF
  CALL C,AGAUCH
  POP AF
;
  ;RRCA
  PUSH AF   ;Ce PUSH et POP semble inutile mais il ne faut pas
  CALL C,ADROIT ;oublier que le pointeur de pile peut-être manipule
  POP AF    ;par les tests . Il convient donc de conserver la
;        ;meme structure de pile .
;
  DI     ;On a plus besoin du cycle d'interruption
  LD A,#C9   ;donc on l'annule par un code RET jusqu'au
  LD (#38),A   ;prochain tour cela accelerera l'affichage .
  EI
;
  CALL AFFISP  ;Afficher a la nouvelle position
NXTVERT CALL SPTRANS ;et recopier les nouvelles coordonnees dans la table
NOAFF POP BC    ;des sprites
  DEC B
  JP NZ,NXTANIM ;Sprite suivant
  JP RECOM   ;On recommence une serie de 25
;

Voila pour le corps principal du programme qui n'a rien de bien complexe :

Pour les tests de sortie d'écran , seule la section de sortie en cas de rencontre avec le bord de l'écran change un peu . Au lieu de bloquer le sprite , on active la routine qui le renvoie dans une autre direction .

;
;- En bas -
;
ENBAS LD B,4   ;Comme dans SOS6
  LD HL,(COINBD)
;
B1   LD A,H
  ;SUB #FF
  JR NZ,OKBAS
  LD A,L
  CP #80
  JR NC,STOPBAS
;
OKBAS CALL ADINF
  DJNZ B1
;
  LD (COINBD),HL
;
  LD HL,(VISAD)
  LD (ADPROV),HL
  LD B,4
B2   CALL ADINF
  DJNZ B2
  LD (VISAD),HL
  ;SCF
  RET
;

  Ici ça change nettement par rapport aux précédentes versions . Noter que CHDIR renvoie une nouvelle direction dans HL sans tester sa validité ! Il est donc possible qu'il renvoie un mouvement impossible auquel cas on recommence tout . Quand la nouvelle direction est trouvée la manipulation du pointeur de pile renvoie en NXTVERT sans rien afficher , dans le cas ou le sprite se trouve dans un angle , CHDIR peut renvoyer une direction invalide pour le prochain tour de boucle ! Dans ce cas , on verra l'un des sprites s'arrèter un bref instant . Ce n'est pas très élégant mais très suffisant pour mettre en évidence le principe essentiel . Nous vous montrerons de meilleures méthodes par la suite .

;
STOPBAS CALL CHDIR ;On ne peut plus descendre donc on cherche une nouvelle
  LD A,(HL)  ;direction . Un eventuel bit mis vers le bas par CHDIR
  AND %11111101 ;est enleve par AND . Si ce AND renvoie 0 on recommence
  JR Z,STOPBAS ;jusqu'a ce que CHDIR renvoie une direction acceptable.
;
NEWDIR LD (DIRJOY),A ;Sortie commune aux 4 changements de direction
  POP IY   ;On enleve une adresse de la pile pour CALL C,direction
  POP IY   ;et encore une pour le PUSH AF qui precede CALL C
  LD HL,(OLDVISU) ;On annule toute eventuelle modification de position
  LD (VISAD),HL ;et la pile ayant ete reequilibree par les 2 POP IY
  LD HL,(OLDCOIN) ;on saute directement en NXTVERT pour passer au
  LD (COINBD),HL ;sprite suivant .
  JP NXTVERT
;

Les 3 autres tests sont similaires .

;
;- Mouvement en haut -
;
ENHAUT LD HL,(VISAD)
  LD B,4
;
H1   LD A,H
  ;SUB #C0
  JR NZ,OKHAUT
  LD A,L
  CP #50
  JR C,STOPUP
;
OKHAUT CALL ADSUP
  DJNZ H1
  LD (VISAD),HL
;
  LD HL,(COINBD)
  LD B,4
H2   CALL ADSUP
  DJNZ H2
  LD (COINBD),HL
;
  LD BC,LSP1
  AND A
  ;SBC HL,BC
  CALL ADINF
  LD (ADPROV),HL
  ;SCF
  RET
;
STOPUP CALL CHDIR   ;On ne peut plus monter donc on essaye de changer
  LD A,(HL)   ;de direction . On enleve un eventuel bit de
  AND %11111110  ;de direction vers le haut et si c'était le seul
  JR Z,STOPUP   ;bit mis on recommence .
  JR NEWDIR
;
;- A DROITE -
;
ADROIT LD HL,(COINBD)
  CALL TSTLAT
  CP #4F
  JR Z,STOPDRO
;
  INC HL
  LD (COINBD),HL
;
  LD HL,(VISAD)
  LD (OLDADV),HL
  INC HL
  LD (VISAD),HL
  ;SCF
  RET
;
STOPDRO CALL CHDIR   ;Meme principe que pour haut et bas
  LD A,(HL)
  AND %11110111
  JR Z,STOPDRO
  JP NEWDIR
;
;- A gauche -
;
AGAUCH LD HL,(VISAD)
  CALL TSTLAT
  OR A
  JR Z,STOPGAU
;
  DEC HL
  LD (VISAD),HL
  LD BC,LSP
  ADD HL,BC
  LD (OLDADV),HL
;
  LD HL,(COINBD)
  DEC HL
  LD (COINBD),HL
  ;SCF
  RET
;
STOPGAU CALL CHDIR   ;Comme pour haut , bas
  LD A,(HL)
  AND %11111011
  JR Z,STOPGAU
  JP NEWDIR
;

 Suivent les routines qu'il n'est pas nécéssaire de montrer une nouvelle fois .

La démonstration vous montrera les 25 sprites rebondissant joyeusement sur les bords de l'écran et se croisant sans complexes . La méthode d'affichage est suffisament rapide pour que ce croisement provoque à peine un léger clignotement . Il peut arriver que 2 sprites superposés suivent la même trajectoire . Dans ce cas c'est un peu confus .

Pour le chapitre suivant nous aborderons la rencontre entre 2 sprites .

SOS PROGRAMMEURS

★ ANNÉE: ???
★ AUTEUR: MICHEL MAIGROT

Page précédente : Graphic - 15 - Animation de Sprites
★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» SOS7DEMODATE: 2011-06-03
DL: 1653
TYPE: ZIP
SiZE: 8Ko
NOTE: 40 Cyls
.HFE: Χ

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Eye
» Coding » Graphic - CPC 34 - Animation et Gestion de Sprites (CPC Revue)
» Coding Src's » Dragon Curves 2 (Computing with the Amstrad)
» Coding Src's » A Very Moving Experience (Sean McManus and Amstrad Computer User)
» Coding Src's » Graffitis (Amstrad Magazine 16)
» Coding Src's » Test CRTC v2.3 (MADRAM, amslive n19)
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.732-desktop/c
Page créée en 506 millisecondes et consultée 2422 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.