Guest User

Untitled

a guest
Jul 12th, 2022
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. EnableExplicit
  3.  
  4. InitSprite()
  5. InitKeyboard()
  6.  
  7. #Window_Main = 0
  8. #Screen_Width = 640
  9. #Screen_Height = 360
  10. #Square_Size = 20
  11.  
  12. #Snake_Initial_Length = 8
  13. #Snake_Initial_X = #Screen_Width / 2
  14. #Snake_Initial_Y = #Screen_Height / 2
  15.  
  16. #Snake_Color = $FFFFFF    ; white
  17. #Apple_Color = $0000FF    ; red
  18. #Bg_Color = $320000       ; Dark blue
  19. #Bg_Color_Light = $460000 ; Less Dark Blue
  20.  
  21. Enumeration Sprite
  22.   #Sprite_Snake
  23.   #Sprite_Apple
  24.   #Sprite_BgTile
  25. EndEnumeration
  26.  
  27. Global.q startStep = 0
  28. Global.q stepDuration = 100 ; speed = 10 cells / s
  29.  
  30. Global leftPushed.i = #False
  31. Global rightPushed.i = #False
  32.  
  33. Global Dim snake.Point(0)
  34. Global speed.Point
  35. Global alive.i = #True
  36.  
  37. Global applePos.Point
  38.  
  39. ;------------------------------------------
  40. ; Returns if a point belong to the snake.
  41. ; @param *pos Point The point to test.
  42. ; @Returns #True if the point belongs to the snake,
  43. ;          #False otherwise.
  44. Procedure.i IsSnakeCell(*pos.Point)
  45.  
  46.   Protected snakeCell
  47.  
  48.   For snakeCell = 0 To ArraySize(snake())
  49.     If snake(snakeCell)\x = *pos\x And
  50.        snake(snakeCell)\y = *pos\y
  51.       ProcedureReturn #True
  52.     EndIf
  53.   Next snakeCell        
  54.  
  55.   ProcedureReturn #False
  56.  
  57. EndProcedure
  58.  
  59. ;------------------------------------------
  60. ; Sets the new position of the apple.
  61. ; Ensures that the apple does not appear
  62. ; on the snake.
  63. Procedure NewApple()
  64.   Repeat
  65.     applePos\x = Random(#Screen_Width/#Square_Size-1)*#Square_Size
  66.     applePos\y = Random(#Screen_Height/#Square_Size-1)*#Square_Size
  67.   Until IsSnakeCell(@applePos) = #False
  68. EndProcedure
  69.  
  70. ;------------------------------------------
  71. ; Initializes the game (snake + apple)
  72. Procedure Init()
  73.  
  74.   ; Sets the snake to its initial length
  75.   ReDim snake(#Snake_Initial_Length - 1)
  76.  
  77.   ; Sets the snake to its initial position
  78.   Protected xHead.i = #Snake_Initial_X
  79.   Protected yHead.i = #Snake_Initial_Y
  80.   Protected snakeCell.i
  81.  
  82.   For snakeCell = 0 To ArraySize(snake())
  83.     snake(snakeCell)\x = xHead
  84.     snake(snakeCell)\y = yHead
  85.     xHead - #Square_Size
  86.   Next snakeCell
  87.  
  88.   ; Sets the snake speed
  89.   speed\x = #Square_Size
  90.   speed\y = 0
  91.  
  92.   ; The snake is alive
  93.   alive = #True
  94.  
  95.   ; "Create" a new apple
  96.   NewApple()
  97.  
  98.   ; Initializes keyboard key states
  99.   leftPushed = #False
  100.   rightPushed = #False
  101.  
  102. EndProcedure
  103.  
  104. ;------------------------------------------
  105. ; Draw the game background (the checkerboard)
  106. Procedure DrawBackground()
  107.  
  108.   Protected x, y
  109.   For y = 0 To #Screen_Height Step 2 * #Square_Size
  110.     For x = 0 To #Screen_Width Step 2 * #Square_Size
  111.       DisplaySprite(#Sprite_BgTile, x, y)
  112.     Next x
  113.   Next y
  114.  
  115. EndProcedure
  116.  
  117. ;------------------------------------------
  118. ; Checks if the snake is alive.
  119. ; @Param *pos Point The point to test.
  120. ; @Returns #False if the point is outside the screen
  121. ;                 or on the snake.
  122. ;          #True otherwise.
  123. Procedure.i IsAlive(*pos.Point)
  124.  
  125.   If *pos\x >= #Screen_Width Or
  126.      *pos\x < 0 Or
  127.      *pos\y >= #Screen_Height Or
  128.      *pos\y < 0 Or
  129.      IsSnakeCell(*pos)
  130.     ProcedureReturn #False
  131.   EndIf
  132.  
  133.   ProcedureReturn #True
  134.  
  135. EndProcedure
  136.  
  137. ;------------------------------------------
  138. ; The main function.
  139. ; Creates the window, the screen, the sprites
  140. ; and manages the main game loop.
  141. Procedure Main()
  142.  
  143.   ; Open the window and the screen
  144.   OpenWindow(#Window_Main, 0, 0, #Screen_Width, #Screen_Height, "Snake", #PB_Window_BorderLess)
  145.   OpenWindowedScreen(WindowID(#Window_Main), 0, 0, #Screen_Width, #Screen_Height, #True, 0, 0)
  146.  
  147.   ; Resize the window
  148.   Define desktopCount = ExamineDesktops()
  149.   ResizeWindow(#Window_Main, #PB_Ignore, #PB_Ignore,
  150.                DesktopWidth(0)/DesktopResolutionX(),
  151.                DesktopHeight(0)/DesktopResolutionY())
  152.  
  153.   ; Create the sprite for the snake cell
  154.   CreateSprite(#Sprite_Snake, #Square_Size, #Square_Size)
  155.   StartDrawing(SpriteOutput(#Sprite_Snake))
  156.   Box(0, 0, #Square_Size, #Square_Size, #Snake_Color)
  157.   StopDrawing()
  158.  
  159.   ; Create the sprite for the apple
  160.   CreateSprite(#Sprite_Apple, #Square_Size, #Square_Size)
  161.   StartDrawing(SpriteOutput(#Sprite_Apple))
  162.   Circle(#Square_Size/2, #Square_Size/2, #Square_Size/2-1, #Apple_Color)
  163.   StopDrawing()
  164.  
  165.   ; Create the sprite for the background tile
  166.   CreateSprite(#Sprite_BgTile, 2 * #Square_Size, 2 * #Square_Size)
  167.   StartDrawing(SpriteOutput(#Sprite_BgTile))
  168.   Box(0, 0, 2 * #Square_Size, 2 * #Square_Size, #Bg_Color)
  169.   Box(0, 0, #Square_Size, #Square_Size, #Bg_Color_Light)  
  170.   Box(#Square_Size, #Square_Size, #Square_Size, #Square_Size, #Bg_Color_Light)
  171.   StopDrawing()
  172.  
  173.   ; Initializes the game
  174.   Init()
  175.  
  176.   Protected event
  177.   Protected snakeCell
  178.   Protected currentTime
  179.   Protected tmpSpeed
  180.   Protected nextHead.Point
  181.  
  182.   ; Main screen loop
  183.   Repeat
  184.     ; Empty the message queue
  185.     Repeat
  186.       event = WindowEvent()
  187.       Select event
  188.         Case #PB_Event_CloseWindow
  189.           End
  190.       EndSelect
  191.     Until Event = 0
  192.    
  193.     FlipBuffers()
  194.    
  195.     currentTime = ElapsedMilliseconds()
  196.    
  197.     If IsScreenActive()
  198.       If currentTime - startStep > stepDuration      
  199.         ; reinit startStep
  200.         startStep = currentTime
  201.        
  202.         If snake(0)\x + speed\x = applePos\x And snake(0)\y + speed\y = applePos\y
  203.           ; The snake has eaten the apple, it grows by one
  204.           ReDim snake(ArraySize(snake()) + 1)
  205.           ; and a new apple appears
  206.           NewApple()
  207.         EndIf
  208.              
  209.         ; Compute the next position of the snake head
  210.         nextHead\x = snake(0)\x + speed\x
  211.         nextHead\y = snake(0)\y + speed\y
  212.        
  213.         ; Check if the snake will be alive or dead after the move        
  214.         alive = IsAlive(@nextHead)
  215.        
  216.         If alive
  217.           ; The snake is alive, move it.
  218.           ; First its body,
  219.           For snakeCell = ArraySize(snake()) To 1 Step -1
  220.             snake(snakeCell)\x = snake(snakeCell-1)\x
  221.             snake(snakeCell)\y = snake(snakeCell-1)\y
  222.           Next snakeCell
  223.           ; then its head
  224.           snake(0)\x = nextHead\x
  225.           snake(0)\y = nextHead\y        
  226.         Else
  227.           ; The snake is dead, restart the game
  228.           Init()
  229.         EndIf
  230.       EndIf
  231.                  
  232.       ; Display the background
  233.       DrawBackground()
  234.          
  235.       ; Display the snake
  236.       For snakeCell = 0 To ArraySize(snake())
  237.         DisplaySprite(#Sprite_Snake, snake(snakeCell)\x, snake(snakeCell)\y)
  238.       Next snakeCell      
  239.      
  240.       ; Display the apple
  241.       DisplayTransparentSprite(#Sprite_Apple, applePos\x, applePos\y)
  242.     EndIf
  243.    
  244.     ; Check if a key has been pressed
  245.     ExamineKeyboard()
  246.    
  247.     If KeyboardPushed(#PB_Key_Left) And Not leftPushed
  248.       ; The left arrow has been pressed,
  249.       ; rotate the speed vector counterclockwise.
  250.       leftPushed = #True
  251.       tmpSpeed = speed\x
  252.       speed\x = speed\y
  253.       speed\y = -tmpSpeed
  254.     ElseIf KeyboardReleased(#PB_Key_Left)
  255.       ; The left arrow has been released.
  256.       leftPushed = #False
  257.     EndIf
  258.    
  259.     If KeyboardPushed(#PB_Key_Right) And Not rightPushed
  260.       ; The right arrow has been pressed,
  261.       ; rotate the speed vector clockwise.
  262.       rightPushed = #True
  263.       tmpSpeed = speed\x
  264.       speed\x = -speed\y
  265.       speed\y = tmpSpeed
  266.     ElseIf KeyboardReleased(#PB_Key_Right)
  267.       ; The right arrow has been released.
  268.       rightPushed = #False
  269.     EndIf      
  270.    
  271.   Until KeyboardPushed(#PB_Key_Escape)
  272.  
  273. EndProcedure
  274.  
  275. Main()
Advertisement
Add Comment
Please, Sign In to add comment