AkaruiKuraku

script.js

Aug 28th, 2022
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var Snake = (function () {
  2.  
  3.   const INITIAL_TAIL = 4;
  4.   var fixedTail = true;
  5.  
  6.   var intervalID;
  7.  
  8.   var tileCount = 10;
  9.   var gridSize = 400/tileCount;
  10.  
  11.   const INITIAL_PLAYER = { x: Math.floor(tileCount / 2), y: Math.floor(tileCount / 2) };
  12.  
  13.   var velocity = { x:0, y:0 };
  14.   var player = { x: INITIAL_PLAYER.x, y: INITIAL_PLAYER.y };
  15.  
  16.   var walls = false;
  17.  
  18.   var fruit = { x:1, y:1 };
  19.  
  20.   var trail = [];
  21.   var tail = INITIAL_TAIL;
  22.  
  23.   var reward = 0;
  24.   var points = 0;
  25.   var pointsMax = 0;
  26.  
  27.   var ActionEnum = { 'none':0, 'up':1, 'down':2, 'left':3, 'right':4 };
  28.   Object.freeze(ActionEnum);
  29.   var lastAction = ActionEnum.none;
  30.  
  31.   function setup () {
  32.     canv = document.getElementById('gc');
  33.     ctx = canv.getContext('2d');
  34.  
  35.     game.reset();
  36.   }
  37.  
  38.   var game = {
  39.  
  40.     reset: function () {
  41.       ctx.fillStyle = 'grey';
  42.       ctx.fillRect(0, 0, canv.width, canv.height);
  43.  
  44.       tail = INITIAL_TAIL;
  45.       points = 0;
  46.       velocity.x = 0;
  47.       velocity.y = 0;
  48.       player.x = INITIAL_PLAYER.x;
  49.       player.y = INITIAL_PLAYER.y;
  50.       // this.RandomFruit();
  51.       reward = -1;
  52.  
  53.       lastAction = ActionEnum.none;
  54.  
  55.       trail = [];
  56.       trail.push({ x: player.x, y: player.y });
  57.       // for(var i=0; i<tail; i++) trail.push({ x: player.x, y: player.y });
  58.     },
  59.  
  60.     action: {
  61.       up: function () {
  62.         if (lastAction != ActionEnum.down){
  63.           velocity.x = 0;
  64.           velocity.y = -1;
  65.         }
  66.       },
  67.       down: function () {
  68.         if (lastAction != ActionEnum.up){
  69.           velocity.x = 0;
  70.           velocity.y = 1;
  71.         }
  72.       },
  73.       left: function () {
  74.         if (lastAction != ActionEnum.right){
  75.           velocity.x = -1;
  76.           velocity.y = 0;
  77.         }
  78.       },
  79.       right: function () {
  80.         if (lastAction != ActionEnum.left){
  81.           velocity.x = 1;
  82.           velocity.y = 0;
  83.         }
  84.       }
  85.     },
  86.  
  87.     RandomFruit: function () {
  88.       if(walls){
  89.         fruit.x = 1+Math.floor(Math.random() * (tileCount-2));
  90.         fruit.y = 1+Math.floor(Math.random() * (tileCount-2));
  91.       }
  92.       else {
  93.         fruit.x = Math.floor(Math.random() * tileCount);
  94.         fruit.y = Math.floor(Math.random() * tileCount);
  95.       }
  96.     },
  97.  
  98.     log: function () {
  99.       console.log('====================');
  100.       console.log('x:' + player.x + ', y:' + player.y);
  101.       console.log('tail:' + tail + ', trail.length:' + trail.length);
  102.     },
  103.  
  104.     loop: function () {
  105.  
  106.       reward = -0.1;
  107.  
  108.       function DontHitWall () {
  109.         if(player.x < 0) player.x = tileCount-1;
  110.         if(player.x >= tileCount) player.x = 0;
  111.         if(player.y < 0) player.y = tileCount-1;
  112.         if(player.y >= tileCount) player.y = 0;
  113.       }
  114.       function HitWall () {
  115.         if(player.x < 1) game.reset();
  116.         if(player.x > tileCount-2) game.reset();
  117.         if(player.y < 1) game.reset();
  118.         if(player.y > tileCount-2) game.reset();
  119.  
  120.         ctx.fillStyle = 'grey';
  121.         ctx.fillRect(0,0,gridSize-1,canv.height);
  122.         ctx.fillRect(0,0,canv.width,gridSize-1);
  123.         ctx.fillRect(canv.width-gridSize+1,0,gridSize,canv.height);
  124.         ctx.fillRect(0, canv.height-gridSize+1,canv.width,gridSize);
  125.       }
  126.  
  127.       var stopped = velocity.x == 0 && velocity.y == 0;
  128.  
  129.       player.x += velocity.x;
  130.       player.y += velocity.y;
  131.  
  132.       if (velocity.x == 0 && velocity.y == -1) lastAction = ActionEnum.up;
  133.       if (velocity.x == 0 && velocity.y == 1) lastAction = ActionEnum.down;
  134.       if (velocity.x == -1 && velocity.y == 0) lastAction = ActionEnum.left;
  135.       if (velocity.x == 1 && velocity.y == 0) lastAction = ActionEnum.right;
  136.  
  137.       ctx.fillStyle = 'rgba(40,40,40,0.8)';
  138.       ctx.fillRect(0,0,canv.width,canv.height);
  139.  
  140.       if(walls) HitWall();
  141.       else DontHitWall();
  142.  
  143.       // game.log();
  144.  
  145.       if (!stopped){
  146.         trail.push({x:player.x, y:player.y});
  147.         while(trail.length > tail) trail.shift();
  148.       }
  149.  
  150.       if(!stopped) {
  151.         ctx.fillStyle = 'rgba(200,200,200,0.2)';
  152.         ctx.font = "small-caps 14px Helvetica";
  153.         ctx.fillText("(esc) reset", 24, 356);
  154.         ctx.fillText("(space) pause", 24, 374);
  155.       }
  156.  
  157.       ctx.fillStyle = 'green';
  158.       for(var i=0; i<trail.length-1; i++) {
  159.         ctx.fillRect(trail[i].x * gridSize+1, trail[i].y * gridSize+1, gridSize-2, gridSize-2);
  160.  
  161.         // console.debug(i + ' => player:' + player.x, player.y + ', trail:' + trail[i].x, trail[i].y);
  162.         if (!stopped && trail[i].x == player.x && trail[i].y == player.y){
  163.           game.reset();
  164.         }
  165.         ctx.fillStyle = 'lime';
  166.       }
  167.       ctx.fillRect(trail[trail.length-1].x * gridSize+1, trail[trail.length-1].y * gridSize+1, gridSize-2, gridSize-2);
  168.  
  169.       if (player.x == fruit.x && player.y == fruit.y) {
  170.         if(!fixedTail) tail++;
  171.         points++;
  172.         if(points > pointsMax) pointsMax = points;
  173.         reward = 1;
  174.         game.RandomFruit();
  175.         // make sure new fruit didn't spawn in snake tail
  176.         while((function () {
  177.           for(var i=0; i<trail.length; i++) {
  178.             if (trail[i].x == fruit.x && trail[i].y == fruit.y) {
  179.               game.RandomFruit();
  180.               return true;
  181.             }
  182.           }
  183.           return false;
  184.         })());
  185.       }
  186.  
  187.       ctx.fillStyle = 'red';
  188.       ctx.fillRect(fruit.x * gridSize+1, fruit.y * gridSize+1, gridSize-2, gridSize-2);
  189.  
  190.       if(stopped) {
  191.         ctx.fillStyle = 'rgba(250,250,250,0.8)';
  192.         ctx.font = "small-caps bold 14px Helvetica";
  193.         ctx.fillText("press ARROW KEYS to START...", 24, 374);
  194.       }
  195.  
  196.       ctx.fillStyle = 'white';
  197.       ctx.font = "bold small-caps 16px Helvetica";
  198.       ctx.fillText("points: " + points, 288, 40);
  199.       ctx.fillText("top: " + pointsMax, 292, 60);
  200.  
  201.       return reward;
  202.     }
  203.   }
  204.  
  205.   function keyPush (evt) {
  206.     switch(evt.keyCode) {
  207.       case 37: //left
  208.       game.action.left();
  209.       evt.preventDefault();
  210.       break;
  211.  
  212.       case 38: //up
  213.       game.action.up();
  214.       evt.preventDefault();
  215.       break;
  216.  
  217.       case 39: //right
  218.       game.action.right();
  219.       evt.preventDefault();
  220.       break;
  221.  
  222.       case 40: //down
  223.       game.action.down();
  224.       evt.preventDefault();
  225.       break;
  226.  
  227.       case 32: //space
  228.       Snake.pause();
  229.       evt.preventDefault();
  230.       break;
  231.  
  232.       case 27: //esc
  233.       game.reset();
  234.       evt.preventDefault();
  235.       break;
  236.     }
  237.   }
  238.  
  239.   return {
  240.     start: function (fps = 15) {
  241.       window.onload = setup;
  242.       intervalID = setInterval(game.loop, 1000 / fps);
  243.     },
  244.  
  245.     loop: game.loop,
  246.  
  247.     reset: game.reset,
  248.  
  249.     stop: function () {
  250.       clearInterval(intervalID);
  251.     },
  252.  
  253.     setup: {
  254.       keyboard: function (state) {
  255.         if (state) {
  256.           document.addEventListener('keydown', keyPush);
  257.         } else {
  258.           document.removeEventListener('keydown', keyPush);
  259.         }
  260.       },
  261.       wall: function (state) {
  262.         walls = state;
  263.       },
  264.       tileCount: function (size) {
  265.         tileCount = size;
  266.         gridSize = 400 / tileCount;
  267.       },
  268.       fixedTail: function (state) {
  269.         fixedTail = state;
  270.       }
  271.     },
  272.  
  273.     action: function (act) {
  274.       switch(act) {
  275.         case 'left':
  276.           game.action.left();
  277.           break;
  278.  
  279.         case 'up':
  280.           game.action.up();
  281.           break;
  282.  
  283.         case 'right':
  284.           game.action.right();
  285.           break;
  286.  
  287.         case 'down':
  288.           game.action.down();
  289.           break;
  290.       }
  291.     },
  292.  
  293.     pause: function () {
  294.       velocity.x = 0;
  295.       velocity.y = 0;
  296.     },
  297.  
  298.     clearTopScore: function () {
  299.       pointsMax = 0;
  300.     },
  301.  
  302.     data: {
  303.       player: player,
  304.       fruit: fruit,
  305.       trail: function () {
  306.         return trail;
  307.       }
  308.     },
  309.  
  310.     info: {
  311.       tileCount: tileCount
  312.     }
  313.   };
  314.  
  315. })();
  316.  
  317. Snake.start(8);
  318. Snake.setup.keyboard(true);
  319. Snake.setup.fixedTail(false);
  320.  
Add Comment
Please, Sign In to add comment