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: 1501
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 » CAD for beginners part 2 (Amstrad Computer User)
» Coding Src's » Triangles (The Amstrad User)
» Coding Src's » Spinning Diamond
» Coding Src's » Grapics (Computing With the Amstrad)
» Coding Src's » Efectos de persiana (Amstrad Personal)
» Coding Src's » Graphic - Screen Rattle (Popular Computing Weekly)
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 344 millisecondes et consultée 1693 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.