Skip to content

Instantly share code, notes, and snippets.

@nicolaisueper
Created August 24, 2018 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicolaisueper/a594673554884276210932f89d088ed9 to your computer and use it in GitHub Desktop.
Save nicolaisueper/a594673554884276210932f89d088ed9 to your computer and use it in GitHub Desktop.
ESP32 + Espruino + SSD1306 + 4 Push Buttons Snake
E.on("init", () => {
const SSD1306 = require("SSD1306");
const OLED_CLOCK_PIN = D22;
const OLED_DATA_PIN = D23;
const OLED_WIDTH = 128;
const OLED_HEIGHT = 64;
const LEFT = D12;
const RIGHT = D26;
const UP = D14;
const DOWN = D27;
const isPinPressed = pin => Boolean(digitalRead(pin));
const setupDisplay = (displayOptions, setupCallback) => {
I2C1.setup(displayOptions);
let device = SSD1306.connect(
I2C1,
() => {
setupCallback(device);
},
{
address: 0x3c
}
);
};
const randomSnakeBite = snake => {
const snakeHasX = X => snake.filter(part => part.x === X);
const snakeHasY = X => snake.filter(part => part.x === X);
let x;
let y;
do {
x = Math.floor(Math.random() * (OLED_WIDTH - 2)) + 1;
} while (!snakeHasX(x));
do {
y = Math.floor(Math.random() * (OLED_HEIGHT - 2)) + 1;
} while (!snakeHasY(y));
return { x: x, y: y };
};
const snake = display => {
let head = { x: OLED_WIDTH / 2 - 1, y: OLED_HEIGHT / 2 - 1 };
let snake = [
head,
{ x: head.x, y: head.y - 1 },
{ x: head.x, y: head.y - 2 },
{ x: head.x, y: head.y - 3 },
{ x: head.x, y: head.y + 4 },
{ x: head.x, y: head.y + 5 }
];
let nextBite = randomSnakeBite(snake);
let orientation = UP;
let buttonPressInterval = setInterval(() => {
if (isPinPressed(LEFT) && orientation !== RIGHT) {
orientation = LEFT;
return;
}
if (isPinPressed(UP) && orientation !== DOWN) {
orientation = UP;
return;
}
if (isPinPressed(DOWN) && orientation !== UP) {
orientation = DOWN;
return;
}
if (isPinPressed(RIGHT) && orientation !== LEFT) {
orientation = RIGHT;
return;
}
}, 5);
let gameLoop = setInterval(() => {
const currentHead = snake[0];
const nextHead = {
x:
orientation === LEFT
? currentHead.x - 1
: orientation === RIGHT
? currentHead.x + 1
: currentHead.x,
y:
orientation === UP
? currentHead.y - 1
: orientation === DOWN
? currentHead.y + 1
: currentHead.y
};
snake = [nextHead].concat(snake);
if (nextHead.x === nextBite.x && nextHead.y === nextBite.y) {
nextBite = randomSnakeBite(snake);
} else {
snake.pop();
}
display.clear();
for (const part of snake) {
display.setPixel(part.x, part.y, 1);
}
display.setPixel(nextBite.x, nextBite.y, 1);
display.flip();
}, 100);
};
const showWelcome = display => {
display.clear();
display.drawString(
"SnakESP",
Math.floor((OLED_WIDTH - "SnakESP".length * 4) / 2),
16
);
display.drawString("Press 'LEFT' (x o o o) to play", 0, 32);
display.flip();
const waitForLeftButton = setInterval(() => {
if (isPinPressed(LEFT)) {
display.clear();
display.flip();
clearInterval(waitForLeftButton);
snake(display);
}
}, 50);
};
const start = display => {
showWelcome(display);
};
setupDisplay(
{
scl: OLED_CLOCK_PIN,
sda: OLED_DATA_PIN
},
device => start(device)
);
});
E.setFlags({ pretokenise: 1 });
save();
@nicolaisueper
Copy link
Author

At this stage you are able to play the game without losing. Good for killing time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment