我正在尝试为我的 discord 机器人编写二十一点程序。下面的代码发送三个嵌入,一个是玩家的手,一个是庄家的手,另一个询问玩家是想打牌还是停牌。我的第一个问题是它发送了三个命中或停止嵌入然后继续发送它们。我只需要发送一个嵌入并且不再重复。其次,当我按下按钮时,无论是按下还是停止,我都会收到一个错误代码。我使用交互方法执行命令。
看来我的收集器/过滤器无法正确读取用户的 id,我不知道为什么!
这是我的代码:
const Discord = require('discord.js');
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = Discord
const createDeck = require('../functions/deck')
const shuffleDeck = require('../functions/shuffleDeck')
const getHandValue = require('../functions/getHandValue')
async function playBlackjack(message) {
const deck = createDeck();
const shuffledDeck = shuffleDeck(deck);
const playerHand = [shuffledDeck.pop(), shuffledDeck.pop()];
const dealerHand = [shuffledDeck.pop(), shuffledDeck.pop()];
const playerEmbed = new EmbedBuilder()
.setTitle('Blackjack')
.setDescription(`Your hand: ${playerHand.join(', ')}`)
.setColor('#FFA500')
.setTimestamp();
const dealerEmbed = new EmbedBuilder()
.setTitle('Blackjack')
.setDescription(`Dealer hand: ${dealerHand[0]}, *hidden*`)
.setColor('#FFA500')
.setTimestamp();
const playerMsg = await message.channel.send({ embeds: [playerEmbed] });
const dealerMsg = await message.channel.send({ embeds: [dealerEmbed] });
let playerScore = getHandValue(playerHand);
let dealerScore = getHandValue(dealerHand.slice(0, 1));
const hitButton = new ButtonBuilder()
.setCustomId('hit')
.setLabel('Hit')
.setStyle(ButtonStyle.Primary);
const standButton = new ButtonBuilder()
.setCustomId('stand')
.setLabel('Stand')
.setStyle(ButtonStyle.Primary);
const buttonRow = new ActionRowBuilder()
.addComponents(hitButton, standButton);
let ongoing = true;
while (ongoing) {
const hitOrStandEmbed = new EmbedBuilder()
.setTitle('Blackjack')
.setDescription('Do you want to hit or stand?')
.setColor('#FFA500')
.setTimestamp();
const hitOrStandMsg = await message.channel.send({ embeds: [hitOrStandEmbed], components: [buttonRow] });
const filter = i => i.user.id === message.author.id;
const collector = hitOrStandMsg.createMessageComponentCollector({ filter, time: 60000 });
collector.on('collect', async i => {
if (i.customId === 'hit') {
const newCard = shuffledDeck.pop();
playerHand.push(newCard);
playerScore = getHandValue(playerHand);
playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}`);
if (playerScore > 21) {
playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\nBust! Dealer wins.`);
playerEmbed.setColor('#FF0000');
await playerMsg.edit({ embeds: [playerEmbed] });
await hitOrStandMsg.delete();
ongoing = false;
collector.stop();
} else {
playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}`);
await playerMsg.edit({ embeds: [playerEmbed] });
await hitOrStandMsg.delete();
}
} else if (i.customId === 'stand') {
while (dealerScore < 17) {
const newCard = shuffledDeck.pop();
dealerHand.push(newCard);
dealerScore = getHandValue(dealerHand);
dealerEmbed.setDescription(`Dealer hand: ${dealerHand.join(', ')}`);
await dealerMsg.edit({ embeds: [dealerEmbed] });
}
dealerEmbed.setDescription(`Dealer hand: ${dealerHand.join(', ')}\nDealer score: ${dealerScore}`);
await dealerMsg.edit({ embeds: [dealerEmbed]
});
if (dealerScore > 21) {
playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\n Dealer hand: ${dealerHand.join(', ')}\nDealer score: ${dealerScore}\nDealer busts! You win!`);
playerEmbed.setColor('#00FF00');
await playerMsg.edit({ embeds: [playerEmbed] });
} else if (playerScore > dealerScore) { playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\nDealer hand: ${dealerHand.join(', ')}\nDealer score: ${dealerScore}\nYou win!`);
playerEmbed.setColor('#00FF00');
await playerMsg.edit({ embeds: [playerEmbed] });
} else if (dealerScore > playerScore) { playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\nDealer hand: ${dealerHand.join(', ')}\nDealer score: ${dealerScore}\nDealer wins!`);
playerEmbed.setColor('#FF0000'); await playerMsg.edit({ embeds: [playerEmbed] });
} else { playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\nDealer hand: ${dealerHand.join(', ')}\nDealer score: ${dealerScore}\nIt's a tie!`);
playerEmbed.setColor('#FFFF00');
await playerMsg.edit({ embeds: [playerEmbed] });
}
await hitOrStandMsg.delete();
collector.stop();
}
});
collector.on('end', async collected => {
if (collected.size === 0) {
await hitOrStandMsg.delete();
playerEmbed.setDescription(`Your hand: ${playerHand.join(', ')}\nYou took too long to make a decision. Game over.`);
playerEmbed.setColor('#FF0000');
await playerMsg.edit({ embeds: [playerEmbed] });
}
});
if (playerScore > 21 || dealerScore > 21) {
break;
}
}
}
module.exports = {
playBlackjack,
};
和执行文件:
const { SlashCommandBuilder, MessageCollector, Message, MessageContextMenuCommandInteraction } = require('discord.js');
const { playBlackjack } = require('../functions/playBlackjack');
module.exports = {
data: new SlashCommandBuilder()
.setName('blackjack')
.setDescription('Play a Game of Blackjack'),
async execute(interaction) {
playBlackjack(interaction);
}
}
任何帮助或提示将不胜感激!!
我在执行我的代码时遇到了这个错误:
节点:事件:491 扔呃; // 未处理的“错误”事件 ^
TypeError:无法读取未定义的属性(读取“id”) 在 InteractionCollector.filter (C:\Users\Sauce\Desktop\FrontierEconomyBot unctions\playBlackjack.js:55:42) 在 InteractionCollector.handleCollect (C:\Users\Sauce\Desktop\FrontierEconomyBot ode_modules\discord.js\src\structures\interfaces\Collector.js:110:39) 在 process.processTicksAndRejections (node:internal/process/task_queues:95:5) 在以下位置的客户端实例上发出“错误”事件: 在 emitUnhandledRejectionOrErr(节点:事件:394:10) 在 process.processTicksAndRejections (node:internal/process/task_queues:84:21)
第55行,filter declaration,这是报错的地方
在您的代码中,您将
interaction
传递给 playBlackjack
函数,并将其存储为 message
。 discord.js 交互中没有author
选项。如果要过滤交互作者,则必须将其替换为user
。
只要在第55行把代码改成下面这样
const filter = i => i.user.id === message.user.id;