You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让函数在下一个时间间隔更新数值?(Discord.js场景)

实现战斗定时数值更新的方案

看起来你想要在battle命令里实现一个「每隔固定时间间隔更新数值」的功能,比如战斗过程中实时刷新玩家/怪物的血量、同步数据库状态。下面结合你的Discord.js Commando代码,给出具体的实现思路和完整代码:

核心实现思路

  • 用setInterval创建定时任务,每隔指定时间执行一次数值更新逻辑
  • 每次更新后同步修改数据库中的玩家/怪物数据
  • 通过编辑Discord消息实时反馈战斗状态(避免频繁刷屏)
  • 战斗结束后必须清除定时任务,防止内存泄漏

完整代码示例

/*jshint esversion: 6*/
const commando = require('discord.js-commando');
const db = require('../../config/db');

module.exports = class Battle extends commando.Command {
    constructor(client) {
        super(client, {
            name: 'battle',
            aliases: ['fight'],
            group: 'actions',
            memberName: 'battle',
            description: 'What mob to battle.',
            args: [
                {
                    key: 'mob',
                    prompt: 'What mob do you want to attack? Mob ID only!',
                    type: 'integer',
                },
            ],
        });
    }

    async run(message, { mob }) {
        try {
            // 1. 从数据库获取玩家和怪物的初始状态
            const [player] = await db.query('SELECT * FROM players WHERE user_id = ?', [message.author.id]);
            const [mobData] = await db.query('SELECT * FROM mobs WHERE id = ?', [mob]);

            if (!player || !mobData) {
                return message.reply(player ? 'Invalid mob ID!' : 'You need to create a character first!');
            }

            // 复制初始数值,避免直接修改数据库查询结果
            let currentPlayerHp = player.hp;
            let currentMobHp = mobData.hp;
            const attackInterval = 2000; // 每2秒触发一次攻击/数值更新

            // 2. 发送初始战斗消息,保存消息对象用于后续编辑
            let battleMessage = await message.reply(`
**Battle Started!**
You vs ${mobData.name}
Your HP: ${currentPlayerHp} | Mob HP: ${currentMobHp}
`);

            // 3. 创建定时更新任务
            const battleTimer = setInterval(async () => {
                // 战斗逻辑:玩家和怪物互相攻击,计算伤害
                const playerDamage = Math.floor(Math.random() * player.attack) + 1;
                const mobDamage = Math.floor(Math.random() * mobData.attack) + 1;

                currentMobHp -= playerDamage;
                currentPlayerHp -= mobDamage;

                // 4. 同步更新数据库中的玩家血量
                await db.query('UPDATE players SET hp = ? WHERE user_id = ?', [currentPlayerHp, message.author.id]);

                // 5. 检查战斗是否结束
                if (currentPlayerHp <= 0 || currentMobHp <= 0) {
                    clearInterval(battleTimer); // 必须清除定时任务,防止内存泄漏
                    const battleResult = currentPlayerHp <= 0 
                        ? 'You lost the battle! Better luck next time.' 
                        : `You defeated ${mobData.name}! Great job!`;
                    
                    return battleMessage.edit(`
**Battle Ended!**
${battleResult}
Final Stats: Your HP ${Math.max(currentPlayerHp, 0)} | Mob HP ${Math.max(currentMobHp, 0)}
`);
                }

                // 6. 更新战斗状态消息
                battleMessage.edit(`
**Battle in Progress!**
You vs ${mobData.name}
Your HP: ${currentPlayerHp} | Mob HP: ${currentMobHp}
You dealt ${playerDamage} damage! Mob dealt ${mobDamage} damage!
`);
            }, attackInterval);

        } catch (err) {
            console.error('Battle command error:', err);
            message.reply('An error occurred during the battle. Please try again later.');
        }
    }
};

关键注意事项

  • 定时任务清理:战斗结束(玩家/怪物血量归0)时一定要调用clearInterval,否则定时任务会一直后台运行,导致内存泄漏
  • 异步操作处理:所有数据库查询都要用await,确保数据同步更新后再执行下一步逻辑
  • 消息编辑限制:Discord对消息编辑有频率限制,建议间隔至少1秒以上,避免被平台限制
  • 数值安全处理:更新血量时可以用Math.max()确保数值不会显示为负数,提升用户体验
  • 异常捕获:用try/catch包裹整个逻辑,避免单个战斗出错导致整个命令崩溃

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:29:34