discordjs-mini-games
Version:
Пакет для мини-игр прямо в дискорде!
174 lines (149 loc) • 5.49 kB
JavaScript
const Discord = require('discord.js');
const WIDTH = 15;
const HEIGHT = 10;
const gameBoard = [];
const apple = { x: 1, y: 1 };
class SnakeGame {
constructor() {
this.snake = [{ x: 5, y: 5 }];
this.snakeLength = 1;
this.score = 1;
this.gameEmbed = null;
this.inGame = false;
for (let y = 0; y < HEIGHT; y++) {
for (let x = 0; x < WIDTH; x++) {
gameBoard[y * WIDTH + x] = "◾";
}
}
}
gameBoardToString() {
let str = ""
for (let y = 0; y < HEIGHT; y++) {
for (let x = 0; x < WIDTH; x++) {
if (x == apple.x && y == apple.y) {
str += "🍎";
continue;
}
let flag = true;
for (let s = 0; s < this.snake.length; s++) {
if (x == this.snake[s].x && y == this.snake[s].y) {
str += "🟩";
flag = false;
}
}
if (flag)
str += gameBoard[y * WIDTH + x];
}
str += "\n";
}
return str;
}
isLocInSnake(pos) {
return this.snake.find(sPos => sPos.x == pos.x && sPos.y == pos.y);
};
newAppleLoc() {
let newApplePos = { x: 0, y: 0 };
do {
newApplePos = { x: parseInt(Math.random() * WIDTH), y: parseInt(Math.random() * HEIGHT) };
} while (this.isLocInSnake(newApplePos))
apple.x = newApplePos.x;
apple.y = newApplePos.y;
}
start(message) {
if (this.inGame)
return;
this.inGame = true;
this.score = 1;
this.snakeLength = 1;
this.snake = [{ x: 5, y: 5 }];
this.newAppleLoc();
const embed = new Discord.MessageEmbed()
.setTitle('Игра "Змейка"')
.setDescription(this.gameBoardToString())
.setTimestamp();
message.channel.send(embed).then(emessage => {
this.gameEmbed = emessage;
this.gameEmbed.react('⬅️');
this.gameEmbed.react('⬆️');
this.gameEmbed.react('⬇️');
this.gameEmbed.react('➡️');
this.gameEmbed.react('❌');
this.waitForReaction();
});
}
step() {
if (apple.x == this.snake[0].x && apple.y == this.snake[0].y) {
this.score += 1;
this.snakeLength++;
this.newAppleLoc();
for (let s = 0; s < this.snake.length; s++) {
if (apple.x == this.snake[s].x && apple.y == this.snake[s].y) {
this.newAppleLoc();
}
}
}
const editEmbed = new Discord.MessageEmbed()
.setTitle('Игра "Змейка"')
.setDescription(this.gameBoardToString())
.setTimestamp();
this.gameEmbed.edit(editEmbed);
this.waitForReaction();
}
gameOver() {
this.inGame = false;
const editEmbed = new Discord.MessageEmbed()
.setTitle('Игра "Змейка"')
.setDescription(`Игра окончена!\nСчёт: ${this.score}`)
.setTimestamp();
this.gameEmbed.edit(editEmbed);
this.gameEmbed.reactions.removeAll()
}
filter(reaction, user) {
return ['⬅️', '⬆️', '⬇️', '➡️'].includes(reaction.emoji.name) && user.id !== this.gameEmbed.author.id;
}
waitForReaction() {
this.gameEmbed.awaitReactions((reaction, user) => this.filter(reaction, user), { max: 1, time: 60000, errors: ['time'] })
.then(collected => {
const reaction = collected.first();
const snakeHead = this.snake[0];
const nextPos = { x: snakeHead.x, y: snakeHead.y };
if (reaction.emoji.name === '⬅️') {
let nextX = snakeHead.x - 1;
if (nextX < 0)
nextX = WIDTH - 1;
nextPos.x = nextX;
}
else if (reaction.emoji.name === '⬆️') {
let nextY = snakeHead.y - 1;
if (nextY < 0)
nextY = HEIGHT - 1;
nextPos.y = nextY;
}
else if (reaction.emoji.name === '⬇️') {
let nextY = snakeHead.y + 1;
if (nextY >= HEIGHT)
nextPos.y = nextY;
}
else if (reaction.emoji.name === '➡️') {
let nextX = snakeHead.x + 1;
if (nextX >= WIDTH)
nextPos.x = nextX;
}
reaction.users.remove(reaction.users.cache.filter(user => user.id !== this.gameEmbed.author.id).first().id).then(() => {
if (this.isLocInSnake(nextPos)) {
this.gameOver();
}
else {
this.snake.unshift(nextPos);
if (this.snake.length > this.snakeLength)
this.snake.pop();
this.step();
}
});
})
.catch(collected => {
this.gameOver();
});
}
}
module.exports = SnakeGame;