Use arrow keys to control the snake, and avoid walls (or not). Press "SPACE" to pause and admire the mess. Press "S" to hide scores, and "C" to clear the canvas
A fork of Snake game 2 by Kevin
xxxxxxxxxx
let snake;
let gridSize = 40;
let cols, rows;
let cw = 1400, ch = 550;
let food = [];
let foodNum = 10;
let foodImages = []; // Array para imagens de comida
let paintedTiles = []; // Array para rastrear os tiles pintados
let WALL_COLOR = 0;
let BG_COLOR = "#BB9173";
let paused = false;
let currentScore, maxScore;
function preload() {
// Carregar a imagem da cabeça
headImage = loadImage('b1.jpeg');
// Aqui as ilustrações
foodImages.push(loadImage('c9.jpeg'));
foodImages.push(loadImage('c8.jpeg'));
foodImages.push(loadImage('c7.jpeg'));
foodImages.push(loadImage('c6.jpeg'));
foodImages.push(loadImage('c5.jpeg'));
foodImages.push(loadImage('c4.jpeg'));
foodImages.push(loadImage('c3.jpeg'));
foodImages.push(loadImage('c2.jpeg'));
foodImages.push(loadImage('c1.jpeg'));
}
function setup() {
createCanvas(cw + 2 * gridSize, ch + 2 * gridSize);
cols = floor(cw / gridSize);
rows = floor(ch / gridSize);
frameRate(10);
snake = new Snake(getCenter());
spawnFood();
currentScore = snake.body.length;
maxScore = currentScore;
textAlign(LEFT, CENTER);
}
function draw() {
background(BG_COLOR);
fill(WALL_COLOR);
rect(0, 0, width, height);
noStroke();
fill(BG_COLOR);
rect(gridSize, gridSize, cw, ch);
if (!paused) {
snake.update();
}
// Exibir pontuação
fill('white');
textSize(gridSize * 0.5);
text(`Current: ${currentScore} | Max: ${maxScore}`, gridSize, gridSize / 2);
push();
translate(gridSize, gridSize);
// Desenhar os tiles pintados
for (let tile of paintedTiles) {
tile.draw();
}
// Atualizar e desenhar comida
for (let f of food) {
if (snake.eat(f)) {
spawnFood();
}
}
snake.draw();
for (let f of food) {
f.draw();
}
if (snake.crashed()) {
snake.die();
snake.respawn(getCenter());
}
pop();
currentScore = snake.body.length;
maxScore = max(currentScore, maxScore);
}
function spawnFood() {
while (food.length < foodNum) {
let x = floor(random(cols)) * gridSize;
let y = floor(random(rows)) * gridSize;
// Evitar sobreposição de comida
while (food.find((f) => f.x === x && f.y === y)) {
x = floor(random(cols)) * gridSize;
y = floor(random(rows)) * gridSize;
}
food.push(new Food(x, y));
}
}
function keyPressed() {
if (keyCode === UP_ARROW && snake.ySpeed != 1) {
snake.setDirection(0, -1);
} else if (keyCode === DOWN_ARROW && snake.ySpeed != -1) {
snake.setDirection(0, 1);
} else if (keyCode === LEFT_ARROW && snake.xSpeed != 1) {
snake.setDirection(-1, 0);
} else if (keyCode === RIGHT_ARROW && snake.xSpeed != -1) {
snake.setDirection(1, 0);
} else if (keyCode === 32) {
// Espaço para pausar
paused = !paused;
}
}
class Food {
constructor(x, y) {
this.x = x;
this.y = y;
this.image = random(foodImages); // Escolher imagem aleatória
this.r = gridSize; // Tamanho da comida
}
draw() {
push();
translate(this.x, this.y);
// Desenhar sombra
noStroke();
fill(0, 50); // Sombra semi-transparente
rectMode(CENTER);
rect(gridSize / 2 + 3, gridSize / 2 + 3, this.r, this.r);
// Desenhar borda preta
stroke(0);
strokeWeight(2);
noFill();
rectMode(CORNER);
rect(0, 0, this.r, this.r);
// Desenhar a imagem para preencher completamente
imageMode(CORNER);
image(this.image, 0, 0, this.r, this.r);
pop();
}
}
class Snake {
constructor(startX = 0, startY = 0) {
this.respawn(startX, startY);
}
respawn(x, y) {
// Inicializa a cobra com 4 segmentos e suas respectivas posições
this.body = [
createVector(x, y),
createVector(x - gridSize, y),
createVector(x - 2 * gridSize, y),
createVector(x - 3 * gridSize, y)
];
this.xSpeed = 0;
this.ySpeed = 0;
this.lastFoodImage = null; // Para armazenar a última imagem da comida
}
setDirection(x, y) {
this.xSpeed = x;
this.ySpeed = y;
}
update() {
let head = this.body[this.body.length - 1].copy();
let trail = this.body.shift();
head.x += this.xSpeed * gridSize;
head.y += this.ySpeed * gridSize;
// Adicionar ao chão pintado com a última foodImage
if (this.body.length > 1 && this.lastFoodImage) {
paintedTiles.push(new PaintedTile(trail.x, trail.y, this.lastFoodImage)); // Pintar com a última foodImage
}
this.body.push(head);
}
eat(f) {
let head = this.body[this.body.length - 1];
if (head.x === f.x && head.y === f.y) {
this.lastFoodImage = f.image; // Atualizar a imagem da comida para a última comida comida
paintedTiles.push(new PaintedTile(f.x, f.y, f.image)); // Pintar o tile com a imagem da comida
food = food.filter((e) => e !== f);
return true;
}
return false;
}
draw() {
// Vamos desenhar a cobra como um cilindro com degradê
for (let i = 0; i < this.body.length - 1; i++) {
let v1 = this.body[i];
let v2 = this.body[i + 1];
// Interpolar entre as cores de cada segmento do corpo da cobra
let c1 = color('rgb(239,206,7)'); // Cor inicial (vermelho)
let c2 = color('rgb(250,142,63)'); // Cor final (verde)
// Criação do degradê
let lerpedColor = lerpColor(c1, c2, map(i, 0, this.body.length, 0, 1));
// Desenhar o cilindro com efeito de degradê
this.drawCylinder(v1.x + gridSize / 2, v1.y + gridSize / 2, v2.x + gridSize / 2, v2.y + gridSize / 2, lerpedColor);
}
// Desenhar os olhos na cabeça da cobra (primeiro segmento)
this.drawEyes(this.body[3].x, this.body[3].y);
}
drawCylinder(x1, y1, x2, y2, color) {
push();
stroke(color);
strokeWeight(gridSize);
line(x1, y1, x2, y2); // Desenhando a linha que representa o cilindro
pop();
}
drawEyes(x, y) {
x += gridSize / 2;
y += gridSize / 2;
let eyeSize = gridSize * 0.3; // Tamanho dos olhos
let eyeOffset = gridSize * 0.1; // Distância dos olhos da cabeça da cobra
// Olho esquerdo (posicionado corretamente na cabeça)
fill(255); // Branco do olho
ellipse(x - eyeOffset, y - eyeOffset, eyeSize, eyeSize);
// Olho direito
ellipse(x + eyeOffset, y - eyeOffset, eyeSize, eyeSize);
// Pupilas
fill(0); // Pupilas pretas
ellipse(x - eyeOffset, y - eyeOffset, eyeSize / 2, eyeSize / 2);
ellipse(x + eyeOffset, y - eyeOffset, eyeSize / 2, eyeSize / 2);
}
crashed() {
let head = this.body[this.body.length - 1];
if (
head.x >= width - 3 * gridSize ||
head.x < gridSize ||
head.y >= height - 3 * gridSize ||
head.y < gridSize
) {
return true;
}
for (let i = 0; i < this.body.length - 1; i++) {
if (head.x === this.body[i].x && head.y === this.body[i].y) {
return true;
}
}
return false;
}
die() {
// Reiniciar cobra
this.body = [];
}
}
class PaintedTile {
constructor(x, y, image) {
this.x = x;
this.y = y;
this.image = image;
}
draw() {
imageMode(CORNER);
image(this.image, this.x, this.y, gridSize, gridSize);
}
}
function getCenter() {
return [
floor(width / 2 / gridSize) * gridSize,
floor(height / 2 / gridSize) * gridSize,
];
}