discord-mini-games-es.js
Version:
Un paquete para implementar minijuegos usando discord.js-v14 en español
108 lines (106 loc) • 5.59 kB
JavaScript
const {createCanvas,registerFont} = require('canvas')
const discord = require('discord.js')
const words = require('./assets/words.json').words
registerFont(__dirname+'/assets/Roboto-Medium.ttf', {family:'Roboto'})
class TypeRunner {
/**
* Initialises a new instance of Type Runner Game.
* @param {`Message/Interaction`} message The Message object.
* @param {`GameOptions-Object`} gameOptions The game Options Object.
* @returns {TypeRunner} Game instance.
*/
constructor(message,gameOptions) {
if(!message) throw new Error("no se proporciona el mensaje.");
this.message = message;
if(gameOptions && typeof gameOptions !== 'object') throw new TypeError("gameOptions debe ser un objeto.");
this.isSlash = gameOptions?.isSlash ?? false;
if(this.isSlash == true){
if(!(this.message instanceof discord.CommandInteraction)){
throw new TypeError("El mensaje debe ser una instancia de Interacción de Comando.")
} } else {
if(!(this.message instanceof discord.Message)) {
throw new TypeError("El mensaje debe ser una instancia de Mensaje de Discord.")
}
}
this.player = this.isSlash == true ? this.message?.user : this.message?.author;
this.time = gameOptions?.time ?? 120000;
this.replied = false;
this.randomN = (min,max) => {return Math.floor(Math.random()*max)+min;}
this.edit = async (messageOptions,replyMessage) => {
messageOptions.fetchReply = true;
if(this.replied == false) {
this.replied=true;
if(this.isSlash == true) return await replyMessage.editReply(messageOptions)
return await this.message.reply(messageOptions);}
else return await replyMessage.edit(messageOptions)
}
this.getSentence = () => {
const number = this.randomN(0,words.length - 11);
return words.slice(number,number+10).map(x => x[0].toUpperCase() + x.slice(1,x.length)).join(" ");
}
this.options = gameOptions;
this.onWin = gameOptions?.onWin ?? null;
this.onLose = gameOptions?.onLose ?? null;
this.onTimeUp = gameOptions?.onTimeUp ?? null;
if(this.onWin && typeof this.onWin !== 'function') throw new TypeError('onWin debe ser una Función');
if(this.onLose && typeof this.onLose !== 'function') throw new TypeError('onLose debe ser una Función');
if(this.onTimeUp && typeof this.onTimeUp !== 'function') throw new TypeError('onTimeUp debe ser una Función');
if(typeof this.isSlash !== 'boolean') throw new TypeError('isSlash debe de ser Boolean');
if(typeof this.time !== 'number') throw new TypeError('time debe ser un Número');
if(this.time < 20000) throw new RangeError('time debe ser mayor que 20000');
if(this.options?.title && typeof this.options?.title !== 'string') throw new TypeError('title debe de ser un string');
if(this.options?.startDes && typeof this.options?.startDes !== 'string') throw new TypeError('startDes debe de ser un string');
if(this.options?.winDes && typeof this.options?.winDes !== 'string') throw new TypeError('winDes must be a string');
if(this.options?.loseDes && typeof this.options?.loseDes !== 'string') throw new TypeError('loseDes debe de ser un string');
if(this.options?.timeUpDes && typeof this.options?.timeUpDes !== 'string') throw new TypeError('timeUpDes debe de ser un string');
}
/**
* Starts The Game.
*/
async run() {
if(this.isSlash == true) {
await this.message.deferReply().catch(() => {});
}
const game = this;
const sentence = this.getSentence();
const canvas = createCanvas(650,50);
const context = canvas.getContext('2d');
context.fillStyle = 'black';
context.fillRect(0,0,canvas.width,canvas.height);
context.font = '20px Roboto'
context.fillStyle = 'white';
context.fillText(sentence,10,25)
function wordEmbed(canvas,color,des) {
const image = new discord.AttachmentBuilder().setFile(canvas.toBuffer()).setName('sentence.png')
const embed = new discord.EmbedBuilder()
.setColor(color)
.setThumbnail(game.player.avatarURL())
.setTimestamp()
.setFooter({text:`Pedido por ${game.player.username}`})
.setTitle(game.options?.title ?? "Type Runner")
.setImage("attachment://sentence.png")
if(des) embed.setDescription(des)
return {embeds:[embed],files:[image] };
}
const msg = await this.edit(wordEmbed(canvas,'Aqua',this.options?.startDes ?? "Escriba la siguiente frase tan rápido como pueda. (con mayúsculas)"),this.message)
try {
const start = Date.now();
const response = await msg.channel.awaitMessages({filter: (m) => m.content && m.author.id == (this.message.user ? this.message.user.id : this.message.author.id), time: this.time,max:1})
const duration = Date.now() - start;
const time = parseFloat(Math.floor(duration/1000)) + parseFloat(parseFloat(parseInt(`${duration/1000}`.split('.')[1])/1000).toFixed(2));
if(response.first().content == sentence) {
await this.edit(wordEmbed(canvas,'Green',this.options?.winDes?.replace(/{time}/g,time) ?? `¡Has ganado! Has tardado ${time} segundos en escribir la frase.`),msg)
if(this.onWin) await this.onWin(time);
}
else {
await this.edit(wordEmbed(canvas,'Red',this.options?.loseDes?.replace(/{time}/g,time) ?? `¡Has perdido! No has escrito la frase correctamente. Has tardado ${time} segundos.`),msg);
if(this.onLose) await this.onLose(time);
}
}
catch(e) {
await this.edit(wordEmbed(canvas,'Red',this.options?.timeUpDes ?? "¡Tiempo!, no has escrito la frase a tiempo.."),msg)
if(this.onTimeUp) return this.onTimeUp();
}
}
}
module.exports = TypeRunner;