msx logo

Maire-adjoint du
msx village france

msxosaure banniere

Traducteur sur

msx osaure accueilMSXosaure menu hautMSXosaure menu hautMSXosaure menu hautMSXosaure menu haut
 
 
 
Programmation
  UFO  
 Images - Listing - Téléchargement - Vidéo - Bonus

Un jeu en 10 lignes MSX Basic

 
En 2010, en l'honneur des 25 ans du MSX, le site de Konamito proposait un concours de programation de jeu sur MSX. Un classique en soi mais là le jeu ne devait tenir qu'en 10 lignes de programation Basic seulement! Sachant que chaque ligne ne peut contenir plus de 255 caractères et interdit l'utilisation de poke pour le langage machine la tache semble bien compliqué, voir impossible. Le défi a pourtant été relevé par de nombreux programmeur  dont votre serviteur avec UFO.
 
L'idée
 
Une nouvelle fois l'inspiration me viendra d'un jeu en ligne pratiqué par mon fils. Un jeu ou une DCA tente d'entraver l'avance de ballons dirigeables bombardant ses positions, de nombreuses options permettent de faire évoluer son armement, celle-ci seront les bienvenues pour affronter les vagues ennemie ssans cesse plus nombreuses et plus puissantes!
Pour la version MSX en 10 lignes Basic le jeu sera profondément épuré. Pas d'options, tir droit et pas en angle mais on choisit  toujours l'endroit où se produira l'explosion de son missile. Au début le jeu devait s'appeler DCA mais son évolution l'a transformé en un UFO. Les graphismes des monstres ne me convenait pas. Je les ai alors remplacé par des ovnis au look plus rétro et cadrant mieux avec le décor. Les vies se sont aussi transformées en une tour de contrôle bombardée.
 
   Quelques Images  
ufo msx msxosaure basic 10 lignes jeu tir shoot ovnis dca ufo msx msxosaure basic 10 lignes jeu tir shoot ovnis dca ufo msx msxosaure basic 10 lignes jeu tir shoot ovnis dca
Le "pré- projet" L'écran d'accueil Touché!
   
 UFO

Le listing commenté: 
  1. Initialisation, graphismes.
  2. Préparation ecran d'attente.
  3. Ecran d'attente, lancement du jeu.
  4. Déplacement viseur et déclenchement du tir.
  5. Gestion des tirs et explosions.
  6. Gestions des ovnis.
  7. Fin de la boucle du jeu, datas.
  8. Gestion des collisions de sprites.
  9. Fin de gestion des collisions, datas.
  10. Perte de vies, fin du jeu.
 Ligne 1
   Initialisation du jeu, avec choix de mode ecran, création et mise en place des graphismes. Rien de spécial dans ce début de programmme si ce n'est le choix du screen1 en mode sprite 8x8 pour plus de facilité graphique.  
 UFO
 
1 SCREEN1,0:DIMC,X,Y,P,W(9):WIDTH32:COLOR3,12,1:KEYOFF:FORI=14350TO14381:READA$:VPOKEI,VAL("&h"+A$):NEXT: FORI=32TO87:READA$:VPOKEI,VAL("&h"+A$):NEXT:FORI=6240TO6815:VPOKEI,0:NEXT:VPOKE8192,177:VPOKE8193,97: FORI=1TO38:READA,B:VPOKE6300+A,B:NEXT 
  • SCREEN1,0: Activation du mode ecran 1 avec sprite 8 x 8 un choix qui simplifie la tache pour les graphismes.
  • DIMC,X,Y,P,W(9): Dimensionnement des tableaux à 9, principalement pour les attributs des ovnis.
  • WIDTH32: 32 colonnes.
  • COLOR3,12,1: Ecriture vert clair sur fond vert foncé et contour noir.
  • KEYOFF: Effacement des touches de fonctions.
  • FORI=14350TO14381:READA$:VPOKEI,VAL("&h"+A$):NEXT: Création des sprites en VRAM à partir des datas.
  • FORI=32TO87:READA$:VPOKEI,VAL("&h"+A$):NEXT: Création des décors en VRAM à partir des datas.
  • FORI=6240TO6815:VPOKEI,0:NEXT: Effacement de la zone de jeu, partie centrale de l'écran.
  • VPOKE8192,177: Colorisation d'une partie des décors en jaune clair sur noir.
  • VPOKE8193,97: Colorisation d'une partie des décors en rouge foncé sur noir.
  • FORI=1TO38:READA,B:VPOKE6300+A,B:NEXT Mise en place des décors; A=positon, B=choix du décor.
 
 Ligne2
   Préparation de l'écran d'attente avant début du jeu, où on initialise les variables et l'ecran avant un prochain jeu.  
 UFO

2 DEFINTA-Z:PLAY"","t250s8m6000o4l2dd+dcd4","T200O3L2D.DD":LOCATE2,22:PRINT"U.F.O. SCORE: 0 MAX:";M: X=40:Y=96:C=0:ONSPRITEGOSUB8:VPOKE6785,7:VPOKE6753,7:VPOKE6721,7:VPOKE6689,7:VPOKE6657,6:FORI=0TO9: X(I)=0:C(I)=0:W(I)=0:P(I)=0:PUTSPRITEI,,0,0:NEXT 
  • DEFINTA-Z: On met toutes les variables en entier, ça accélère le programme.
  • PLAY"","t250s8m6000o4l2dd+dcd4","T200O3L2D.DD": On joue la petite musique d'intro en paramètrant.
  • LOCATE2,22: Positionnement du curseur X=2, Y=22.
  • PRINT"U.F.O. SCORE: 0 MAX:";M: Mise en place des inscriptions, M est la variable du meilleur score.
  • X=40:Y=96:C=0: initialisation des variables.
  • ONSPRITEGOSUB8:Déclaration de la ligne du sous-programme gérant les collisions de sprites.
  • VPOKE6785,7:VPOKE6753,7:VPOKE6721,7:VPOKE6689,7:VPOKE6657,6:Mise en place de la tour de controle.
  • FORI=0TO9:X(I)=0:C(I)=0:W(I)=0:P(I)=0:PUTSPRITEI,,0,0:NEXTMise à zéro des paramètre des sprites
 
 Ligne 3
  Initialisation des registres son, de la valeur aléatoire et on tourne en boucle jusqu'à l'appui sur une touche.
Petite astuce: La formule Q=1+1*(STRIG(0)=-1) permet de définir le mode de contrôle suivant que "espace" ou le bouton 1 a été enfoncé, en fait par défaut Q vaut 1 tant qu'on a pas appuyé sur "espace".
 
UFO

3 SOUND7,48:SOUND6,0:Z=RND(-TIME):LOCATE5,1:PRINT"PUSH SPACE OR SWITCH 1 ! ":Q=1+1*(STRIG(0)=-1): IFSTRIG(Q)=-1THENFORI=6176TO6232:VPOKEI,32:NEXT:V=5:P=4:PLAY"v11","t250v9s8m6000o4L2dd+dcl4dd-dl2ee+ec2l4ee","t250v10o3l2d.d-dcl4dd+dl2ee-ec2l4e"ELSE3 
  • SOUND7,48:SOUND6,0: Gestion des registres sons et du bruit.
  • Z=RND(-TIME): Initialisation des valeurs aléatoires sur l'heure pour que chaque partie soit différente.
  • LOCATE5,1: Positionnement du curseur X=5, Y=1.
  • PRINT"PUSH SPACE OR SWITCH 1 ! ": Mise en place inscription d'attente de départ du jeu.
  • Q=1+1*(STRIG(0)=-1): Identification du bouton enfoncé (manette ou clavier).
  • IFSTRIG(Q)=-1 Test du bouton enfoncé.
THEN ...
FORI=6176TO6232:VPOKEI,32:NEXT: Effacement du message PUSH SPACE...
V=5:P=4: Initialisation des variables,  V (vies) à 5 et P à 4.
PLAY"v11","t250v9s8m6000o4L2dd+dcl4dd-dl2ee+ec2l4ee","t250v10o3l2d.d-dcl4dd+dl2ee-ec2l4e" ...musique d'intro.
ELSE3 Sinon on reprend au début de la ligne
 
 
 Ligne 4
  Déplacement du viseur et gestion des déclenchement des tirs sur une boucle tournant 3 fois de 7 à 9 , plans d'affichage des sprites.C(I) gère la couleur du tir et et permet aussi de détecter l'activation du tir ou non.  
 UFO

4 D=8*(S=3)*(X<224)-8*(S=7)*(X>24):E=16*(S=5)*(Y<112)-16*(S=1)*(Y>32):Y=Y+E:X=X+D:PUTSPRITE21,(X,Y),13,3: PUTSPRITE20,(X,159),10,4:IFSTRIG(Q)=0THENH=0ELSEIFH=0THENH=1:FORI=7TO9:IFC(I)<2THENW(I)=Y:X(I)=X:Y(I)=152: C(I)=2:P(I)=1:I=9:PLAY"o4f32":NEXTELSENEXT 
  • D=8*(S=3)*(X<224)-8*(S=7)*(X>24): Définiton de D suivant position horizontale du canon et de l'action sur le "stick" actif.
  • E=16*(S=5)*(Y<112)-16*(S=1)*(Y>32): Définiton de E suivant position verticale du viseur et de l'action sur le "stick" actif.
  • Y=Y+E: Ajout de E à Y: déplacement vertical du viseur.
  • X=X+D: Ajout de D à X: déplacement horizontal du canon.
  • PUTSPRITE21,(X,Y),13,3: Affichage du sprite curseur.
  • PUTSPRITE20,(X,159),10,4: Affichage du sprite canon.
  • IFSTRIG(Q)=0 Détection si bouton tir non enfoncé...
THENH=0...alors tempo(H) à 0...
ELSEIFH=0...sinon si tempo(H) à 0...
THENH=1:...alors tempo(H) à 1...
FORI=7TO9:...début de la boucle des 3 tirs...
IFC(I)<2...Si statut tir n'est pas en cours...
THENW(I)=Y:...enregitrement niveau de l'explosion...
X(I)=X:...enregitrement du X du tir...
Y(I)=152:...enregitrement du Y du tir...
C(I)=2:...statut tir actif...
P(I)=1:...N° sprite = tir...
I=9:...on force la fin de la boucle...
PLAY"o4f32"...on joue le son tir...
NEXT...fin de la boucle...
ELSENEXT...sinon fin de la boucle...
 
 
 Ligne 5
  Gestion des tirs toujours sur une boucle de 7 à 9. Là C(i) permet de définir le statut du tir, en cours, explosion, fin et sert de tempo pour l'explosion tout en en changeant la couleur donnant une impression d'animation de celle-ci.  
 UFO

5 FORI=7TO9:IFC(I)>1THENY(I)=Y(I)+8*(P(I)=1):PUTSPRITEI,(X(I),Y(I)+1),C(I),P(I):IFY(I)=W(I)THENP(I)=5:W(I)=0:PUTSPRITEI,(X(I),Y(I)+1),C(I),P(I) :C(I)=3:PLAY"t250o4e64"ELSEIFC(I)>2THENC(I)=C(I)+1:IFC(I)=10THENC(I)=1:P(I)=0:PUTSPRITEI,(0,0),0,0 
  • FORI=7TO9: Définiton de D suivant position horizontale du canon et de l'action sur le "stick" actif.
  • IFC(I)>1 Détection si statut tir actif...
THENY(I)=Y(I)+8*(P(I)=1):...alors Y tir monte si N° sprite = tir...
PUTSPRITEI,(X(I),Y(I)+1),C(I),P(I):...affichage du sprite tir...
IFY(I)=W(I)...Détection si tir atteind le niveau de l'explosion...
THENP(I)=5:...alors N°sprite = explosion...
W(I)=0:...niveau explosion à 0...
PUTSPRITEI,(X(I),Y(I)+1),C(I),P(I):...affichage du sprite explosion...
C(I)=3:...couleur sprite (tempo explosion) à 3...
PLAY"t250o4e64"...on joue le son explosion...
ELSEIFC(I)>2...sinon si tempo explosion actif...
THENC(I)=C(I)+1:...alors incrémentation tempo explosion...
IFC(I)=10...si tempo explosion finit...
THENC(I)=1:...alors fin cycle tir/explosion...
P(I)=0...N° sprite tir à 0...
PUTSPRITEI,(0,0),0,0...Effacement du sprite explosion...
 
 
 Ligne 6
  Gestion des 6 ovnis avec une boucle de 0 à 5. le programme vérifie si on a perdu sinon on continue le jeu.
Petite astuce: On commence par fermer avec un NEXT la boucle de la ligne précédente, ça permet de palier les ratages du aux IF...THEN... de la ligne précédente. La variable C(i) gère à la fois la couleur de l'ennemi et sa vitesse.
 
 UFO
 
NEXT:IFV=0THENV=8:PLAY"","t180o3b","t180o2b":GOTO10ELSEFORI=0TO5:IFX(I)=<8THENIFC(I)=0THENX(I)=240: C(I)=INT(1+RND(1)*(3+INT(C/500))):C(I)=5*-(C(I)>5)-C(I)*(C(I)<6)ELSEC(I)=0:GOSUB10ELSEY(I)=32+I*16:
PUTSPRITEI,(X(I),Y(I)),C(I)+4,2:X(I)=X(I)-C(I)
  • NEXT: On clot la boucle lancée au début de la ligne 5.
  • IFV=0 Détection si plus de vie...
THENV=8:...alors le compteur vie est mis à 8 pour gestion du game over...
PLAY"","t180o3b","t180o2b":..on joue une petite musique de fin...
GOTO10...Et on saute à la ligne 10...
ELSEFORI=0TO5:...sinon on lance la boucle "UFO"...
IFX(I)=<8...on teste si l'ovni a atteind le bord de l'écran...
THENIFC(I)=0...alors si l'ovni n'est plus affiché (couleur à 0)...
O=I:...Sauvegarde du plan de sprite actif pour affichage de l'explosion de la tour...
THENX(I)=240: ...alors on remet l'ovni à droite...
C(I)=INT(1+RND(1)*(3+INT(C/500))):...on choisi l'ovni (vitesse/couleur) au hasard et suivant le score (C)...
C(I)=5*-(C(I)>5)-C(I)*(C(I)<6)...on limite le niveau de l'ovni...
ELSEC(I)=0:...sinon effacement de l'ovni...
GOSUB10
...et on va au sous-programme de gestion de perte de vie en 10...
ELSEY(I)=32+I*16:...sinon on définit la hauteur de l'ovni...
PUTSPRITEI,(X(I),Y(I)),C(I)+4,2:...on affiche l'ovni...
X(I)=X(I)-C(I) ...et on déplace l'ovni vers la gauche.
 
 
 Ligne 7
  On commence une nouvelle fois par fermer la boucle de la ligne précédente et on retourne en ligne 4 pour fermer la boucle principale. La ligne est courte, on en profite pour y mettre un max de datas qui peuvent être mis n'importe où dans le jeu.  
 UFO
 
7 NEXT:SPRITEON:S=STICK(Q):GOTO4:DATA18,18,00,18,24,ff,7e,3c,42,00,66,00,00,00,00,00,00,66,18,18,18,18,42,7e,a5,db, ba,7c,d9,7e,3a,55,00,00,00,00,00,50,20,50,20,20,a8,70,df,70,a8,20,00,91,9a,9c,ae,97,98,66,ff,99,99,ff,ff,99,99,ff,01,02,04,08, 10,20,40,80 
  • NEXT: Fermeture de la boucle de la ligne 6.
  • SPRITEON: Activation de la détection de collisions de sprites.
  • S=STICK(Q): Enregistrement de l'état du bouton 1 ou barre espace dans la variable S.
  • GOTO4: Retour à la ligne4, début de la boucle du jeu.
  • DATA18,18,00,18,24,ff,7e,Etc... Datas patrons des décors et des sprites.
 
 Ligne 8
  La ligne  qui gère les collisions de sprites. Ici on ne s'occupe que des collisions entre explosions et ovnis car c'est le seul cas posssible en dehors de 2 explosions ensemble, voir "Le petit truc en plus" pour plus d'info. On lance une boucle pour les ovnis et une pour les tirs et on teste pour chaque s'il y a destruction de l' ovni ou pas.  
 UFO
 
8 SPRITEOFF:FORL=0TO5:FORK=7TO9:IFP(K)<5THENNEXT:NEXT:RETURNELSEIFY(K)=Y(L)ANDX(K)>X(L)-9ANDX(K)<X(L)+9THEN PUTSPRITEL,(0,0),0,0 :X(L)=0:C(K)=9:C=C+C(L)*10:C(L)=0:LOCATE15,22:PRINTC:PLAY"t250o5l64e":K=9: DATA80,40,20,10,08,04,02,01,00,00,00,00,00,3c,7e,ff
  • SPRITEOFF: Désactivation de la détection de collisions de sprites pour éviter que ça boucle.
  • FORL=0TO5: Lancement de la boucle pour gérer les ovnis.
  • FORK=7TO9: Lancement de la boucle pour gérer les tirs.
  • IFP(K)<5 ...On teste si le tir n'est pas en mode explosion (forme du sprite).
THENNEXT:...alors on teste le tir suivant...
NEXT: ...Quand on a fini de tester les tirs on passe à l'ovni suivant...
RETURN ...Quand on a fini de tester les tirs et ovnis on retourne au programme principal.
ELSEIFY(K)=Y(L)ANDX(K)>X(L)-9ANDX(K)<X(L)+9 ...Sinon si les coordonées ovni et explosion correspondent...
THEN PUTSPRITEL,(0,0),0,0: ... Effacement du sprite ovni...
X(L)=0: ...Position horizontale de l'ovni à 0.
C(K)=9: ...Mise à la valeur de fin de cycle du temporisateur de l'explosion...
C=C+C(L)*10: ... Incrémentation du score en fonction de l'ovni abattu; ovni plus rapide= score plus élevé....
C(L)=0: ... Mise à 0 de la valeur de l'ovni...
LOCATE15,22: ...Placement du curseur au niveau du score pour écriture...
PRINTC: ...Affichage du score...
PLAY"t250o5l64e": ...On joue le bruitage de l'explosion.
K=9:  ...On "sort" de la boucle tir.
  • DATA0,40,20,10,08,04,02,01,00,00,00,00,00,3c,7e,ff... Fin des datas patrons des décors et des sprites.
 
 Ligne 9
  On commence une nouvelle fois par fermer les boucles des lignes précédentes et on retourne au programme principal. Une ligne qui fourmille de data gérant en premier l'emplacement ou sera mis le décor écran (-6300) et en second celui qui sera mis à cet emplacement, voir ligne1.  
 UFO
 
9 NEXT:NEXT:RETURN:DATA99,4,78,4,147,4,248,4,265,4,305,4,381,4,484,7,486,7,513,7,490,8,459,8,428,8,397,8,366,8,367,9,400,
9,433,9,496,8,465,8,434,8,435,9,468,9,501,9,506,8,507,9,509,8,478,8,479,9,512,9,452,10,454,10,481,10,102,5,225,5,21,5,407,5,182,5
  • NEXT: On teste le tir suivant...
  • NEXT:  Quand on a fini de tester les tirs on passe à l'ovni suivant...
  • RETURN ...Quand on a fini de tester les tirs et ovnis on retourne au programme principal.
  • DATA99,4,78,4,147,4,248,4,265,Etc. ...Datas emplacement et nature du décor.
 
 Ligne 10
  Gestion des pertes de vies et de la fin du jeu avec affichage du Game Over , petite musique de fin et enregistrement du score max. Ici c'est la musique qui sert de tempo avant le retour à l'écran d'acueil. Le compteur de vie sert de variable de statut du jeu.  
 UFO
 
10 IFV=8THENLOCATE12,1:PRINT"GAME OVER !":V=9:PLAY"","cdd-ddl2ee+ecl4ee","c.dd-ddl2ee+ecl4e." :GOTO10ELSEIFV=9THENM=-M*(C<=M)-C*(C>M):IFPLAY(0)=0THEN2ELSE10ELSEV=V+1*(V>0):VPOKE6785-V*32,0: PUTSPRITEO,(8,162-V*8),10,5:PLAY"t250o3l32gf":RETURN
  • IFV=8... Si le jeu est perdu...
THENLOCATE12,1: ...Alors placement du curseur en haut pour écriture...
PRINT"GAME OVER !": ...Affichage du Game Over !.
V=9: ...Incrémentation de la variable de détection de stade jeu en jeu = perdu et géré...
PLAY"","cdd-ddl2ee+ecl4ee","c.dd-ddl2ee+ecl4e.": ...Musique de fin...
GOTO10 ...Retour en début de ligne
ELSEIFV=9...Sinon si le jeu est perdu et géré...
THENM=-M*(C<=M)-C*(C>M): ... Sauvegarde du meilleur score grace à une formule magique...
IFPLAY(0)=0 ...Si la musique de fin est finie....
THEN2 ...Retour à l'accueil...
ELSE10 ... Sinon retour à la ligne (attente)...
ELSEV=V+1*(V>0): ... Sinon perte d'une vie si pas déjà à 0...
VPOKE6785-V*32,0:...Effacement de l'élément de la tour concerné...
PUTSPRITEO,(8,162-V*8),10,5: ...Affichage explosion tour...
PLAY"t250o3l32gf": ...On joue le bruitage de l'explosion.
RETURN  ...Retour au programme principal.
 
Téléchargement:
  Fichier zip comprenant le  fichier disquette et le fichier texte du programme. UFO.zip  
UFO
 
La vidéo:
   
 UFO
 
Le petit truc en plus...
 

La gestion des collisions de sprites
.
 
Les interruptions provoquées par les collisions provoquent de forts ralentissements, pour palier à une surcharge excessive du programme, on joue sur la forme et le déplacement des sprites. Le viseur en violet ne rencontre ni le tir en jaune ni l'ovni en bleu qui ne se rencontrent pas l'un l'autre grace à leurs formes mais aussi à leurs déplacements (de 8 en 8 pour le viseur et le tir). Il en va de même pour l'explosion. Seuls une explosion et un ovni peuvent se superposer ce qui déclenche un appel au sous programme de gestion des collisions en ligne 8.
Toutefois un autre cas peut se présenter, il s'agit de deux explosions se déclenchant au même endroit, de plus ce cas a tendance à "boucler" du fait que les sprites ne disparaissent pas tout de suite. Ce désagrément est atténué par le fait que le joueur n'a que très peu d'intéret à tirer 2 fois de suite au même endroit et l'impossibilité de tirer en "rafale".
 

ufo msx msxosaure basic 10 lignes jeu tir shoot ovnis dca  OOOOOOOOOOOOOOOOufo msx msxosaure basic 10 lignes jeu tir shoot ovnis dca
 
 UFO
 
     
   
   
  Made in Osaure  

 



Créer un site
Créer un site