//index keeps track of boxes index which can help us move and manipulate the grid let index = 0; //box class creates box objects which have the properties of x postion ,y postion , state ,previousState and index //index helps us find new boxes //box has a method called changeState() which takes in 3 possible states^ : "snk","mpt","pnt" . // "note : the changeState() method can take in other states and will not result in an error // ,but will cause rendering and logic issues in the game" // states pnt for point, mpt for empty , snk for snake. //the method changes the previousState to the current state and then changes the current state to the state we specifed //each box has an unique index which we can use to axcess it class box { constructor(x,y,stt){ this.x = x; this.y = y; this.state = stt; this.previousState = null; this.index = index; index++; } changeState(stt){ this.previousState = this.state; this.state= stt; } } //the game object keeps track of the ingame grid ,if there is a point present in the game, //if the game has been lost const game = { grid : [], haslost : false, hasPoint : true, points : 0, } //snake object //directions "p","l","d","r" function findBox (box,dir){ if(dir == "p") return game.grid[box.index-9]; if(dir =="l") return game.grid[box.index-1]; if(dir == "d") return game.grid[box.index+9]; if(dir =="r") return game.grid[box.index+1]; return null; } const snake = { headbox: {}, tailbox: {}, boxes: [], previousMove : null, move:function (dir) { if(game.haslost) return 0; //find the new box let temp = findBox(this.headbox,dir); if (temp == null) return 0; if(temp === undefined) game.haslost = true; let tempCord = temp.y; if(dir == "l")tempCord++; else tempCord--; if(tempCord > 8 || tempCord < 0 && (dir == "l" || dir == "r")) game.haslost = true; if(temp.state == "snk") game.haslost = true; temp.changeState("snk"); //add it to boxes this.boxes.push(temp); //change the headbox this.headbox = temp; //set tailbox this.tailbox.changeState("mpt"); this.boxes.shift(); this.tailbox = this.boxes[0]; this.previousMove = dir; } , eat: function () { if(this.headbox.previousState == "pnt"){ game.hasPoint = false; game.points++; //find new tailbox in opposite direction let oppositeDir; if(this.previousMove === "p") oppositeDir = "d"; if(this.previousMove === "l") oppositeDir = "r"; if(this.previousMove === "d") oppositeDir = "p"; if(this.previousMove === "r") oppositeDir = "l"; let temp = findBox(this.tailbox,oppositeDir); //change state & push it into boxes temp.changeState("snk"); this.boxes.unshift(temp); // update tailbox this.tailbox = temp; } } } function start() { let randX; let randY; do{ randX = Math.floor(Math.random()*9); randY = Math.floor(Math.random()*9); }while(randX == 4 && randY == 4) for(let i = 0; i < 9; i++){ for(let j = 0 ; j < 9 ; j++){ let tempbox; if(i == 4 && j == 4){ tempbox = new box(j,i,"snk"); snake.headbox = tempbox; snake.tailbox = tempbox; snake.boxes.push(tempbox); }else if ( i == randX && j == randY){ tempbox = new box(j,i,"pnt"); game.hasPoint = true; }else{ tempbox = new box(i,j,"mpt"); } game.grid.push(tempbox); } } } function generatePoint(){ let randIndex; do randIndex = Math.floor(Math.random()*80); while(game.grid[randIndex].state == "snk"); game.hasPoint = true; game.grid[randIndex].changeState("pnt"); } start(); //logic rendering //setup createsCanvas which will be rendered to function setup() { createCanvas(445,445); } //currentDirection is the direction the snake is moving and the nextDirectoin will be //the direction where the snake will go. let currentDirection = null; let nextDirection = null; //keyTyped() function handles the input/output of the game.It detects when a key is pressed //and checks if the key was ether a,d,w or s and it also checks what is the current direction. //If the current direction isn't the opposite of the next direction ,the next direction gets set to the //the coresponding direction function keyTyped() { if (key === "a" && currentDirection != "r") nextDirection = "l"; else if (key === "d" &¤tDirection!= "l") nextDirection = "r"; else if (key === "w" &¤tDirection!= "d") nextDirection = "p"; else if (key === "s" &¤tDirection!= "p") nextDirection = "d"; } //wait time is time between each uptade in the game it will either be 300 or 1000 milliseconds let waitTime = 300; //setInterval waits for waitTime miliseconds then updates the snakes postion ,makes the snake //eat and updates the direction setInterval(() => { currentDirection = nextDirection; snake.eat(); snake.move(nextDirection); }, waitTime); //draw()^ handles the rendering of the game and a few of its logical components //"note:the draw function is in an infinte loop" function draw() { // we initlize wait time to 300 ms waitTime = 300; //if the snakes head is at the edge of the grid^ we set the wait time to 1000 ms so that the player has more time to evade loss //"note: we can tell wether or not if the player is at the edge by looking at the x and y cordinates of the snakes head. //if we at least one of the cordinates is 8 or 0 we know that the //head is at the edge since we are using a 9 by 9 grid (keep in mind that indexing both in the y and the x direction begins at 0)" if(snake.headbox.x == 8 || snake.headbox.x == 0 || snake.headbox.y == 8 || snake.headbox.y == 0) waitTime = 1000; // if the game objects has lost property has been set to true we alret the user if(game.haslost == true) alert('waage'); // if there are no new points in the grid we create one if(game.hasPoint == false) generatePoint(); // we clear the screen of the prevous frame background(155,122,33); // counter helps us keep tract of which box we are rendering let counter = 0; //we use a nested loop itirate over each one of the grids elemnts in a way that we can have an easy time //get the cordinates of the boxes which will match the i and j iterators for(let i = 0; i < 9; i++){ for(let j = 0; j < 9; j++){ //nostroke() stops the game from making strokes noStroke(); //c by default will be 255 but will change if the boxes state is ethier "snk" or "pnt" let c = color(255) if(game.grid[counter].state == "snk") c = color(99,205,11); if(game.grid[counter].state == "pnt") c = color(153,23,144); fill(c); //calucaltes the rectangles postion and draws it rect(5+j*45,5+i*45,45,45); //update the counter so that we can keep trac of things counter++; } } }