Skip to content

Instantly share code, notes, and snippets.

@avdotion
Last active August 12, 2018 22:01
Show Gist options
  • Save avdotion/c59dbe86be4bf43fb78a8cc4b49e9514 to your computer and use it in GitHub Desktop.
Save avdotion/c59dbe86be4bf43fb78a8cc4b49e9514 to your computer and use it in GitHub Desktop.
Snake p5.js
const GRID_SCALE = 20;
const GRID_CELLS = 20;
const FPS = 15;
let snake;
let food;
function setup() {
createCanvas(GRID_SCALE * GRID_CELLS, GRID_SCALE * GRID_CELLS);
frameRate(FPS);
snake = new Snake();
food = new Food();
food.respawnOut(snake.body);
}
function draw() {
background(51);
if (snake.near(food)) {
snake.eat(food);
food.respawnOut(snake.body);
}
snake.update();
food.show();
snake.show();
}
function keyPressed() {
if (keyCode === UP_ARROW) {
if (snake.yspeed !== 1) {
snake.dir(0, -1);
}
} else if (keyCode === DOWN_ARROW) {
if (snake.yspeed !== -1) {
snake.dir(0, 1);
}
} else if (keyCode === RIGHT_ARROW) {
if (snake.xspeed !== -1) {
snake.dir(1, 0);
}
} else if (keyCode === LEFT_ARROW) {
if (snake.xspeed !== 1) {
snake.dir(-1, 0);
}
}
}
class SnakeCell {
constructor(x, y) {
this.x = x;
this.y = y;
}
show() {
fill(255);
rect(this.x, this.y, GRID_SCALE, GRID_SCALE);
}
}
class Snake {
constructor() {
this.xspeed = 1;
this.yspeed = 0;
let head = new SnakeCell(0, 0);
this.body = [head];
this.growing = false;
}
get head() {
return this.body[0];
}
update() {
let head = new SnakeCell(this.body[0].x, this.body[0].y);
head.x += this.xspeed*GRID_SCALE;
head.y += this.yspeed*GRID_SCALE;
if (!this.growing) {
this.body.pop();
} else {
this.growing = false;
}
this.body.unshift(head);
if (this.intersection()) {
this.reborn();
}
}
show() {
this.body.forEach(cell => cell.show());
}
dir(x, y) {
this.xspeed = x;
this.yspeed = y;
}
near(food) {
return dist(this.head.x, this.head.y, food.x, food.y) < GRID_SCALE;
}
eat(food) {
this.growing = true;
}
intersection() {
for (let i = 1; i < this.body.length; i++) {
let cell = this.body[i];
if (this.head.x === cell.x && this.head.y === cell.y) {
return true;
}
}
return false;
}
reborn() {
let head = this.head;
this.body = [head];
}
}
class Food {
constructor() {
this.x = 0;
this.y = 0;
}
show() {
fill(255, 0, 100);
rect(this.x, this.y, GRID_SCALE, GRID_SCALE);
}
respawnOut(body) {
let found = false;
do {
let x = floor(random(width) / GRID_SCALE) * GRID_SCALE;
let y = floor(random(height) / GRID_SCALE) * GRID_SCALE;
body.forEach(cell => {
if (!(cell.x === x && cell.y === y)) {
found = true;
this.x = x;
this.y = y;
}
});
} while (!found);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment