by-idb
Version:
A simple terminal snake game library with no external dependencies
118 lines (98 loc) • 3.21 kB
JavaScript
const Snake = require('./snake');
const Food = require('./food');
const { initSystem } = require('./utils');
class Game {
constructor(width = 20, height = 10, speed = 200) {
this.width = width;
this.height = height;
this.speed = speed;
this.score = 0;
this.isRunning = false;
this.snake = new Snake(width, height);
this.food = new Food(width, height);
initSystem();
}
start() {
this.isRunning = true;
this.score = 0;
this.snake.reset();
this.food.generate(this.snake.body);
this.setupInput();
this.gameLoop();
}
setupInput() {
const readline = require('readline');
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on('keypress', (str, key) => {
if (key.name === 'q') {
this.isRunning = false;
process.exit();
}
if (key.name === 'r') {
this.start();
return;
}
const directions = {
'up': 'up',
'down': 'down',
'left': 'left',
'right': 'right'
};
if (directions[key.name]) {
this.snake.changeDirection(directions[key.name]);
}
});
}
gameLoop() {
if (!this.isRunning) return;
// Move the snake
const ateFood = this.snake.move(this.food.getPosition());
// Check for collisions
if (this.snake.checkCollision()) {
this.gameOver();
return;
}
// If food is eaten
if (ateFood) {
this.score += 10;
this.food.generate(this.snake.body);
}
// Render the game screen
this.render();
// Continue the game loop
setTimeout(() => this.gameLoop(), this.speed);
}
render() {
// Clear screen
console.clear();
// Create game area
const board = Array(this.height).fill().map(() =>
Array(this.width).fill(' ')
);
// Place food
const foodPos = this.food.getPosition();
board[foodPos.y][foodPos.x] = '*';
// Place snake
this.snake.body.forEach((segment, index) => {
board[segment.y][segment.x] = index === 0 ? 'O' : 'o';
});
// Render borders and game area
console.log('┌' + '─'.repeat(this.width) + '┐');
board.forEach(row => {
console.log('│' + row.join('') + '│');
});
console.log('└' + '─'.repeat(this.width) + '┘');
// Display score
console.log(`\nScore: ${this.score}`);
console.log('Press Q to quit, R to restart');
}
gameOver() {
console.clear();
console.log('Game Over!');
console.log(`Final Score: ${this.score}`);
console.log('Press R to restart, Q to quit');
this.isRunning = false;
}
}
module.exports = Game;