Section courante

A propos

Section administrative du site

Le jeu Space Invaders est un jeu très ancien proposé en Amérique sur Atari 2600. Bien que très ancien et célèbre, il fut très peu cloné par des développeurs amateurs sur PC. L'une des raisons pouvant expliquer le côté repoussant de ce jeu par les développeurs, c'est le fait que presque toutes l'écran bouge. Et sur des systèmes anciens, les jeux manquaient énormément de fluidité lorsqu'on faisait déplacer l'image entière à moins d'écrire le jeu en assembleur ou d'utiliser directement l'électronique pour afficher les images le plus rapidement possible. Du côté de la concurrence comme le micro-ordinateur Commodore 64, il existait la possibilité d'utiliser des sprits lequel, même en langage de programmation BASIC, avait d'excellente performance.

Le langage de programmation Turbo Pascal, disposaient bien sure de pilote BGI pour l'affichage graphique mais les performances sont très modeste, pour ne pas dire médiocre, il faut donc prendre des captures d'une partie de l'image des objet et afficher ces images lorsque qu'il faut afficher un alien plutôt que de dessiner les aliens et les vaisseaux à chaque fois.

Concernant les aliens a afficher, bien qu'au début il n'y a qu'un bloc d'alien, leur nombre se réduit de plus en plus en fonction des attaques du vaisseaux. On ne peut donc pas simplement retenue une coordonnée X et Y pour arriver à nos fins. Pour solution le problème, une des techniques les plus simples, et de simuler un tableau (dans ce code source, nommé ScreenBoard), à la manière d'un écran de texte et de garder en mémoire la présence d'un alien à cette position.

Enfin, on déplacera l'ensemble des aliens (à l'aide de la fonction MoveAlien) soit vers la gauche ou la droite d'une seule position à la fois après un certain intervalle de temps. Lorsqu'il atteint la limite de droite, il va vers la gauche et lorsqu'il atteint la limite de la gauche, il va vers la droite (voir la fonction NextAlienDirection). En prenant soit d'augmenter la coordonnées verticales à chaque fois qu'il atteint la limite de gauche ou de droite.

Lorsque la coordonnée verticales d'un des aliens est supérieur à la coordonnée verticales des boucliers (soit indiquer par la comparaison J+4>50), le joueur à perdu.

Lorsque le vaisseau tire, il a la possibilité de percer les boucliers. S'il n'a pas totalement percer le bouclier, il n'attendra pas les aliens. La technique la plus simple est de vérifier la couleur du bouclier, si la couleur est noir, alors il continue, sinon il est arrêté par le bouclier. Aussi, lorsqu'il tire, il est possible que la balle n'atteigne pas l'objectif immédiatement, il faut faire en sorte d'avoir un tableau avec plusieurs coordonnées de projectile, afin qu'il puisse tirer plusieurs fois.

L'écran de présentation est construite en utilisant les écrits gérer par la commande BANNER du projet Corail. Pour remplir un peu plus l'écran, les captures d'écran des différents aliens avec leurs valeurs en points est ajoutés à l'écran de présentation du jeu.

Voici le code source en Turbo Pascal du jeu :

  1. { @author: Sylvain Maltais (support@gladir.com)
  2. @created: 2024
  3. @website(https://www.gladir.com/7iles)
  4. @abstract(Target: Turbo Pascal 7, Free Pascal 3.2)
  5. }
  6.  
  7. Program SpaceInvaders; { INVADERS.PAS / SPACEINVADERS.PAS }
  8.  
  9. {$R-}
  10.  
  11. Uses {$IFDEF FPC}
  12.       DOS,Crt,PtcGraph,PtcCrt,PtcMouse
  13.      {$ELSE}
  14.       DOS,Crt,Graph
  15.      {$ENDIF};
  16.  
  17. Var
  18.  Finish,BoardCleared:Boolean;
  19.  Score,Lives:LongInt;
  20.  AlienCount,AlienScore:Word;
  21.  Image:Array[0..14]of Pointer;
  22.  BallX:Array[0..19]of Integer;
  23.  BallY:Array[0..19]of Integer;
  24.  AlienBallX:Array[0..3]of Integer;
  25.  AlienBallY:Array[0..3]of Integer;
  26.  LazerAlien:Integer;
  27.  ClearX:Array[0..19]of Integer;
  28.  ClearY:Array[0..19]of Integer;
  29.  MasterAlienX:Integer;
  30.  ScreenBoard:Array[0..59,0..79]of Byte;
  31.  GunnerX,CurrSprite:Byte;
  32.  Direction:ShortInt;
  33.  
  34. Function LongToStr(X:LongInt):String;
  35. Var
  36.  S:String;
  37. Begin
  38.  Str(X,S);
  39.  LongToStr:=S;
  40. End;
  41.  
  42. Procedure ClrKbd;Begin
  43.  While(Keypressed)do ReadKey;
  44. End;
  45.  
  46. Procedure InitScr;
  47. Var
  48.  Driver,Mode:Integer;
  49.  ErrCode:Integer;
  50. Begin
  51.  {$IFDEF FPC}
  52.   Driver:=VGA;
  53.   Mode:=VGAHi;
  54.  {$ELSE}
  55.   Driver:=Detect;
  56.   Mode:=VGAHi;
  57.  {$ENDIF}
  58.  InitGraph(Driver,Mode,'');
  59.  ErrCode:=GraphResult;
  60.  If ErrCode=grOk Then Begin
  61.   SetColor(White);
  62.   SetLineStyle(0,0,1);
  63.  End
  64.   Else
  65.  Begin
  66.   WriteLn('Erreur graphique : ',GraphErrorMsg(ErrCode));
  67.   Halt;
  68.  End;
  69. End;
  70.  
  71. Procedure Copy4Bin(X,Y,Matrix,ForegroundColor,BackgroundColor:Integer);
  72. Var
  73.  I:Byte;
  74. Begin
  75.  For I:=0 to 3 do Begin
  76.   If(Matrix shl (I shl 1))and 64=64 Then Begin
  77.    PutPixel(X+I,Y,ForegroundColor);
  78.   End
  79.    Else
  80.   Begin
  81.    PutPixel(X+I,Y,BackgroundColor);
  82.   End;
  83.  End;
  84. End;
  85.  
  86. Procedure PutImage4Bits(X,Y,Width,Height:Word;ForegroundColor,BackgroundColor:Integer;Var Buffer);
  87. Type
  88.  TByte=Array[0..2048]of Byte;
  89. Var
  90.  I,J:Integer;
  91.  P:Word;
  92.  PByte:TByte Absolute Buffer;
  93. Begin
  94.  If(Width=0)or(Height=0)Then Exit;
  95.  P:=0;
  96.  For J:=0 to Height-1 do For I:=0 to (Width shr 2)-1 do Begin
  97.   Copy4Bin(X+(I shl 2),Y+J,PByte[P],ForegroundColor,BackgroundColor);
  98.   Inc(P);
  99.  End;
  100. End;
  101.  
  102. Procedure Copy8Bin(X,Y,Matrix,ForegroundColor,BackgroundColor:Integer);
  103. Var
  104.  I:Byte;
  105. Begin
  106.  For I:=0 to 7 do Begin
  107.   If(Matrix shl I)and 128=128 Then Begin
  108.    PutPixel(X+I,Y,ForegroundColor);
  109.   End
  110.    Else
  111.   Begin
  112.    PutPixel(X+I,Y,BackgroundColor);
  113.   End;
  114.  End;
  115. End;
  116.  
  117. Procedure PutImage8Bits(X,Y,Width,Height:Word;ForegroundColor,BackgroundColor:Integer;Var Buffer);
  118. Type
  119.  TByte=Array[0..2048]of Byte;
  120. Var
  121.  I,J:Integer;
  122.  P:Word;
  123.  PByte:TByte Absolute Buffer;
  124. Begin
  125.  If(Width=0)or(Height=0)Then Exit;
  126.  P:=0;
  127.  For J:=0 to Height-1 do For I:=0 to (Width shr 3)-1 do Begin
  128.   Copy8Bin(X+(I shl 3),Y+J,PByte[P],ForegroundColor,BackgroundColor);
  129.   Inc(P);
  130.  End;
  131. End;
  132.  
  133. Procedure DrawAlien(Number:Byte;X,Y:Word);
  134. Const
  135.  Data:Array[0..14,1..6*17]of Byte=(
  136.     { 0 }
  137.   ($00,$00,$00,$00,$00,$00,{0}
  138.    $00,$00,$F4,$09,$10,$06,{1}
  139.    $00,$04,$00,$00,$10,$00,{2}
  140.    $00,$01,$00,$00,$40,$00,{3}
  141.    $00,$00,$44,$11,$00,$00,{4}
  142.    $00,$00,$15,$54,$00,$00,{5}
  143.    $00,$00,$55,$55,$00,$00,{6}
  144.    $00,$01,$45,$45,$40,$00,{7}
  145.    $00,$05,$41,$41,$50,$00,{8}
  146.    $00,$55,$55,$55,$55,$00,{9}
  147.    $00,$41,$55,$55,$41,$00,{10}
  148.    $00,$40,$50,$05,$01,$00,{11}
  149.    $00,$41,$51,$45,$41,$00,{12}
  150.    $00,$44,$05,$50,$11,$00,{13}
  151.    $00,$44,$01,$40,$11,$00,{14}
  152.    $00,$41,$00,$00,$41,$00,{15}
  153.    $00,$40,$40,$01,$01,$00),{16}
  154.     { 1 }
  155.   (0,  0,$01,$41,$40,$01,{0}
  156.    $41,$40,$90,$09,$10,$06,{1}
  157.    $01,$40,$04,$10,$01,$40,{2}
  158.    $00,$40,$04,$10,$01,$00,{3}
  159.    $00,$40,$44,$11,$01,$00,{4}
  160.    $00,$40,$15,$54,$01,$00,{5}
  161.    $00,$40,$55,$55,$01,$00,{6}
  162.    $00,$41,$45,$45,$41,$00,{7}
  163.    $00,$45,$41,$41,$51,$00,{8}
  164.    $00,$55,$55,$55,$55,$00,{9}
  165.    $00,$01,$50,$05,$40,$00,{10}
  166.    $00,$00,$50,$05,$00,$00,{11}
  167.    $00,$01,$50,$05,$40,$00,{12}
  168.    $00,$04,$04,$10,$10,$00,{13}
  169.    $00,$04,$04,$10,$10,$00,{14}
  170.    $00,$10,$01,$40,$04,$00,{15}
  171.    $04,$40,$01,$40,$01,$10),{16}
  172.     { 2 }
  173.   (0,  $01,$00,$00,$00,$00,{0}
  174.    $40,$BC,$0D,$0A,$10,$06,{1}
  175.    $00,$40,$00,$00,$01,$00,{2}
  176.    $01,$10,$00,$00,$04,$40,{3}
  177.    $00,$04,$00,$00,$10,$00,{4}
  178.    $00,$01,$05,$50,$40,$00,{5}
  179.    $14,$05,$55,$55,$50,$14,{6}
  180.    $14,$15,$01,$40,$54,$14,{7}
  181.    $14,$55,$41,$50,$55,$14,{8}
  182.    $14,$55,$01,$40,$55,$14,{9}
  183.    $15,$55,$54,$15,$55,$54,{10}
  184.    $05,$55,$50,$05,$55,$50,{11}
  185.    $00,$15,$50,$05,$54,$00,{12}
  186.    $00,$05,$54,$15,$50,$00,{13}
  187.    $00,$05,$05,$50,$50,$00,{14}
  188.    $00,$14,$00,$00,$14,$00,{15}
  189.    $05,$50,$00,$00,$05,$50),{16}
  190.     { 3 }
  191.   ($00,$01,$50,$00,$00,$05,{0}
  192.    $40,$58,$0D,$0A,$10,$06,{1}
  193.    $00,$01,$40,$01,$40,$00,{2}
  194.    $00,$04,$00,$00,$10,$00,{3}
  195.    $00,$04,$00,$00,$10,$00,{4}
  196.    $00,$01,$05,$50,$40,$00,{5}
  197.    $00,$05,$55,$55,$50,$00,{6}
  198.    $00,$15,$55,$55,$54,$00,{7}
  199.    $00,$15,$01,$40,$55,$00,{8}
  200.    $00,$55,$05,$41,$55,$00,{9}
  201.    $05,$55,$01,$40,$55,$50,{10}
  202.    $15,$55,$54,$15,$55,$54,{11}
  203.    $14,$15,$54,$15,$54,$14,{12}
  204.    $14,$05,$55,$55,$50,$14,{13}
  205.    $14,$05,$55,$55,$50,$14,{14}
  206.    $14,$05,$00,$00,$50,$14,{15}
  207.    $00,$01,$40,$01,$40,$00),{16}
  208.     { 4 }
  209.   (0,  0,$00,$00,$54,$15,{0}
  210.    $00,$00,$84,$0B,$10,$06,{1}
  211.    $00,$00,$04,$10,$00,$00,{2}
  212.    $01,$40,$15,$54,$01,$40,{3}
  213.    $05,$50,$55,$55,$05,$50,{4}
  214.    $14,$14,$55,$55,$14,$14,{5}
  215.    $14,$14,$55,$55,$14,$14,{6}
  216.    $05,$55,$55,$55,$55,$50,{7}
  217.    $01,$50,$55,$55,$05,$40,{8}
  218.    $00,$00,$50,$05,$00,$00,{9}
  219.    $00,$00,$10,$04,$00,$00,{10}
  220.    $00,$00,$10,$04,$00,$00,{11}
  221.    $00,$01,$51,$45,$40,$00,{12}
  222.    $00,$15,$55,$55,$54,$00,{13}
  223.    $01,$50,$50,$05,$05,$40,{14}
  224.    $05,$01,$40,$01,$40,$50,{15}
  225.    $14,$05,$00,$00,$50,$14),{16}
  226.     { 5 }
  227.   (0,  0,$50,$14,$00,$00,{0}
  228.    $14,$05,$20,$0B,$10,$06,{1}
  229.    $00,$00,$04,$10,$00,$00,{2}
  230.    $00,$00,$14,$14,$00,$00,{3}
  231.    $00,$00,$55,$55,$00,$00,{4}
  232.    $01,$40,$55,$55,$01,$40,{5}
  233.    $05,$50,$55,$55,$05,$50,{6}
  234.    $15,$54,$55,$55,$15,$54,{7}
  235.    $14,$14,$55,$55,$14,$14,{8}
  236.    $05,$55,$55,$55,$55,$50,{9}
  237.    $01,$50,$55,$55,$05,$40,{10}
  238.    $00,$00,$14,$14,$00,$00,{11}
  239.    $00,$01,$54,$15,$40,$00,{12}
  240.    $00,$05,$55,$55,$50,$00,{13}
  241.    $00,$14,$04,$10,$14,$00,{14}
  242.    $00,$50,$14,$14,$05,$00,{15}
  243.    $00,$40,$10,$04,$01,$00),{16}
  244.     { 6 }
  245.   (0,  0,$00,$50,$14,$14,{0}
  246.    $05,$00,$4C,$0C,$10,$06,{1}
  247.    $00,$10,$01,$40,$04,$00,{2}
  248.    $00,$14,$01,$40,$14,$00,{3}
  249.    $00,$15,$01,$40,$54,$00,{4}
  250.    $00,$11,$41,$41,$44,$00,{5}
  251.    $00,$15,$55,$55,$54,$00,{6}
  252.    $05,$55,$41,$41,$55,$50,{7}
  253.    $15,$55,$51,$45,$55,$54,{8}
  254.    $50,$15,$55,$55,$54,$05,{9}
  255.    $40,$14,$55,$55,$14,$01,{10}
  256.    $50,$50,$50,$05,$05,$05,{11}
  257.    $00,$50,$11,$44,$05,$00,{12}
  258.    $00,$50,$05,$50,$05,$00,{13}
  259.    $00,$50,$01,$40,$05,$00,{14}
  260.    $01,$40,$01,$40,$01,$40,{15}
  261.    $05,$50,$00,$00,$05,$50),{16}
  262.     { 7 }
  263.   (0,  0,$15,$54,$00,$00,{0}
  264.    $15,$54,$E8,$0B,$10,$06,{1}
  265.    $50,$10,$05,$50,$04,$05,{2}
  266.    $40,$14,$01,$40,$14,$01,{3}
  267.    $50,$15,$01,$40,$54,$05,{4}
  268.    $15,$51,$41,$41,$45,$54,{5}
  269.    $05,$55,$55,$55,$55,$50,{6}
  270.    $00,$05,$05,$50,$50,$00,{7}
  271.    $00,$05,$41,$41,$50,$00,{8}
  272.    $00,$15,$55,$55,$54,$00,{9}
  273.    $00,$14,$50,$05,$14,$00,{10}
  274.    $00,$50,$55,$55,$05,$00,{11}
  275.    $00,$50,$55,$55,$05,$00,{12}
  276.    $00,$50,$05,$50,$05,$00,{13}
  277.    $00,$50,$01,$40,$05,$00,{14}
  278.    $00,$14,$00,$00,$14,$00,{15}
  279.    $00,$55,$00,$00,$55,$00),{16}
  280.     { 8 }
  281.   (0,$01,$55,$50,$05,$55,{0}
  282.    $40,$14,$0D,$0A,$10,$06,{1}
  283.    $00,$00,$00,$00,$00,$00,{2}
  284.    $00,$00,$50,$05,$00,$00,{3}
  285.    $00,$01,$54,$15,$40,$00,{4}
  286.    $00,$05,$55,$55,$50,$00,{5}
  287.    $00,$05,$01,$40,$50,$00,{6}
  288.    $00,$15,$11,$44,$54,$00,{7}
  289.    $01,$55,$55,$55,$55,$40,{8}
  290.    $15,$15,$40,$01,$54,$54,{9}
  291.    $14,$05,$41,$41,$50,$14,{10}
  292.    $14,$05,$55,$55,$50,$14,{11}
  293.    $14,$15,$05,$50,$54,$14,{12}
  294.    $14,$14,$01,$40,$14,$14,{13}
  295.    $00,$15,$00,$00,$54,$00,{14}
  296.    $00,$05,$54,$15,$50,$00,{15}
  297.    $00,$01,$54,$15,$40,$00),{16}
  298.     { 9 }
  299.   ( 0,  0,$00,$00,$00,$00,{0}
  300.    00,$00,$B0,$0C,$10,$06,{1}
  301.    $00,$00,$00,$00,$00,$00,{2}
  302.    $14,$00,$50,$05,$00,$14,{3}
  303.    $14,$01,$54,$15,$40,$14,{4}
  304.    $14,$05,$55,$55,$50,$14,{5}
  305.    $14,$05,$11,$44,$50,$14,{6}
  306.    $15,$15,$01,$40,$54,$54,{7}
  307.    $01,$55,$55,$55,$55,$40,{8}
  308.    $00,$15,$50,$05,$54,$00,{9}
  309.    $00,$05,$55,$55,$50,$00,{10}
  310.    $00,$05,$55,$55,$50,$00,{11}
  311.    $00,$15,$05,$50,$54,$00,{12}
  312.    $00,$14,$00,$00,$14,$00,{13}
  313.    $00,$54,$00,$00,$15,$00,{14}
  314.    $15,$50,$00,$00,$05,$54,{15}
  315.    $15,$40,$00,$00,$01,$54),{16}
  316.     { 10 }
  317.   (0,$00,$00,$00,$00,$00,{0}
  318.    $00,$78,$0D,$0A,$10,$06,{1}
  319.    $00,$00,$01,$40,$00,$00,{2}
  320.    $00,$00,$01,$40,$00,$00,{3}
  321.    $00,$00,$05,$50,$00,$00,{4}
  322.    $00,$00,$15,$54,$00,$00,{5}
  323.    $00,$00,$55,$55,$00,$00,{6}
  324.    $55,$55,$55,$55,$55,$55,{7}
  325.    $00,$00,$44,$11,$00,$00,{8}
  326.    $00,$00,$55,$55,$00,$00,{9}
  327.    $00,$00,$55,$55,$00,$00,{10}
  328.    $00,$05,$55,$55,$50,$00,{11}
  329.    $00,$01,$55,$55,$40,$00,{12}
  330.    $00,$01,$55,$55,$40,$00,{13}
  331.    $00,$00,$55,$55,$00,$00,{14}
  332.    $00,$00,$51,$45,$00,$00,{15}
  333.    $00,$00,$51,$45,$00,$00),{16}
  334.     { 11 }
  335.   (0,$00,$00,$51,$45,$00,{0}
  336.    $00,$0D,$0A,$11,$0E,$06,{1}
  337.    $00,$00,$05,$50,$00,$00,{2}
  338.    $00,$00,$10,$04,$00,$00,{3}
  339.    $00,$00,$40,$01,$00,$00,{4}
  340.    $00,$01,$00,$00,$40,$00,{5}
  341.    $00,$04,$00,$00,$10,$00,{6}
  342.    $05,$54,$44,$11,$15,$50,{7}
  343.    $55,$55,$55,$55,$55,$55,{8}
  344.    $00,$50,$10,$14,$01,$00,{9}
  345.    $00,$51,$51,$44,$51,$00,{10}
  346.    $00,$51,$51,$44,$01,$00,{11}
  347.    $00,$51,$51,$44,$55,$00,{12}
  348.    $00,$10,$10,$14,$54,$00,{13}
  349.    $00,$05,$55,$55,$50,$00,{14}
  350.    $00,$00,$00,$00,$00,$00,{15}
  351.    $5F,$11,$0D,$0A,$06,$00),{16}
  352.     { 12 }
  353.   (0,$00,$01,$00,$00,$00,{0}
  354.    $00,$00,$00,$00,$00,$00,{1}
  355.    $00,$00,$05,$40,$00,$00,{2}
  356.    $00,$00,$15,$50,$00,$00,{3}
  357.    $00,$01,$55,$55,$00,$00,{4}
  358.    $01,$55,$44,$44,$54,$50,{5}
  359.    $55,$55,$55,$55,$55,$54,{6}
  360.    $15,$55,$55,$55,$55,$50,{7}
  361.    $00,$01,$55,$55,$00,$00,{8}
  362.    $00,$01,$11,$11,$00,$00,{9}
  363.    $9F,$11,$06,$02,$01,$10,{10}
  364.    $01,$10,$01,$50,$00,$40,{11}
  365.    $00,$40,$00,$40,$AF,$11,{12}
  366.    $0D,$0A,$01,$10,$10,$10,{13}
  367.    $10,$10,$10,$10,$10,$54,{14}
  368.    $44,$00,$00,$00,$F9,$0E,{15}
  369.    $10,$06,$00,$00,$00,$00),{16}
  370.     { 13 }
  371.   (0,  0,  0,  0,$00,$00,{0}
  372.    $00,$00,$00,$00,$00,$40,{1}
  373.    $00,$00,$40,$44,$00,$00,{2}
  374.    $00,$00,$00,$10,$00,$00,{3}
  375.    $00,$05,$15,$01,$00,$00,{4}
  376.    $00,$01,$54,$15,$50,$00,{5}
  377.    $00,$01,$55,$41,$50,$00,{6}
  378.    $00,$15,$05,$45,$40,$00,{7}
  379.    $01,$01,$50,$54,$40,$00,{8}
  380.    $00,$00,$54,$15,$00,$00,{9}
  381.    $00,$45,$05,$41,$51,$10,{10}
  382.    $00,$00,$01,$40,$44,$00,{11}
  383.    $00,$11,$01,$00,$44,$00,{12}
  384.    $04,$50,$00,$00,$40,$00,{13}
  385.    $44,$00,$00,$00,$00,$00,{14}
  386.    $04,$00,$00,$00,$00,$00,{15}
  387.    $95,$0E,$10,$06,$01,$00),{16}
  388.     { 14 }
  389.   (0,  0,  0,  0,$00,$40,{0}
  390.    $00,$41,$04,$00,$00,$00,{1}
  391.    $04,$10,$10,$40,$11,$04,{2}
  392.    $40,$04,$40,$00,$01,$00,{3}
  393.    $00,$01,$00,$04,$41,$11,{4}
  394.    $01,$00,$10,$40,$11,$04,{5}
  395.    $10,$04,$00,$00,$00,$40,{6}
  396.    $00,$00,$50,$00,$05,$45,{7}
  397.    $01,$00,$01,$00,$51,$50,{8}
  398.    $00,$05,$10,$04,$01,$01,{9}
  399.    $10,$00,$00,$00,$10,$44,{10}
  400.    $01,$04,$04,$00,$40,$41,{11}
  401.    $00,$00,$40,$00,$00,$44,{12}
  402.    $00,$41,$10,$10,$10,$40,{13}
  403.    $10,$04,$04,$00,$00,$04,{14}
  404.    $00,$10,$01,$00,$41,$00,{15}
  405.    $00,$40,$C0,$11,$12,$06){16}
  406.  );
  407. Begin
  408.  PutImage4Bits(X,Y,6*4,17,White,Black,Data[Number]);
  409. End;
  410.  
  411. Procedure ShowAlien(Number:Byte;X,Y:Word);Begin
  412.  PutImage(X,Y,Image[Number]^,NormalPut);
  413. End;
  414.  
  415. Procedure UnshowAlien(X,Y:Word);Begin
  416.  SetFillStyle(SolidFill,Black);
  417.  Bar(X,Y,X+6*4,Y+16);
  418. End;
  419.  
  420. Procedure ShowWall(X:Word);
  421. Const
  422.  Data:Array[1..6*17]of Byte=(
  423.    $00,$00,$00,$00,$00,$00,{0}
  424.    $00,$78,$0D,$0A,$10,$06,{1}
  425.    $00,$00,$01,$40,$00,$00,{2}
  426.    $00,$00,$01,$40,$00,$00,{3}
  427.    $00,$00,$05,$50,$00,$00,{4}
  428.    $00,$00,$15,$54,$00,$00,{5}
  429.    $00,$00,$55,$55,$00,$00,{6}
  430.    $55,$55,$55,$55,$55,$55,{7}
  431.    $00,$00,$44,$11,$00,$00,{8}
  432.    $00,$00,$55,$55,$00,$00,{9}
  433.    $00,$00,$55,$55,$00,$00,{10}
  434.    $00,$05,$55,$55,$50,$00,{11}
  435.    $00,$01,$55,$55,$40,$00,{12}
  436.    $00,$01,$55,$55,$40,$00,{13}
  437.    $00,$00,$55,$55,$00,$00,{14}
  438.    $00,$00,$51,$45,$00,$00,{15}
  439.    $00,$00,$51,$45,$00,$00);{16}
  440. Begin
  441.  PutImage4Bits(X,400,6*4,17,Brown,Black,Data);
  442. End;
  443.  
  444. Procedure _ShowGunner(X,Y:Word);
  445. Const
  446.  Gunner:Array[1..6*17]of Byte=(
  447.    $00,$00,$01,$40,$00,$00,{0}
  448.    $00,$00,$01,$40,$00,$00,{1}
  449.    $00,$00,$01,$40,$00,$00,{2}
  450.    $00,$00,$01,$40,$00,$00,{3}
  451.    $00,$00,$05,$50,$00,$00,{4}
  452.    $00,$00,$15,$54,$00,$00,{5}
  453.    $00,$00,$51,$45,$00,$00,{6}
  454.    $00,$01,$51,$45,$40,$00,{7}
  455.    $00,$15,$11,$44,$54,$00,{8}
  456.    $00,$51,$11,$44,$45,$00,{9}
  457.    $05,$51,$11,$44,$45,$50,{10}
  458.    $45,$54,$55,$55,$15,$51,{11}
  459.    $45,$55,$55,$55,$55,$51,{12}
  460.    $55,$55,$40,$01,$55,$55,{13}
  461.    $40,$05,$00,$00,$50,$01,{14}
  462.    $00,$05,$00,$00,$50,$00,{15}
  463.    $00,$00,$00,$00,$00,$00);{16}
  464. Begin
  465.  PutImage4Bits(X,Y,24,17,White,Black,Gunner);
  466. End;
  467.  
  468. Procedure ShowGunner;Begin
  469.  _ShowGunner(GunnerX shl 3,440);
  470. End;
  471.  
  472. Procedure UnshowGunner;Begin
  473.  SetFillStyle(SolidFill,Black);
  474.  Bar(GunnerX shl 3,440,(GunnerX shl 3)+23,440+16);
  475. End;
  476.  
  477. Function NextAlienDirection:Integer;
  478. Var
  479.  I,J:Integer;
  480. Begin
  481.  NextAlienDirection:=Direction;
  482.  If Direction>0 Then Begin
  483.   For J:=10 to 55 do For I:=79 downto 0 do Begin
  484.    If ScreenBoard[J,I]in[1..5]Then Begin
  485.     If I>=79-4 Then Begin
  486.      NextAlienDirection:=-1;
  487.      Exit;
  488.     End;
  489.    End;
  490.   End;
  491.  End
  492.   Else
  493.  If Direction<0 Then Begin
  494.  For J:=10 to 55 do For I:=0 to 79 do Begin
  495.    If ScreenBoard[J,I]in[1..5]Then Begin
  496.     If I<=4 Then Begin
  497.      NextAlienDirection:=1;
  498.      Exit;
  499.     End;
  500.    End;
  501.   End;
  502.  End;
  503. End;
  504.  
  505. Function MoveAlien:Boolean;
  506. Var
  507.  I,J,K:Integer;
  508.  Alien:Byte;
  509.  NextDirection:Integer;
  510. Begin
  511.  MoveAlien:=True;
  512.  CurrSprite:=(CurrSprite+1)and 1;
  513.  NextDirection:=NextAlienDirection;
  514.  If(NextDirection<>Direction)Then Begin
  515.   If NextDirection>0 Then Begin
  516.    For J:=55 downto 10 do For I:=79 downto 0 do Begin
  517.     If ScreenBoard[J,I]in[1..5]Then Begin
  518.      If J+4>50 Then Begin
  519.       MoveAlien:=False;
  520.       Exit;
  521.      End;
  522.      UnshowAlien(I*8,J*8);
  523.      Alien:=ScreenBoard[J,I];
  524.      ScreenBoard[J,I]:=0;
  525.      ScreenBoard[J+4,I+1]:=Alien;
  526.      ShowAlien(Alien*2+CurrSprite,(I+1)*8,(J+4)*8);
  527.     End;
  528.    End;
  529.   End
  530.    Else
  531.   Begin
  532.    For J:=55 downto 10 do For I:=0 to 79 do Begin
  533.     If ScreenBoard[J,I]in[1..5]Then Begin
  534.      If J+4>50 Then Begin
  535.       MoveAlien:=False;
  536.       Exit;
  537.      End;
  538.      UnshowAlien(I*8,J*8);
  539.      Alien:=ScreenBoard[J,I];
  540.      ScreenBoard[J,I]:=0;
  541.      ScreenBoard[J+2,I-1]:=Alien;
  542.      ShowAlien(Alien*2+CurrSprite,(I-1)*8,(J+2)*8);
  543.     End;
  544.    End;
  545.   End;
  546.   Direction:=NextDirection;
  547.  End
  548.   Else
  549.  If Direction>0 Then Begin
  550.   For J:=10 to 55 do For I:=79 downto 0 do Begin
  551.    If ScreenBoard[J,I]in[1..5]Then Begin
  552.     UnshowAlien(I*8,J*8);
  553.     Alien:=ScreenBoard[J,I];
  554.     ScreenBoard[J,I]:=0;
  555.     ScreenBoard[J,I+1]:=Alien;
  556.     ShowAlien(Alien*2+CurrSprite,(I+1)*8,J*8);
  557.     If(LazerAlien>0)Then Dec(LazerAlien)
  558.      Else
  559.     Begin
  560.      LazerAlien:=Random(3);
  561.      For K:=0 to 3 do If AlienBallY[K]=0 Then Begin
  562.       AlienBallX[K]:=(I+1)*8;
  563.       AlienBallY[K]:=J*8;
  564.       Break;
  565.      End;
  566.     End;
  567.    End;
  568.   End;
  569.  End
  570.   Else
  571.  Begin
  572.   For J:=10 to 55 do For I:=0 to 79 do Begin
  573.    If ScreenBoard[J,I]in[1..5]Then Begin
  574.     UnshowAlien(I*8,J*8);
  575.     Alien:=ScreenBoard[J,I];
  576.     ScreenBoard[J,I]:=0;
  577.     ScreenBoard[J,I-1]:=Alien;
  578.     ShowAlien(Alien*2+CurrSprite,(I-1)*8,J*8);
  579.     If(LazerAlien>0)Then Dec(LazerAlien)
  580.      Else
  581.     Begin
  582.      LazerAlien:=Random(3);
  583.      For K:=0 to 3 do If AlienBallY[K]=0 Then Begin
  584.       AlienBallX[K]:=(I-1)*8;
  585.       AlienBallY[K]:=J*8;
  586.       Break;
  587.      End;
  588.     End;
  589.    End;
  590.   End;
  591.  End;
  592. End;
  593.  
  594. Function AlienCollision(X,Y:Integer;Clear:Boolean):Boolean;
  595. Var
  596.  I,J,K:Integer;
  597. Begin
  598.  AlienCollision:=False;
  599.  For J:=55 downto 10 do For I:=79 downto 0 do Begin
  600.   If ScreenBoard[J,I]in[1..5]Then Begin
  601.    If(X>=I*8)and(X<=I*8+23)and(Y>=J*8)and(Y<=J*8+16)Then Begin
  602.     If(Clear)Then Begin
  603.      For K:=0 to 39 do If ClearY[K]=0 Then Begin
  604.       ClearX[K]:=I*8;
  605.       ClearY[K]:=J*8;
  606.      End;
  607.      ShowAlien(14,I*8,J*8);
  608.     End;
  609.     AlienScore:=(5-ScreenBoard[J,I])*10;
  610.     ScreenBoard[J,I]:=0;
  611.     Dec(AlienCount);
  612.     AlienCollision:=True;
  613.     Exit;
  614.    End;
  615.   End;
  616.  End;
  617. End;
  618.  
  619. Function AlienBallCollision(X,Y:Integer):Boolean;
  620. Var
  621.  I:Integer;
  622. Begin
  623.  AlienBallCollision:=False;
  624.  For I:=0 to 3 do Begin
  625.   If(X>=GunnerX*8)and(X<=GunnerX*8+23)and(Y>=440)and(Y<=460)Then Begin
  626.    AlienBallCollision:=True;
  627.    Exit;
  628.   End;
  629.  End;
  630. End;
  631.  
  632. Function MasterAlienCollision(X,Y:Integer):Boolean;Begin
  633.  MasterAlienCollision:=False;
  634.  If(X>=MasterAlienX)and(X<=MasterAlienX+23)and(Y>=30)and(Y<=30+16)Then Begin
  635.   MasterAlienCollision:=True;
  636.   AlienScore:=100;
  637.   Exit;
  638.  End;
  639. End;
  640.  
  641. Procedure AddScore(X:Integer);Begin
  642.  SetColor(Black);
  643.  OutTextXY(20*8,0,'Pointage : '+LongToStr(Score));
  644.  Score:=Score+X;
  645.  SetColor(Yellow);
  646.  OutTextXY(20*8,0,'Pointage : '+LongToStr(Score));
  647. End;
  648.  
  649. Procedure ShowLives;
  650. Var
  651.  I:Integer;
  652. Begin
  653.  SetColor(White);
  654.  Line(0,460,639,460);
  655.  SetFillStyle(SolidFill,Black);
  656.  Bar(0,462,639,479);
  657.  For I:=1 to Lives do Begin
  658.   _ShowGunner(I*40,462);
  659.  End;
  660. End;
  661.  
  662. Procedure InitBoard;
  663. Var
  664.  I,J:Integer;
  665. Begin
  666.  FillChar(BallX,SizeOf(BallX),0);
  667.  FillChar(BallY,SizeOf(BallY),0);
  668.  FillChar(AlienBallX,SizeOf(AlienBallX),0);
  669.  FillChar(AlienBallY,SizeOf(AlienBallY),0);
  670.  FillChar(ClearX,SizeOf(ClearX),0);
  671.  FillChar(ClearY,SizeOf(ClearY),0);
  672.  LazerAlien:=Random(3);
  673.  BoardCleared:=False;
  674.  GunnerX:=39;
  675.  CurrSprite:=0;
  676.  Direction:=1;
  677.  AlienCount:=0;
  678.  MasterAlienX:=-1;
  679.  AddScore(0);
  680.  For J:=0 to 4 do For I:=0 to 11 do Begin
  681.   If J=4 Then ScreenBoard[10+J*4,16+I*4]:=4
  682.          Else ScreenBoard[10+J*4,16+I*4]:=J+1;
  683.   ShowAlien(ScreenBoard[10+J*4,16+I*4],(16+I*4)*8,(10+J*4)*8);
  684.   Inc(AlienCount);
  685.  End;
  686.  For I:=0 to 3 do ShowWall((20+I*12)*8);
  687.  ShowLives;
  688.  ShowGunner;
  689. End;
  690.  
  691. Procedure MakeImage;
  692. Var
  693.  I:Integer;
  694.  Size:Word;
  695. Begin
  696.  For I:=0 to 14 do Begin
  697.   DrawAlien(I,0,0);
  698.   Size:=ImageSize(0,0,6*4-1,17-1);
  699.   GetMem(Image[I],Size);
  700.   GetImage(0,0,6*4-1,17-1,Image[I]^);
  701.  End;
  702.  ClearDevice;
  703. End;
  704.  
  705. Var
  706.  I:Integer;
  707.  
  708. BEGIN
  709.  FillChar(ScreenBoard,SizeOf(ScreenBoard),0);
  710.  Finish:=False;
  711.  InitScr;
  712.  MakeImage;
  713.  ClearDevice;
  714. OutTextXY(150,0,'XXXXXXXX XXXXXXX  XXXXX    XXXXXXXX XXXXXXXX');
  715.  OutTextXY(150,8,'X    XXX X     XX X   XX   X    XXX X       ');
  716.  OutTextXY(150,16,'X    XXX X      X X    X   X    XXX X       ');
  717.  OutTextXY(150,24,'X        X      X X    X   X    XXX X       ');
  718.  OutTextXY(150,32,'X        XX     X XX    X  X        XX      ');
  719.  OutTextXY(150,40,'XXXXXXXX XXXXXXXX XXXXXXXX X        XXXXXX  ');
  720.  OutTextXY(150,48,'     XXX XXX      XXX    X X        XXX     ');
  721.  OutTextXY(150,56,'     XXX XXX      XXX    X X        XXX     ');
  722.  OutTextXY(150,64,'X    XXX XXX      XXX    X X      X XXX     ');
  723.  OutTextXY(150,72,'X    XXX XXX      XXX    X X      X XXX     ');
  724.  OutTextXY(150,80,'XXXXXXXX XXX      XXX    X XXXXXXXX XXXXXXXX');
  725.  SetColor(LightRed);
  726.  OutTextXY(50,96,'  X   XXX    XX      X  XXXXX XXXXXXX XXXXXXXXXXXXXX  XXXXXXXX');
  727.  OutTextXY(50,104,'  X   X  X   XX      X  X   XXXXX   XXX       X    XX X    XXX');
  728.  OutTextXY(50,112,'  X   X   X  XX      X  X    XXXX    XX       X     X X    XXX');
  729.  OutTextXY(50,120,'  X   X    X XX      X  X    XXXX    XX       X     X X       ');
  730.  OutTextXY(50,128,' XX   X     XXX     XX XX    XXXX    XXX      XX    XXX       ');
  731.  OutTextXY(50,136,'XXX   X      XX    XXXXXXXXXXXXXX    XXXXXXX  XXXXXXXXXXXXXXXX');
  732.  OutTextXY(50,144,'XXX   X      XX    XXXXXX    XXXX    XXXX     XXX   XX     XXX');
  733.  OutTextXY(50,152,'XXX   X      XX    XXXXXX    XXXX    XXXX     XXX   XX     XXX');
  734.  OutTextXY(50,160,'XXX   X  XX  X X   XX XXX    XXXX    XXXX     XXX   XXX    XXX');
  735.  OutTextXY(50,168,'XXX   X  XX  X  X  X  XXX    XXXX    XXXX     XXX   XXX    XXX');
  736.  OutTextXY(50,176,'XXX   X  XX  X   XX   XXX    XXXXXXXXXXXXXXXXXXXX   XXXXXXXXXX');
  737. SetColor(White);
  738.  OutTextXY(50,280,'Table avancé des pointages :');
  739.  For I:=0 to 3 do Begin
  740.   ShowAlien(I*2,100,300+I*20);
  741.   OutTextXY(130,300+I*20,'='+LongToStr((3-I)*10)+' points');
  742.  End;
  743.  ShowAlien(11,100,380);
  744.  OutTextXY(130,380,'=100 points');
  745.  OutTextXY(0,460,'Presse une touche pour jouer...');
  746.  ReadKey;
  747.  ClearDevice;
  748.  Score:=0;
  749.  Lives:=3;
  750.  InitBoard;
  751.  Repeat
  752.   Repeat
  753.    If MasterAlienX>=0 Then Begin
  754.     UnshowAlien(MasterAlienX,30);
  755.     If MasterAlienX<=0 Then Begin
  756.      MasterAlienX:=-1;
  757.     End
  758.      Else
  759.     Begin
  760.      Dec(MasterAlienX,8);
  761.      ShowAlien(11+CurrSprite,MasterAlienX,30);
  762.     End;
  763.    End
  764.     Else
  765.    Begin
  766.     If Random(30)=1 Then MasterAlienX:=600
  767.                     Else MasterAlienX:=-1;
  768.    End;
  769.    For I:=0 to 19 do If ClearY[I]<>0 Then Begin
  770.     UnshowAlien(ClearX[I],ClearY[I]);
  771.     ClearY[I]:=0;
  772.     ClearX[I]:=0;
  773.    End;
  774.    If Not(MoveAlien)Then Begin
  775.     ClrKbd;
  776.     SetColor(LightRed);
  777.     OutTextXY(300,220,'Vous avez perdu !');
  778.     ReadKey;
  779.     Finish:=True;
  780.     Break;
  781.    End;
  782.    For I:=0 to 19 do If(BallY[I]>0)Then Begin
  783.     PutPixel(BallX[I],BallY[I],Black);
  784.     If BallY[I]>20 Then Begin
  785.      If GetPixel(BallX[I],BallY[I]-5)=Brown Then Begin
  786.       SetColor(Black);
  787.       Line(BallX[I],BallY[I]-5,BallX[I],BallY[I]);
  788.       BallY[I]:=0;
  789.      End
  790.       Else
  791.      Begin
  792.       Dec(BallY[I],5);
  793.       If MasterAlienCollision(BallX[I],BallY[I])Then Begin
  794.        BallY[I]:=0;
  795.        AddScore(AlienScore);
  796.       End
  797.        Else
  798.       If AlienCollision(BallX[I],BallY[I],True)Then Begin
  799.        BallY[I]:=0;
  800.        AddScore(AlienScore);
  801.       End
  802.        Else
  803.       PutPixel(BallX[I],BallY[I],White);
  804.      End;
  805.     End
  806.      Else
  807.     BallY[I]:=0;
  808.    End;
  809.    For I:=0 to 3 do If(AlienBallY[I]<>0)Then Begin
  810.     PutPixel(AlienBallX[I],AlienBallY[I],Black);
  811.     If AlienBallY[I]<=440 Then Begin
  812.      If GetPixel(AlienBallX[I],AlienBallY[I]+5)=Brown Then Begin
  813.       AlienBallX[I]:=0;
  814.       AlienBallY[I]:=0;
  815.      End
  816.       Else
  817.      Begin
  818.       Inc(AlienBallY[I],5);
  819.       If(AlienBallCollision(AlienBallX[I],AlienBallY[I]))Then Begin
  820.        If Lives>0 Then Begin
  821.         Dec(Lives);
  822.         ShowLives;
  823.         SetColor(LightRed);
  824.         OutTextXY(300,220,'Vous avez été touché !');
  825.         ReadKey;
  826.         SetColor(Black);
  827.         OutTextXY(300,220,'Vous avez été touché !');
  828.         SetColor(White);
  829.         FillChar(AlienBallX,SizeOf(AlienBallX),0);
  830.         FillChar(AlienBallY,SizeOf(AlienBallY),0);
  831.         Break;
  832.        End
  833.         Else
  834.        Begin
  835.         ClrKbd;
  836.         SetColor(LightRed);
  837.         OutTextXY(300,220,'Vous avez perdu !');
  838.         ReadKey;
  839.         Finish:=True;
  840.         Break;
  841.        End;
  842.       End
  843.        Else
  844.       PutPixel(AlienBallX[I],AlienBallY[I],LightRed);
  845.      End;
  846.     End
  847.      Else
  848.     Begin
  849.      AlienBallX[I]:=0;
  850.      AlienBallY[I]:=0;
  851.     End;
  852.    End;
  853.    If AlienCount=0 Then Begin
  854.     ClrKbd;
  855.     SetColor(LightGreen);
  856.     OutTextXY(300,220,'Tableau complété !');
  857.     OutTextXY(150,240,'Presse une touche pour accéder au niveau suivant...');
  858.     Inc(Lives);
  859.     ReadKey;
  860.     BoardCleared:=True;
  861.    End;
  862.    Delay(200);
  863.   Until(Keypressed)or(BoardCleared);
  864.   Case ReadKey of
  865.    #0:Case ReadKey of
  866.     #75:Begin { Gauche }
  867.      UnshowGunner;
  868.      If GunnerX>0 Then GunnerX:=GunnerX-1;
  869.      ShowGunner;
  870.     End;
  871.     #77:Begin { Droite }
  872.      UnshowGunner;
  873.      If GunnerX<77 Then GunnerX:=GunnerX+1;
  874.      ShowGunner;
  875.     End;
  876.    End;
  877.    #27:Finish:=True;
  878.    #32:Begin
  879.     For I:=0 to 19 do Begin
  880.      If BallY[I]=0 Then Begin
  881.       BallX[I]:=GunnerX*8+12;
  882.       BallY[I]:=439;
  883.       Break;
  884.      End;
  885.     End;
  886.    End;
  887.   End;
  888.   If(BoardCleared)Then Begin
  889.    InitBoard;
  890.   End;
  891.  Until Finish;
  892. END.
  893.  

Code source

Voici le code source du jeu sur GitHub :

Lien Langage de programmation Projet
https://github.com/gladir/7iles/blob/main/INVADERS.PAS Turbo Pascal, Free Pascal 7iles


Dernière mise à jour : Jeudi, le 4 août 2022