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
★ AMSTRAD CPC ★ DOWNLOAD ★ |
|
CPCrulez[Content Management System] v8.7-desktop/c Page créée en 344 millisecondes et consultée 1693 foisL'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. |
|
|