Discord.js RPG机器人反应检测问题求助:表情不全+单次检测
解决Discord.js RPG机器人的两个问题:表情添加不全与单次反应检测
我来帮你排查这两个问题,先拆解代码里的关键错误:
问题1:仅添加1个表情而非设定的4个
你当前用链式调用.then()来依次添加表情,这种方式的问题是:如果某一步的react()操作因为网络延迟或API限制失败,后续的表情就不会被添加。更可靠的方式是用Promise.all()并行处理所有表情的添加请求,这样即使某个请求出现小问题,其他表情仍能正常添加。
问题2:仅能检测一次用户反应,且后续逻辑不触发
这里有两个核心错误:
- 你用了
awaitReactions(),它本身就是一次性的反应收集器,只会收集到第一次符合条件的反应就停止;如果需要支持多次反应,应该改用createReactionCollector()。 - 反应判断逻辑完全错误:你写的
Discord.MessageReaction.emoji是调用类本身的属性,而不是当前触发的反应实例的表情。正确的做法是使用reaction.emoji.name来匹配表情。
修正后的代码片段
if (message.channel.name === "rpg") { let HP = 0; let atk = 0; let def = 0; // 如果你不需要给用户的原始消息加表情,可以删掉下面这行 const emoji = message.guild.emojis.cache.find(emoji => emoji.name === 'SurvivalManos'); message.react(emoji); const random = Math.ceil(Math.random() * 3); // 简化随机数生成,直接得到1-3的整数 const rpgembed = new Discord.MessageEmbed() .setColor('#ffd15e') .setTitle('RPG') .setThumbnail('https://cdn.discordapp.com/attachments/732552438283894824/733256439602086019/New_Project_3.png') .setTimestamp() .setFooter('Feito por R0dr1G02M4R5 com <3; Desenhos de Kunyk'); if (random === 1) { HP = 50; atk = 10; def = 5; rpgembed.setDescription('Um slime verde selvagem apareceu!') .setImage('https://media.discordapp.net/attachments/696805791319064618/733967904890159134/SPOILER_New_Piskel.png?width=585&height=585') .addFields( { name: 'HP', value: HP, inline: true }, { name: 'Atk', value: atk, inline: true }, { name: 'Def', value: def, inline: true } ); } else if (random === 2) { HP = 100; atk = 5; def = 10; rpgembed.setDescription('Um slime vermelho selvagem apareceu!') .setImage('https://media.discordapp.net/attachments/696805791319064618/733968480390610955/SPOILER_New_Piskel_1.png?width=585&height=585') .addFields( { name: 'HP', value: HP, inline: true }, { name: 'Atk', value: atk, inline: true }, { name: 'Def', value: def, inline: true } ); } else if (random === 3) { HP = 25; atk = 10; def = 10; rpgembed.setDescription('Um feiticeiro fantasma selvagem apareceu!') .setImage('https://media.discordapp.net/attachments/696805791319064618/733968482122727494/SPOILER_New_Piskel_2.png?width=585&height=585') .addFields( { name: 'HP', value: HP, inline: true }, { name: 'Atk', value: atk, inline: true }, { name: 'Def', value: def, inline: true } ); } message.channel.send(rpgembed).then(async function(botMessage) { // 用Promise.all并行添加所有表情,确保四个表情都能加载 await Promise.all([ botMessage.react('⚔'), botMessage.react('🛡'), botMessage.react('🍖'), botMessage.react('🏃') ]); const filter = (reaction, user) => { return ['⚔', '🛡', '🍖', '🏃'].includes(reaction.emoji.name) && user.id === message.author.id; }; // 改用createReactionCollector支持多次反应收集 const collector = botMessage.createReactionCollector({ filter, time: 60000 }); collector.on('collect', (reaction, user) => { console.log('he logs'); switch(reaction.emoji.name) { case '⚔': botMessage.channel.send("He atacs"); console.log("He ataks"); // 如果需要保留多次攻击,不要设置act=false,否则根据你的逻辑调整 break; case '🛡': botMessage.channel.send("He defens"); console.log("He defens"); break; case '🍖': botMessage.channel.send("He itz"); console.log("He itz"); break; case '🏃': botMessage.channel.send("He rans"); console.log("He rans"); collector.stop(); // 逃跑后停止收集反应 break; } }); collector.on('end', collected => { console.log(`收集到了 ${collected.size} 次反应`); // 可以在这里添加超时或结束后的提示,比如"回合结束!" }); }); }
额外优化说明
- 我把回调里的
message变量改成了botMessage,避免和外层的用户消息变量重名,减少混淆。 - 简化了随机数生成逻辑,去掉了冗余的计算。
- 把重复声明的
const HP/atk/def改成let,避免变量作用域冲突。 - 用
switch语句替代冗长的if-else,让逻辑更清晰易读。
内容的提问来源于stack exchange,提问作者user12657757
相关产品推荐
相关产品推荐

