Advertisement
guvacode

Snake

Jan 16th, 2024
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 8.29 KB | None | 0 0
  1. program snake;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}
  5.   cthreads,
  6.   {$ENDIF}
  7.   Classes, SysUtils, CustApp, RayLib;
  8.  
  9. const
  10.  SNAKE_LENGTH = 256;  // максимальная длина змейки
  11.  SQUARE_SIZE = 31; // размер поля
  12.  screenWidth = 800;  // задаём высоту и ширину окна
  13.  screenHeight = 450;
  14.  
  15. type
  16.   TSnake = record    // тело змейки
  17.     position: TVector2;
  18.     size: TVector2;
  19.     speed: TVector2;
  20.     color: TColorB;
  21.  end;
  22.  
  23.  TFood = record
  24.    position: TVector2;
  25.    size: TVector2;
  26.    active: Boolean;
  27.    color: TColorB;
  28.  end;
  29.  
  30. type
  31.   { TRayApplication }
  32.   TRayApplication = class(TCustomApplication)
  33.   protected
  34.     procedure DoRun; override;
  35.   public
  36.     framesCounter: Integer;
  37.     gameOver: Boolean;
  38.     pause: Boolean;
  39.     fruit: TFood;
  40.     snake: array [0..SNAKE_LENGTH] of TSnake;
  41.     snakePosition: array [0..SNAKE_LENGTH] of TVector2;
  42.     allowMove: boolean;
  43.     offset: TVector2;
  44.     counterTail: Integer;
  45.     score: Integer;
  46.     constructor Create(TheOwner: TComponent); override;
  47.     destructor Destroy; override;
  48.  
  49.     procedure InitGame();         // Initialize game
  50.     procedure UpdateGame();       // Update game (one frame)
  51.     procedure DrawGame();         // Draw game (one frame)
  52.     procedure UnloadGame();       // Unload game
  53.     procedure UpdateDrawFrame();  // Update and Draw (one frame)
  54.   end;
  55.  
  56.   const AppTitle = 'classic game: snake';
  57.  
  58. { TRayApplication }
  59.  
  60. constructor TRayApplication.Create(TheOwner: TComponent);
  61. begin
  62.   inherited Create(TheOwner);
  63.   InitWindow(screenWidth, screenHeight, AppTitle); // for window settings, look at example - window flags
  64.   InitGame();
  65.   SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  66. end;
  67.  
  68. procedure TRayApplication.DoRun;
  69. begin
  70.   while (not WindowShouldClose) do // Detect window close button or ESC key
  71.   begin
  72.     // Update your variables here
  73.     UpdateDrawFrame();
  74.   end;
  75.   // Stop program loop
  76.   Terminate;
  77. end;
  78.  
  79. destructor TRayApplication.Destroy;
  80. begin
  81.  
  82.   UnloadGame();         // Unload loaded data (textures, sounds, models...)
  83.   CloseWindow(); // Close window and OpenGL context
  84.  
  85.   inherited Destroy;
  86. end;
  87.  
  88. procedure TRayApplication.InitGame();
  89. var i: Integer;
  90. begin
  91.   framesCounter := 0;
  92.   gameOver := false;
  93.   pause := false;
  94.   score := 0; //modify
  95.   counterTail := 1;
  96.   allowMove := false;
  97.  
  98.   offset.x := screenWidth mod SQUARE_SIZE;
  99.   offset.y := screenHeight mod SQUARE_SIZE;
  100.  
  101.   for i:= 0 to SNAKE_LENGTH - 1 do
  102.   begin
  103.     snake[i].position := Vector2Create( offset.x/2, offset.y/2 );
  104.     snake[i].size := Vector2Create( SQUARE_SIZE, SQUARE_SIZE );
  105.     snake[i].speed := Vector2Create( SQUARE_SIZE, 0 );
  106.  
  107.     if i = 0 then snake[i].color := DARKBLUE // бошка
  108.     else snake[i].color := BLUE;   // тело
  109.   end;
  110.  
  111.  // for i := 0 to  SNAKE_LENGTH - 1 do
  112. //  snakePosition[i] := Vector2Create(0,0);
  113.  
  114.   fruit.size := Vector2Create( SQUARE_SIZE, SQUARE_SIZE );
  115.   fruit.color := SKYBLUE;
  116.   fruit.active := false;
  117. end;
  118.  
  119. procedure TRayApplication.UpdateGame();
  120. var i: integer;
  121. begin
  122. if (not gameOver) then
  123. begin
  124.   if (IsKeyPressed(KEY_P)) then pause := not pause;
  125.  
  126.   if (not pause) then
  127.   begin
  128.   // Player control
  129.     if (IsKeyPressed(KEY_RIGHT) and (snake[0].speed.x = 0) and allowMove) then
  130.     begin
  131.       snake[0].speed := Vector2Create (SQUARE_SIZE, 0 );
  132.       allowMove := false;
  133.     end;
  134.  
  135.     if (IsKeyPressed(KEY_LEFT) and (snake[0].speed.x = 0) and allowMove) then
  136.     begin
  137.       snake[0].speed := Vector2Create( -SQUARE_SIZE, 0 );
  138.       allowMove := false;
  139.     end;
  140.  
  141.     if (IsKeyPressed(KEY_UP) and (snake[0].speed.y = 0) and allowMove) then
  142.     begin
  143.       snake[0].speed := Vector2Create( 0, -SQUARE_SIZE );
  144.       allowMove := false;
  145.     end;
  146.  
  147.     if (IsKeyPressed(KEY_DOWN) and (snake[0].speed.y = 0) and allowMove) then
  148.     begin
  149.       snake[0].speed := Vector2Create( 0, SQUARE_SIZE );
  150.       allowMove := false;
  151.     end;
  152.  
  153.     // Snake movement
  154.     for  i:=0 to counterTail -1 do snakePosition[i] := snake[i].position;
  155.     if ((framesCounter mod 10) = 0) then  // speed
  156.     begin
  157.       for i := 0 to counterTail do
  158.       begin
  159.         if (i = 0) then
  160.         begin
  161.           snake[0].position.x += snake[0].speed.x;
  162.           snake[0].position.y += snake[0].speed.y;
  163.           allowMove := true;
  164.         end
  165.         else snake[i].position := snakePosition[i-1];
  166.       end;
  167.     end;
  168.  
  169.     // Wall behaviour  /// проверяем выход за пределы поля
  170.     if (((snake[0].position.x) > (screenWidth - offset.x)) or
  171.        ((snake[0].position.y) > (screenHeight - offset.y)) or
  172.        (snake[0].position.x < 0) or (snake[0].position.y < 0)) then gameOver := true;
  173.  
  174.     // Collision with yourself  Столкновение с самим собой
  175.     for  i := 1 to counterTail -1 do
  176.     begin
  177.       if ((snake[0].position.x = snake[i].position.x) and (snake[0].position.y = snake[i].position.y))
  178.       then gameOver := true;
  179.     end;
  180.  
  181.     // Fruit position calculation    Расчет положения плода
  182.     if (not fruit.active) then
  183.     begin
  184.       fruit.active := True;
  185.       fruit.position := Vector2Create(GetRandomValue (0,(screenWidth div SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.x/2,
  186.       GetRandomValue(0, (screenHeight div SQUARE_SIZE) - 1) * SQUARE_SIZE + offset.y/2);
  187.  
  188.       i := 0;
  189.       while i < counterTail do
  190.       begin
  191.         while (fruit.position.x = snake[i].position.x) and (fruit.position.y = snake[i].position.y) do
  192.         begin
  193.           fruit.position := Vector2Create( GetRandomValue(0, (screenWidth div SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.x/2,
  194.           GetRandomValue(0, (screenHeight div SQUARE_SIZE) - 1)*SQUARE_SIZE + offset.y/2);
  195.           i := 0;  /// Гемоор
  196.         end;
  197.         Inc(i);
  198.       end;
  199.  
  200.     end;
  201.     // Collision  Столкновения
  202.     if ((snake[0].position.x < (fruit.position.x + fruit.size.x)) and
  203.     ((snake[0].position.x + snake[0].size.x) > fruit.position.x) and
  204.     (snake[0].position.y < (fruit.position.y + fruit.size.y)) and
  205.     ((snake[0].position.y + snake[0].size.y) > fruit.position.y)) then
  206.     begin
  207.       snake[counterTail].position := snakePosition[counterTail - 1];
  208.       counterTail += 1;
  209.       fruit.active := false;
  210.       Inc(Score); // mod score
  211.     end;
  212.     Inc(framesCounter);
  213.   end;
  214. end
  215.   else
  216.   begin
  217.     if (IsKeyPressed(KEY_ENTER)) then
  218.     begin
  219.       InitGame();
  220.       gameOver := false;
  221.     end;
  222.   end;
  223. end;
  224.  
  225. procedure TRayApplication.DrawGame();
  226. var i: integer;
  227. begin
  228.   BeginDrawing();
  229.     ClearBackground(RAYWHITE);
  230.  
  231.     if (not gameOver) then
  232.     begin
  233.     // Draw grid lines   Vertical
  234.     for  i := 0 to screenWidth div SQUARE_SIZE + 1 do
  235.     DrawLineV( Vector2Create(SQUARE_SIZE*i + offset.x/2, offset.y/2),
  236.                Vector2Create(SQUARE_SIZE*i + offset.x/2, screenHeight - offset.y/2), LIGHTGRAY);
  237.  
  238.     // horizont
  239.     for i := 0 to screenHeight div SQUARE_SIZE + 1 do
  240.     DrawLineV( Vector2Create(offset.x/2, SQUARE_SIZE*i + offset.y/2),
  241.                Vector2Create(screenWidth - offset.x/2, SQUARE_SIZE*i + offset.y/2), LIGHTGRAY);
  242.  
  243.  
  244.     // Draw fruit to pick
  245.     DrawRectangleV(fruit.position, fruit.size, fruit.color);
  246.  
  247.     // Draw snake
  248.     for i := 0 to counterTail -1 do DrawRectangleV(snake[i].position, snake[i].size, snake[i].color);
  249.  
  250.   if (pause) then  DrawText('GAME PAUSED', screenWidth div 2 - MeasureText('GAME PAUSED', 40) div 2,
  251.      screenHeight div 2 - 40, 40, GRAY);
  252.   end
  253.   else
  254.   begin  // modify add score
  255.   DrawText('PRESS [ENTER] TO PLAY AGAIN', GetScreenWidth() div 2 - MeasureText('PRESS [ENTER] TO PLAY AGAIN', 20) div 2,
  256.   GetScreenHeight() div 2 - 50, 20, GRAY);
  257.  
  258.   // mod
  259.     DrawText(PChar('YOUR SCORE:'+ IntToStr(score)), GetScreenWidth() div 2 - MeasureText(PChar('YOUR SCORE:'+ IntToStr(score)), 20) div 2,
  260.   GetScreenHeight() div 2 - 80, 20, SKYBLUE);
  261.  
  262.  
  263.   end;
  264.   EndDrawing();
  265. end;
  266.  
  267. procedure TRayApplication.UnloadGame();
  268. begin
  269. // TODO: Unload all dynamic loaded data (textures, sounds, models...)
  270. end;
  271.  
  272. procedure TRayApplication.UpdateDrawFrame();
  273. begin
  274.   UpdateGame();
  275.   DrawGame();
  276. end;
  277.  
  278. var
  279.   Application: TRayApplication;
  280. begin
  281.   Application:=TRayApplication.Create(nil);
  282.   Application.Title:=AppTitle;
  283.   Application.Run;
  284.   Application.Free;
  285. end.
  286.  
Tags: Raylib
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement