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
 &emspSCF     ;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 même 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 déplacement .
 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
 &emspSCF     ;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
 &emspSCF     ;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: 1769
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 » Sternenzeichner (CPC Amstrad International)
» Coding Src's » Ripple (Computing with the Amstrad)
» Coding » Graphic - 40 - Overscan (SOS Programmeurs)
» Coding Src's » Dragon Curves 2 (Computing with the Amstrad)
» Coding Src's » Detect CRTC type by Rhino
» Coding Src's » Eye
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 046 millisecondes et consultée 2166 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.