Advertisement
Guest User

Help?!

a guest
May 5th, 2017
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Simple Snake Game</title>
  6.    
  7.     <!-- Basic styling, centering of the canvas. -->
  8.     <style>
  9.     canvas {
  10.         display: block;
  11.         position: absolute;
  12.         border: 1px solid #000;
  13.         margin: auto;
  14.         top: 0;
  15.         bottom: 0;
  16.         right: 0;
  17.         left: 0;
  18.     }
  19.     </style>
  20. </head>
  21. <body>
  22. <script>
  23. /** NEW VARIABLE ADDED AND eventListener **/
  24. var gamePaused = false;
  25. document.addEventListener('keydown', keyDown);
  26.  
  27. var
  28.  
  29. /**
  30.  * Constante
  31.  */
  32. COLS = 28,
  33. ROWS = 28,
  34.  
  35. EMPTY = 0,
  36. SNAKE = 1,
  37. FRUIT = 2,
  38.  
  39. LEFT  = 0,
  40. UP    = 1,
  41. RIGHT = 2,
  42. DOWN  = 3,
  43.  
  44. KEY_LEFT  = 37,
  45. KEY_UP    = 38,
  46. KEY_RIGHT = 39,
  47. KEY_DOWN  = 40,
  48.  
  49. /**
  50.  * Game objects
  51.  */
  52. canvas,   /* HTMLCanvas */
  53. ctx,      /* CanvasRenderingContext2d */
  54. keystate, /* keyboard inputs */
  55. frames,   /* used for animation */
  56. score;    /* keep track of the player score */
  57.  
  58.  
  59. /**
  60.  * Grid datastructor, usefull in games where the game world is
  61.  * confined in absolute sized chunks of data or information.
  62.  *
  63.  * @type {Object}
  64.  */
  65. grid = {
  66.    
  67.     width: null,  /* number, the number of columns */
  68.     height: null, /* number, the number of rows */
  69.     _grid: null,  /* Array<any>, data representation */
  70.  
  71.     /**
  72.      * Initiate and fill a c x r grid with the value of d
  73.      * @param  {any}    d default value to fill with
  74.      * @param  {number} c number of columns
  75.      * @param  {number} r number of rows
  76.      */
  77.     init: function(d, c, r) {
  78.         this.width = c;
  79.         this.height = r;
  80.  
  81.         this._grid = [];
  82.         for (var x=0; x < c; x++) {
  83.             this._grid.push([]);
  84.             for (var y=0; y < r; y++) {
  85.                 this._grid[x].push(d);
  86.             }
  87.         }
  88.     },
  89.  
  90.     /**
  91.      * Set the value of the grid cell at (x, y)
  92.      *
  93.      * @param {any}    val what to set
  94.      * @param {number} x   the x-coordinate
  95.      * @param {number} y   the y-coordinate
  96.      */
  97.     set: function(val, x, y) {
  98.         this._grid[x][y] = val;
  99.     },
  100.  
  101.     /**
  102.      * Get the value of the cell at (x, y)
  103.      *
  104.      * @param  {number} x the x-coordinate
  105.      * @param  {number} y the y-coordinate
  106.      * @return {any}   the value at the cell
  107.      */
  108.     get: function(x, y) {
  109.         return this._grid[x][y];
  110.     }
  111. }
  112. /**
  113. ****/
  114. /**
  115.  * The snake, works as a queue (FIFO, first in first out) of data
  116.  * with all the current positions in the grid with the snake id
  117.  *
  118.  * @type {Object}
  119.  */
  120. snake = {
  121.  
  122.     direction: null, /* number, the direction */
  123.     last: null,      /* Object, pointer to the last element in
  124.                         the queue */
  125.     _queue: null,    /* Array<number>, data representation*/
  126.  
  127.     /**
  128.      * Clears the queue and sets the start position and direction
  129.      *
  130.      * @param  {number} d start direction
  131.      * @param  {number} x start x-coordinate
  132.      * @param  {number} y start y-coordinate
  133.      */
  134.     init: function(d, x, y) {
  135.         this.direction = d;
  136.  
  137.         this._queue = [];
  138.         this.insert(x, y);
  139.     },
  140.  
  141.     /**
  142.      * Adds an element to the queue
  143.      *
  144.      * @param  {number} x x-coordinate
  145.      * @param  {number} y y-coordinate
  146.      */
  147.     insert: function(x, y) {
  148.         // unshift prepends an element to an array
  149.         this._queue.unshift({x:x, y:y});
  150.         this.last = this._queue[0];
  151.     },
  152.  
  153.     /**
  154.      * Removes and returns the first element in the queue.
  155.      *
  156.      * @return {Object} the first element
  157.      */
  158.     remove: function() {
  159.         // pop returns the last element of an array
  160.         return this._queue.pop();
  161.     }
  162. };
  163.  
  164. /**
  165.  * Set a food id at a random free cell in the grid
  166.  */
  167. function setFood() {
  168.     var empty = [];
  169.     // iterate through the grid and find all empty cells
  170.     for (var x=0; x < grid.width; x++) {
  171.         for (var y=0; y < grid.height; y++) {
  172.             if (grid.get(x, y) === EMPTY) {
  173.                 empty.push({x:x, y:y});
  174.             }
  175.         }
  176.     }
  177.     // chooses a random cell
  178.     var randpos = empty[Math.round(Math.random()*(empty.length - 1))];
  179.     grid.set(FRUIT, randpos.x, randpos.y);
  180. }
  181.  
  182. /**
  183.  * Starts the game
  184.  */
  185. function main() {
  186.    
  187.     // create and initiate the canvas element
  188.     canvas = document.createElement("canvas");
  189.     canvas.width = COLS*20;
  190.     canvas.height = ROWS*20;
  191.     ctx = canvas.getContext("2d");
  192.     // add the canvas element to the body of the document
  193.     document.body.appendChild(canvas);
  194.  
  195.     // sets an base font for bigger score display
  196.     ctx.font = "15px Helvetica";
  197.  
  198.     frames = 0;
  199.     keystate = {};
  200.     // keeps track of the keybourd input
  201.     document.addEventListener("keydown", function(evt) {
  202.         keystate[evt.keyCode] = true;
  203.     });
  204.    
  205.     document.addEventListener("keyup", function(evt) {
  206.         delete keystate[evt.keyCode];
  207.     });
  208.  
  209.     // intatiate game objects and starts the game loop
  210.     init();
  211.     loop();
  212. }
  213. /** function that pauses the game **/
  214.  
  215. /**
  216.  * Resets and inits game objects
  217.  */
  218. function init() {
  219.     score = 0;
  220.  
  221.     grid.init(EMPTY, COLS, ROWS);
  222.  
  223.     var sp = {x:Math.floor(COLS/2), y:ROWS-1};
  224.     snake.init(UP, sp.x, sp.y);
  225.     grid.set(SNAKE, sp.x, sp.y);
  226.  
  227.     setFood();
  228. }
  229.  
  230. /**
  231.  * The game loop function, used for game updates and rendering
  232.  */
  233. function loop() {
  234.     //if(gamePause) return;
  235.     update();
  236.     draw();
  237.     // When ready to redraw the canvas call the loop function
  238.     // first. Runs about 60 frames a second
  239.     window.requestAnimationFrame(loop, canvas);
  240.    
  241. }
  242.  
  243. /** PAUSE GAME FUNCTION **/
  244. function pauseGame() {
  245.     gamePaused = !gamePaused; // toggle the gamePaused value (false <-> true)
  246.     if (!gamePaused) loop(); // restart loop
  247. }
  248.  
  249.  
  250. /**
  251.  * Updates the game logic
  252.  */
  253. function update() {
  254.     frames++;
  255.  
  256.     // changing direction of the snake depending on which keys
  257.     // that are pressed
  258.     if (keystate[KEY_LEFT] && snake.direction !== RIGHT) {
  259.         snake.direction = LEFT;
  260.     }
  261.     if (keystate[KEY_UP] && snake.direction !== DOWN) {
  262.         snake.direction = UP;
  263.     }
  264.     if (keystate[KEY_RIGHT] && snake.direction !== LEFT) {
  265.         snake.direction = RIGHT;
  266.     }
  267.     if (keystate[KEY_DOWN] && snake.direction !== UP) {
  268.         snake.direction = DOWN;
  269.     }
  270.  
  271.     // each five frames update the game state.
  272.     if (frames%5 === 0) {
  273.         // pop the last element from the snake queue i.e. the
  274.         // head
  275.         var nx = snake.last.x;
  276.         var ny = snake.last.y;
  277.  
  278.         // updates the position depending on the snake direction
  279.         switch (snake.direction) {
  280.             case LEFT:
  281.                 nx--;
  282.                 break;
  283.             case UP:
  284.                 ny--;
  285.                 break;
  286.             case RIGHT:
  287.                 nx++;
  288.                 break;
  289.             case DOWN:
  290.                 ny++;
  291.                 break;
  292.         }
  293.  
  294.         // checks all gameover conditions
  295.         if (0 > nx || nx > grid.width-1  ||
  296.             0 > ny || ny > grid.height-1 ||
  297.             grid.get(nx, ny) === SNAKE
  298.         ) {
  299.             return init();
  300.         }
  301.  
  302.         // check wheter the new position are on the fruit item
  303.         if (grid.get(nx, ny) === FRUIT) {
  304.             // increment the score and sets a new fruit position
  305.             score++;
  306.             setFood();
  307.         } else {
  308.             // take out the first item from the snake queue i.e
  309.             // the tail and remove id from grid
  310.             var tail = snake.remove();
  311.             grid.set(EMPTY, tail.x, tail.y);
  312.         }
  313.  
  314.         // add a snake id at the new position and append it to
  315.         // the snake queue
  316.         grid.set(SNAKE, nx, ny);
  317.         snake.insert(nx, ny);
  318.     }
  319. }
  320.  
  321. /**
  322.  * Render the grid to the canvas.
  323.  */
  324. function draw() {
  325.     // calculate tile-width and -height
  326.     var tw = canvas.width/grid.width;
  327.     var th = canvas.height/grid.height;
  328.     // iterate through the grid and draw all cells
  329.     for (var x=0; x < grid.width; x++) {
  330.         for (var y=0; y < grid.height; y++) {
  331.             // sets the fillstyle depending on the id of
  332.             // each cell
  333.             switch (grid.get(x, y)) {
  334.                 case EMPTY:
  335.                     ctx.fillStyle = "#d9ddd9";
  336.                     break;
  337.                 case SNAKE:
  338.                     ctx.fillStyle = "#038423";
  339.                     break;
  340.                 case FRUIT:
  341.                     ctx.fillStyle = "#f00";
  342.                     break;
  343.             }
  344.             ctx.fillRect(x*tw, y*th, tw, th);
  345.         }
  346.     }
  347.     // changes the fillstyle once more and draws the score
  348.     // message to the canvas
  349.     ctx.fillStyle = "#000";
  350.     ctx.fillText("SCORE: " + score, 10, canvas.height-10);
  351. }
  352.  
  353. // start and run the game
  354. main();
  355. </script>
  356. </body>
  357. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement