Section courante

A propos

Section administrative du site

Le jeu Asteroids est un autre classique de la console Atari 2600. Le but est détruire des vagues d'astéroïdes arrivant de peu toute les directions. Le problème le plus complexe est de faire tournée le vaisseau étant en faite une triangle avec un angle spécifié. Pour y arriver, on doit utiliser une formule trigonométrique basé sur les cosinus et les sinus.

Ensuite, il faut déterminer les collisions possibles entre les astéroïdes et les tirs de vaisseau ou le vaisseau et les astéroïdes. Les collisions peut être de biens des façons, on peut calculer l'espace carré d'un objet avec un autre objet d'espace carré ou bien on peut y aller de façon plus précise en chercher a calculer un cercle. Lorsqu'un le vaisseau et un des astéroïdes a une coordonnée de collision, alors la vie est décrémenté s'il lui en reste un moins, sinon le joueur a perdu la partie.

Le déplacement des astéroïdes est une simple ligne droite dans lequel on ajoute une quantité fixe horizontale et verticale jusqu'à ce qu'il sorte de l'espace visible de l'écran, qu'il soit détruit par un tire ou qu'il frappe le vaisseau. Lorsqu'un astéroïdes est détruit, il augmente le pointage du joueur.

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 ASTEROIDS;
  8.  
  9. Uses {$IFDEF FPC}
  10.       Crt,PtcGraph,PtcCrt,PtcMouse
  11.      {$ELSE}
  12.       Crt,Graph
  13.      {$ENDIF};
  14.  
  15. Const
  16.  TopY=20;
  17.  
  18. Var
  19.  Lives,Score:LongInt;
  20.  Finish,North,South,East,West:Boolean;
  21.  ShipAngle:Real;
  22.  ShipX,ShipY:Integer;
  23.  BallX:Array[0..19]of Integer;
  24.  BallY:Array[0..19]of Integer;
  25.  BallDelta:Array[0..19]of Integer;
  26.  BallAngle:Array[0..19]of Real;
  27.  AsteroidX:Array[0..19]of Integer;
  28.  AsteroidY:Array[0..19]of Integer;
  29.  AsteroidDelta:Array[0..19]of Integer;
  30.  AsteroidAngle:Array[0..19]of Real;
  31.  AsteroidRadius:Array[0..19]of Integer;
  32.  
  33. Function LongToStr(X:LongInt):String;
  34. Var
  35.  S:String;
  36. Begin
  37.  Str(X,S);
  38.  LongToStr:=S;
  39. End;
  40.  
  41. Procedure ClrKbd;Begin
  42.  While(Keypressed)do ReadKey;
  43. End;
  44.  
  45. Procedure InitScr;
  46. Var
  47.  Driver,Mode:Integer;
  48.  ErrCode:Integer;
  49. Begin
  50.  {$IFDEF FPC}
  51.   Driver:=VGA;
  52.   Mode:=VGAHi;
  53.  {$ELSE}
  54.   Driver:=Detect;
  55.   Mode:=VGAHi;
  56.  {$ENDIF}
  57.  InitGraph(Driver,Mode,'');
  58.  ErrCode:=GraphResult;
  59.  If ErrCode=grOk Then Begin
  60.   SetColor(White);
  61.   SetLineStyle(0,0,1);
  62.  End
  63.   Else
  64.  Begin
  65.   WriteLn('Erreur graphique : ',GraphErrorMsg(ErrCode));
  66.   Halt;
  67.  End;
  68. End;
  69.  
  70. Function FindY(X,Y:Integer):Integer;Begin
  71.  FindY:=ShipY+Round(Y*Sin(ShipAngle)+X*Cos(ShipAngle));
  72. End;
  73.  
  74. Function FindX(X,Y:Integer):Integer;Begin
  75.  FindX:=ShipX+Round(Y*Cos(ShipAngle)-X*Sin(ShipAngle));
  76. End;
  77.  
  78. Procedure Ship(Show:Boolean);
  79. Var
  80.  X:Array[0..9]of Integer;
  81. Begin
  82.  FillChar(X,SizeOf(X),0);
  83.  X[0]:=FindX(0,12);
  84.  X[1]:=FindY(0,12);
  85.  X[2]:=FindX(-6,0);
  86.  X[3]:=FindY(-6,0);
  87.  X[4]:=FindX(6,0);
  88.  X[5]:=FindY(6,0);
  89.  X[6]:=X[0];
  90.  X[7]:=X[1];
  91.  If(Show)Then Begin
  92.   SetColor(LightGreen);
  93.   SetFillStyle(SolidFill,Green);
  94.  End
  95.   Else
  96.  Begin
  97.   SetColor(Black);
  98.   SetFillStyle(SolidFill,Black);
  99.  End;
  100.  FillPoly(4,X);
  101. End;
  102.  
  103. Function FindBallY(Ball,X,Y:Integer):Integer;Begin
  104.  FindBallY:=BallY[Ball]+Round(Y*Sin(BallAngle[Ball])+X*Cos(BallAngle[Ball]));
  105. End;
  106.  
  107. Function FindBallX(Ball,X,Y:Integer):Integer;Begin
  108.  FindBallX:=BallX[Ball]+Round(Y*Cos(BallAngle[Ball])-X*Sin(BallAngle[Ball]));
  109. End;
  110.  
  111. Function FindAsteroidY(Asteroid,X,Y:Integer):Integer;Begin
  112.  FindAsteroidY:=AsteroidY[Asteroid]+Round(Y*Sin(AsteroidAngle[Asteroid])+
  113.                 X*Cos(AsteroidAngle[Asteroid]));
  114. End;
  115.  
  116. Function FindAsteroidX(Asteroid,X,Y:Integer):Integer;Begin
  117.  FindAsteroidX:=AsteroidX[Asteroid]+Round(Y*Cos(AsteroidAngle[Asteroid])-
  118.                 X*Sin(AsteroidAngle[Asteroid]));
  119. End;
  120.  
  121. Function Collision(x1,y1,h1,w1,x2,y2,h2,w2:Integer):Boolean;
  122. Var
  123.  CX1,CX2,CY1,CY2,Dist,R1,R2:Real;
  124. Begin
  125.  CX1:=X1+W1/2.0;
  126.  CY1:=Y1+H1/2.0;
  127.  CX2:=X2+W2/2.0;
  128.  CY2:=Y2+H2/2.0;
  129.  R1:=H1/2.0;
  130.  R2:=H2/2.0;
  131.  Dist:=Sqrt(Sqr(cx2-cx1)+Sqr(cy2-cy1));
  132.  Collision:=Dist<R1+R2;
  133. End;
  134.  
  135. Function AsteroidCollision(Asteroid,X,Y:Integer):Boolean;Begin
  136.  AsteroidCollision:=Collision(X-1,Y-1,3,3,
  137.                               AsteroidX[Asteroid]-AsteroidRadius[Asteroid],
  138.                               AsteroidY[Asteroid]-AsteroidRadius[Asteroid],
  139.                               AsteroidRadius[Asteroid] shl 1,
  140.                               AsteroidRadius[Asteroid] shl 1);
  141. End;
  142.  
  143. Function ShipCollision:Boolean;
  144. Var
  145.  I:Integer;
  146. Begin
  147.  ShipCollision:=False;
  148.  For I:=0 to 19 do Begin
  149.   If Collision(ShipX-6,ShipY-6,12,12,
  150.                           AsteroidX[I]-AsteroidRadius[I],
  151.                           AsteroidY[I]-AsteroidRadius[I],
  152.                           AsteroidRadius[I] shl 1,
  153.                           AsteroidRadius[I] shl 1)Then Begin
  154.    ShipCollision:=True;
  155.    Exit;
  156.   End;
  157.  End;
  158. End;
  159.  
  160. Procedure AddScore(X:Integer);Begin
  161.  SetColor(Black);
  162.  OutTextXY(20*8,0,'Pointage : '+LongToStr(Score));
  163.  Score:=Score+X;
  164.  SetColor(Yellow);
  165.  OutTextXY(20*8,0,'Pointage : '+LongToStr(Score));
  166. End;
  167.  
  168. Procedure ShowLives;
  169. Var
  170.  I:Integer;
  171. Begin
  172.  SetFillStyle(SolidFill,Black);
  173.  Bar(0,0,639,19);
  174.  For I:=1 to Lives do Begin
  175.   ShipAngle:=(PI/2)*3;
  176.   ShipX:=I*20;
  177.   ShipY:=10;
  178.   Ship(True);
  179.  End;
  180. End;
  181.  
  182. Procedure ResetBoard;Begin
  183.  SetColor(Black);
  184.  SetFillStyle(SolidFill,Black);
  185.  Bar(0,TopY,639,479);
  186.  FillChar(BallX,SizeOf(BallX),0);
  187.  FillChar(BallY,SizeOf(BallY),0);
  188.  FillChar(BallDelta,SizeOf(BallDelta),0);
  189.  FillChar(BallAngle,SizeOf(BallAngle),0);
  190.  FillChar(AsteroidX,SizeOf(AsteroidX),0);
  191.  FillChar(AsteroidY,SizeOf(AsteroidY),0);
  192.  FillChar(AsteroidDelta,SizeOf(AsteroidDelta),0);
  193.  FillChar(AsteroidAngle,SizeOf(AsteroidAngle),0);
  194.  FillChar(AsteroidRadius,SizeOf(AsteroidRadius),0);
  195.  AddScore(0);
  196.  ShipX:=320;
  197.  ShipY:=240;
  198.  ShipAngle:=(PI/2)*3;
  199.  Ship(True);
  200. End;
  201.  
  202. Var
  203.  I,J:Integer;
  204.  
  205. BEGIN
  206.  InitScr;
  207.  OutTextXY(0,8,'   ··                                              ··       ···         ');
  208.  OutTextXY(0,16,'   ··              ·                               ··        ··         ');
  209.  OutTextXY(0,24,'  · ··            ··                                         ··         ');
  210.  OutTextXY(0,32,'  · ··   ···· · ······    ····· ·· ···   ·····    ···    ··· ··  ···· · ');
  211.  OutTextXY(0,40,' ·   ·· ··   ··   ··     ··   ·· ··  ·· ··   ··    ··   ··  ··· ··   ·· ');
  212.  OutTextXY(0,48,' ······  ···      ··     ······· ··     ··   ··    ··   ··   ··  ···    ');
  213.  OutTextXY(0,56,'·     ··   ···    ··     ··      ··     ··   ··    ··   ··   ··    ···  ');
  214.  OutTextXY(0,64,'·     ····   ··   ··  ·  ··    · ··     ··   ··    ··   ··   ·· ··   ·· ');
  215.  OutTextXY(0,72,'··   ···· ····     ···    ····· ····     ·····    ····   ···· ··· ····  ');
  216.  ShipX:=100;
  217.  ShipY:=300;
  218.  ShipAngle:=(PI/180)*350;
  219.  Ship(True);
  220.  BallX[0]:=FindX(0,12);
  221.  BallY[0]:=FindY(0,12);
  222.  BallDelta[0]:=12;
  223.  BallAngle[0]:=ShipAngle;
  224.  For I:=0 to 5 do Begin
  225.   Inc(BallDelta[0],5);
  226.   BallX[0]:=FindBallX(0,0,BallDelta[0]);
  227.   BallY[0]:=FindBallY(0,0,BallDelta[0]);
  228.   PutPixel(BallX[0],BallY[0],LightRed);
  229.  End;
  230.  SetColor(White);
  231.  Circle(400,250,25);
  232.  OutTextXY(0,460,'Presse une touche pour jouer...');
  233.  ReadKey;
  234.  ClearDevice;
  235.  Finish:=False;
  236.  Score:=0;
  237.  Lives:=3;
  238.  ShowLives;
  239.  ResetBoard;
  240.  Repeat
  241.   Repeat
  242.    For I:=0 to 19 do Begin
  243.     If AsteroidDelta[I]<>0 Then Begin
  244.      SetColor(Black);
  245.      Circle(AsteroidX[I],AsteroidY[I],AsteroidRadius[I]);
  246.      Inc(AsteroidDelta[I],1);
  247.      AsteroidX[I]:=FindAsteroidX(I,0,AsteroidDelta[I]);
  248.      AsteroidY[I]:=FindAsteroidY(I,0,AsteroidDelta[I]);
  249.      If(AsteroidX[I]<0)or(AsteroidY[I]<0)or(AsteroidX[I]>639)or(AsteroidY[I]>479)Then Begin
  250.       AsteroidX[I]:=0;
  251.       AsteroidY[I]:=0;
  252.       AsteroidDelta[I]:=0;
  253.       SetColor(Black);
  254.       Circle(AsteroidX[I],AsteroidY[I],AsteroidRadius[I]);
  255.      End
  256.       Else
  257.      Begin
  258.       SetColor(White);
  259.       Circle(AsteroidX[I],AsteroidY[I],AsteroidRadius[I]);
  260.      End;
  261.     End;
  262.    End;
  263.    For I:=0 to 19 do Begin
  264.     If AsteroidDelta[I]=0 Then Begin
  265.      AsteroidAngle[I]:=Random*(PI*2);
  266.      AsteroidRadius[I]:=10+Random(3)*5;
  267.      North:=False;South:=False;East:=False;West:=False;
  268.      If AsteroidAngle[I]<PI Then North:=True
  269.                             Else South:=True;
  270.      If(AsteroidAngle[I]>=0.0)and(AsteroidAngle[I]<=PI/2)Then East:=True Else
  271.      If(AsteroidAngle[I]>=2*PI/(3/4))and(AsteroidAngle[I]<=(PI/2))Then East:=True;
  272.      If Not(East)Then West:=True;
  273.      If(North)Then Begin
  274.       AsteroidX[I]:=Random(640);
  275.       AsteroidY[I]:=479;
  276.      End
  277.       Else
  278.      If(East)Then Begin
  279.       AsteroidX[I]:=0;
  280.       AsteroidY[I]:=Random(480);
  281.      End
  282.       Else
  283.      If(West)Then Begin
  284.       AsteroidX[I]:=639;
  285.       AsteroidY[I]:=Random(480);
  286.      End
  287.       Else
  288.      Begin { South }
  289.       AsteroidX[I]:=Random(640);
  290.       AsteroidY[I]:=TopY;
  291.      End;
  292.      AsteroidDelta[I]:=5;
  293.      Break;
  294.     End;
  295.    End;
  296.    For I:=0 to 19 do Begin
  297.     If BallDelta[I]<>0 Then Begin
  298.      PutPixel(BallX[I],BallY[I],Black);
  299.      Inc(BallDelta[I],5);
  300.      BallX[I]:=FindBallX(I,0,BallDelta[I]);
  301.      BallY[I]:=FindBallY(I,0,BallDelta[I]);
  302.      For J:=0 to 19 do Begin
  303.       If AsteroidCollision(J,BallX[I],BallY[I])Then Begin
  304.        SetColor(Black);
  305.        Circle(AsteroidX[J],AsteroidY[J],AsteroidRadius[J]);
  306.        AsteroidX[J]:=0;
  307.        AsteroidY[J]:=0;
  308.        AsteroidDelta[J]:=0;
  309.        AddScore(10);
  310.       End;
  311.      End;
  312.      If(BallX[I]<=0)or(BallY[I]<=TopY)or(BallX[I]>639)or(BallY[I]>479)Then Begin
  313.       BallX[I]:=0;
  314.       BallY[I]:=0;
  315.       BallDelta[I]:=0;
  316.      End
  317.       Else
  318.      Begin
  319.       PutPixel(BallX[I],BallY[I],LightRed);
  320.      End;
  321.     End;
  322.    End;
  323.    If(ShipCollision)Then Begin
  324.     If Lives>0 Then Begin
  325.      Dec(Lives);
  326.      ShowLives;
  327.      SetColor(LightRed);
  328.      OutTextXY(300,220,'Vous avez été touché !');
  329.      ReadKey;
  330.      SetColor(Black);
  331.      OutTextXY(300,220,'Vous avez été touché !');
  332.      SetColor(White);
  333.      ResetBoard;
  334.      Break;
  335.     End
  336.      Else
  337.     Begin
  338.      ClrKbd;
  339.      SetColor(LightRed);
  340.      OutTextXY(300,220,'Vous avez perdu !');
  341.      ReadKey;
  342.      Finish:=True;
  343.      Break;
  344.     End;
  345.    End;
  346.    Delay(200);
  347.   Until Keypressed;
  348.   Case ReadKey of
  349.    #0:Case ReadKey of
  350.     #75:Begin
  351.      Ship(False);
  352.      ShipAngle:=ShipAngle-(PI/180)*20;
  353.      Ship(True);
  354.     End;
  355.     #77:Begin
  356.      Ship(False);
  357.      ShipAngle:=ShipAngle+(PI/180)*20;
  358.      Ship(True);
  359.     End;
  360.    End;
  361.    #27:Finish:=True;
  362.    #32:Begin
  363.     For I:=0 to 19 do Begin
  364.      If BallDelta[I]=0 Then Begin
  365.       BallX[I]:=FindX(0,12);
  366.       BallY[I]:=FindY(0,12);
  367.       BallDelta[I]:=12;
  368.       BallAngle[I]:=ShipAngle;
  369.       Break;
  370.      End;
  371.     End;
  372.    End;
  373.   End;
  374.   ClrKbd;
  375.  Until Finish;
  376. END.
  377.  

Code source

Voici le code source du jeu sur GitHub :

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


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