CODING ★ COURS DE GRAPHISME - CHAPITRE 7 : AMELIORER LE PROGRAMME ★

Graphic - 22 - Amelirer le Programme (SOS Programmeurs)

Tout d'abord , éviter cet effet d'accélération désagréable qui se produit lors de la destruction des sprite , c'est l'enfance de l'art . Au lieu de sauter directement à la fin de la boucle si STATSP = 0 on fera un détour par une routine de temporisation dont la durée équivaut approximativement au temps d'affichage d'un sprite .

Maintenant , faire quelque chose d'un peu plus joli en remplaçant l'effacement instantané des dessins détruits par une belle explosion . Cette dernière sera figurée par la superposition successive de 6 sprites différents logés en fin de table . Cette localisation des sprites explosion n'est pas dûe au hasard ! Dans la mesure ou le numéro de sprite d'une des 6 explosions
est toujours plus grand qu'un sprite quelconque , cela simplifie les tests envisagés .

L'octet STATSP va à nouveau être mis à contribution , au lieu de le mettre de suite à 0 , il prendra la valeur 8 et on remplacera les paramètres du sprite détruit par ceux du 1er sprite explosion contenu dans la table . Ceci nous permettra de tester dans la boucle principale que si STATSP n'est ni #FF ni 0 , le sprite en cours est une explosion et que l'on doit réagir en
conséquence !

Pourquoi 8 dans STATSP ? Parceque c'est le nombre de tours de boucle pendant lequel un même sprite explosion sera maintenu à l'écran (sinon on ne verrait rien) . Ce compteur de 8 revenu à 0 , on remplacera le 1er sprite explosion par le suivant et on remettra le compteur STATSP à 8 pour maintenir le second sprite explosion . Ce n'est que lorsque la série des 6 explosions aura été affichée au lieu de la destruction que STATSP passera à 0 et que le sprite sera définitivement hors jeu .

Dans COLIUP seule la sortie de test TOUCHE est à modifier comme ceci :

;
TOUCHE POP BC    ;Un sprite est touche , on remet la pile en etat
  POP HL    ;On signale sa destruction en modifiant l'octet
  POP BC    ;STATSP . On y met 8 pour faire savoir qu'on veut
  LD (IX+7),8   ;afficher une explosion a la place du sprite .
  LD HL,(ADEXPLO) ;On remplace l'adresse du sprite par l'adresse
  LD (IX+0),L   ;du 1er sprite explosion .
  LD (IX+1),H   ;Et le numéro du sprite par le numéro du 1er sprite
  LD (IX+8),23  ;explosion . On n'a plus besoin de l'effacer il le
   SCF     ;sera par l'affichage du sprite explosion .
  RET
;
ADEXPLO DW 22*TOTSP+TABLSP+4 ;Adresse de l'explosion qui est le 23ème sprite
;

La séquence d'affichage de l'explosion .

;
EXPLOSE LD A,(STATSP) ;Voir d'abord le contenu de STATSP , tant qu'il
  DEC A    ;n'est pas revenu a 0 le meme sprite explosion
  LD (STATSP),A ;reste a afficher
  JR NZ,SUITEXP
;        ;On a fini cette sequence .
  LD A,(NUMSP) ;Tester le numéro de sprite , si on en est au
  CP 27    ;dernier sprite explosion c'est fini et le sprite
  JR Z,EFFSP  ;Est efface avant de devenir inactif .
;
  INC A    ;Sinon on selectionne le sprite explosion suivant
  LD (NUMSP),A
  LD A,8   ;On recharge la duree de l'affichage explosion
  LD (STATSP),A
  LD HL,(ADSP) ;On pointe son adresse et on la range
  LD DE,TOTSP ;Pour cela , les sprites doivent se succeder
  ADD HL,DE   ;dans l'ordre . Ne creez pas une table de sprites
  LD (ADSP),HL ;n'importe comment .
;
SUITEXP SCF    ;On met le CARRY pour signaler au programme que
  RET    ;l'affichage de l'explosion continue .
;
;- Efface le sprite touche -
;
EFFSP LD BC,HSP
  LD HL,(VISAD) ;Ici le sprite , bien que detruit , figure en zone
;        ;programme puisqu'il y revient en tant qu'explosion.
BCLEFF1 PUSH HL
  PUSH BC
  LD B,C
BCLEFF2 LD (HL),0
  INC HL
  DJNZ BCLEFF2
  POP BC
  POP HL
;
  LD A,H
  ADD A,8
  LD H,A
  JR NC,EXIEFF
  LD DE,#C050
  ADD HL,DE
EXIEFF DJNZ BCLEFF1
  XOR A
  RET
;
    ; La boucle d'affichage est encore modifiée .
;
;- Boucle pour deplacer un sprite -
;
NXTANIM CALL TRANSP ;Passer les parametres du sprite en cours au programme
  LD A,(STATSP) ;Verifier que le sprite n'est pas hors jeu , si c'est
  OR A    ;le cas on saute a la temporisation .
  JR Z,ESTMORT
;
  PUSH BC   ;Voir si le sprite est bien vivant , si STATSP<>#FF
  INC A   ;il s'agit d'une explosion qui doit etre affichee
  JR Z,OUIMOVE ;sans passer par les routines de deplacemnt .
;
  CALL EXPLOSE ;On va voir ou en est l'explosion si on revient sans
  JR NC,EXPFINI ;le CARRY l'explosion est finie
  JR NOMOVE  ;Sinon on saute la routine de deplacement .
OUIMOVE CALL TSTMOVE
NOMOVE CALL AFFISP ;Afficher un sprite
EXPFINI CALL SPTRANS ;Recopier les nouvelles coordonnees dans la table
  POP BC
COUIC DJNZ NXTANIM
  JP RECOM   ;On recommence une serie de 25
;
ESTMORT LD DE,#80  ;On simule la duree d'un affichage si on tombe sur
TPMORT DEC DE   ;un sprite detruit .
  LD A,D
  OR E
  JR NZ,TPMORT
  JR COUIC
;

Comme vous le voyez , il suffit de bien peu de chose pour obtenir un bel effet qui sera montré par la démonstration . Il ne subsiste plus qu'un problème assez simple à résoudre :

Relancez plusieurs fois la démonstration du programme précédent et observez attentivement jusqu'au bout , vous verrez que si le missile détruit bien les sprites qu'il touche par dessous , un sprite quelconque peut tomber impunément sur le missile si ce dernier se déplace latéralement .

Le problème est lié à la nécéssité de faire 2 tests au lieu d'un seul. En effet , il faut savoir qui touche qui ! Si le missile se déplace VERS LE HAUT ET AVANT un sprite , le test se fait et le sprite explose . En revanche , si un sprite se déplace AVANT le missile et VERS LE BAS rien n'est fait pour tester une éventuelle rencontre avec le missile numéro 6 . Cela à 2 effets
génants :

1 : Parfois un certain chevauchement avant l'explosion si le missile est déplacé vers le haut APRES le sprite en collision .
2 : La possibilité pour un sprite de tomber sur le missile en toute innocence si le missile se déplace LATERALEMENT ce qui est peu logique .
Rien de bien sorcier à résoudre . On modifie la sortie de ENBAS pour appeler une routine de collision vers le bas qui ressemble de très près à COLIUP .

Comme on l'a fait pour ENHAUT , on ajoute ces 3 lignes à ENBAS tout en ayant soin de remplacer JR NZ,STOPBAS par JR NZ,BASCOLI dans le test sur les couleurs .

;
BASCOLI LD (ADCOLLIS),DE ;ON MEMORISE L'ADRESSE DE COLLISION ET ON VA VOIR
  CALL COLIBAS  ;SI C'EST LE SPRITE NUMERO 6 QUI EST TOUCHE . LE
  RET C    ;CARRY EST MIS SINON .
;
STOPBAS RES 1,(IY+0)
  XOR A
  RET
;

La sortie TOUCHEB de COLIBAS présente une différence notable avec TOUCHE de COLIUP . Dans COLIUP le sprite destructeur est dans la zone active du programme et le sprite à détruire stocké dans la table . Ici , c'est l'inverse , on doit rechercher dans la table si c'est le sprite destructeur qui est rencontré et si oui c'est le sprite en zone programme qui doit être
détruit .

;
;- Test de collision vers le bas -
;
COLIBAS LD B,NBTOANI  ;Nombre a animer donc a tester
  LD IX,ZONESPT ;Debut de la table des sprites
  LD DE,(ADCOLLIS) ;Adresse collision
;
BCLCBAS PUSH BC
  LD A,(IX+7) ;Voir statut sprite
  INC A    ;Si <> de #FF , c'est obligatoirement une explosion
  JR NZ,NOTESTB ;ou un mort donc on l'ignore et on passe au suivant
;
  LD B,2   ;Hauteur a tester
  LD C,LSP   ;Largeur d'un sprite
  LD L,(IX+2) ;Adresse de VISAD sprite teste
  LD H,(IX+3)
;
BCLCB2 PUSH HL   ;Preserver VISAD en cours de test
  PUSH BC   ;et les hauteurs et largeurs de la zone a tester
;
BCLCB1 LD A,H   ;Tester octet par octet gagne du temps
  CP D    ;On commence par l'octet fort des adresses
  JR NZ,PATOUCB
  LD A,L   ;Et on ne teste le faible que si la comparaison
  CP E    ;precedente est valide
  JR Z,TOUCHEB ;Si les 2 adresses coincident le sprite teste
;        ;en rencontre un autre .
PATOUCB INC HL   ;Sinon on continue a tester la ligne en cours
  DEC C
  JR NZ,BCLCB1
;
  POP BC   ;Et si la collision n'est pas verifiee sur cette
  POP HL   ;ligne on va voir sur la ligne au dessus .
  CALL ADINF
  DJNZ BCLCB2
;
NOTESTB LD BC,11   ;Un sprite vient d'etre teste , on passe au suivant
  ADD IX,BC
  POP BC
  DJNZ BCLCBAS
  XOR A    ;Ici on constate qu'aucun sprite n'est touche , on
  RET    ;enleve le CARRY et c'est fini
;
TOUCHEB POP BC    ;Un sprite est touche , on remet la pile en etat
  POP HL
  POP BC
;
  LD A,(IX+8)   ;On verifie que c'est bien le sprite numéro 6 qui
  LD (NUMCOLI),A ;est touche
  CP 6
   SCF     ;Si ce n'est pas le cas , rien ne se passe
  ;CCF     ;on enleve le CARRY pour provoquer un changement
  RET NZ    ;de direction et c'est fini .
;
  LD A,8    ;Ici le sprite qui doit etre detruit n'est pas
  LD (STATSP),A ;dans la table mais dans la zone active du
  LD HL,(ADEXPLO) ;programme ! On modifie donc son statut en RAM
  LD (ADSP),HL  ;car il sera recopie dans la table par SPTRANS
  LD A,23    ;apres le retour de cette routine .
  LD (NUMSP),A
   SCF     ;On met le CARRY pour signaler sa disparition
  RET
;

Il ne vous reste plus qu'à lancer la dernière démonstration pour voir le résultat final .

Ce programme reste très incomplet mais nous n'allons pas remplir toute la disquette avec d'autres développements . Cette suite d'exemple devrait suffire à démontrer que si la structure de base d'un programme est bien conçue et la table des sprites bien ordonnée , le reste est plus affaire d'imagination que de connaissances en programmation . En partant de cette base , de simples tests sur STATSP et NUMSP peuvent produire des effets spectaculaires en quelques lignes de programme . Voici une série d'idées tout à fait réalisables pour vous entraîner en attendant SOS8 .

En sortie de test dans TOUCHE et TOUCHEB , faire :
CP un numéro de sprite
SCF
RET Z
Le sprite de numéro donné devient invulnérable .

Ressusciter un ou plusieurs sprites est simple . Il suffit de tester tous les octets de STATSP dans la table , lorsque l'on en trouve un à 0 , on le remet à #FF en rechargeant ADSP & NUMSP) avec l'adresse et le numéro du sprite que l'on veut revoir apparai^tre . Il n'est pas nécéssaire de changer VISAD & COINBD , ces 2 données sont conservées et le sprite reviendra là où il a disparu .

Ajouter un test en TOUCHE et TOUCHEB de telle sorte que ce soit la rencontre de 2 sprites donnés qui active la routine de résurection .

Faire en sorte qu'un sprite doive e^tre touché plusieurs fois par le missile avant d'exploser . Rappelons que dans ce programme les octets LENSP et HAUTSP sont inutilisés . On peut lors de l'initialisation les charger avec un nombre qui de7terminera le nombre de collision avant destruction et au lieu de modifier de suite STATSP dans TOUCHE / TOUCHEB , on décrémente cet octet . La destruction ne sera effective que s'il revient à 0 .

Rien n'interdit non plus de faire en sorte que la collision d'un sprite avec un autre ne transforme l'un d'entre eux en sprite destructeur . Il suffit de modifier les 2 octets ADSP et l'octet NUMSP avec le numéro et l'adresse du sprite numéro 6 . Le test se mettra encore en TOUCHE / TOUCHEB .

Et pourquoi ne pas accorder à un sprite le droit de détruire le missile s'il le rencontre ?

Essayer donc d'ajouter un sprite qui se déplace au joystik , ce n'est guère compliqué car joystick ou pas un sprite est un sprite et un test un test . La modification la plus sérieuse consiste à inhiber les routines de déplacement automatique dans ce cas . Choisissez donc le sprite 6 comme sprite joystick .

   ;NXTANIM CALL TRANSP
;
      LD A,(NUMSP)CP 6
      JR Z,TSTJOY
;
      LD A,(STATSP)
     ; Etc ...

Vous permettra de sauter les routines automatiques .

De toute manière nous vous en reparlerons dans SOS8 car nous avons promis d'aborder le CRTC et l'overscan dans ce numéro . Il faudrait peut-être leur laisser de la place non ?

SOS PROGRAMMEURS

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

Page précédente : Graphic - 21 - Reagir Au Test de Collision sur les Couleurs
★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» SOS7DEMODATE: 2011-06-03
DL: 1512
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 » Triangles (The Amstrad User)
» Coding Src's » Cinemascope
» Coding Src's » Mutli-Coloured Characters (Amstrad Action)
» Coding Src's » Graffitis (Amstrad Magazine 16)
» Coding Src's » Scroller (Computing with the Amstrad)
» Coding » Graphic - CPC 33 - Animation et Gestion de Sprites - Deplacement Multi - Sprites - Test de Collision (CPC Revue)
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.7-desktop/c
Page créée en 266 millisecondes et consultée 1735 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.