0

在考虑制作网页游戏时,我遇到了一个令人不安的麻烦。许多游戏都有这样的“事件队列”。我有一支“军队”并将其发送给我的对手。我需要一些时间。当我的“军队”获得对手“军队”的位置时,就会计算出一场战斗,因此我的“军队”输了或赢了。当我或我的对手在比赛中时,一切都很好。某种 ajax 工作可以管理要调用的 php 脚本并计算战斗 - 然后将其结果保存到数据库。但是如果战斗发生时我和对手都没有登录,它怎么能工作呢?这种游戏的一个很好的例子是Ogame,当您将船只发送到另一个星球时,它可以在您注销时到达目的地,进行战斗,获取敌人的来源并卷土重来,

我一直认为我可以在数据库行中节省攻击者和他的对手的攻击时间,并在任何玩家登录游戏时计算战斗,但这种解决方案有很多缺点。例如,如果在我攻击我的对手之前有第三个玩家会攻击,这将改变他的军队统计数据(因为他可以杀死他的一部分军队)并且我有很多后果。此外,如果长时间没有玩家退出,他们就会出现在游戏中,因为他们没有在战斗,这不是真的。

你知道如何制作这样的事件队列吗?我想使用 cron 也不是一个好主意——它有时很少被使用,如果有成千上万的玩家,成千上万的 cron 实例可能会成为性能杀手。任何概念都将不胜感激-希望我能很好地描述我的问题:)

4

2 回答 2

1

在您的数据库中,创建一个“作业”表(无论您需要什么内容,加上一个 EXPIRE 日期 - 即作业完成的时间),并且每次用户创建作业(例如,将船只从一个集群移动到另一个集群),制作一个此表中的新条目,其中 EXPIRE 设置为船只到达目标集群的时间。

然后,每当任何人(!)加载任何站点(甚至是起始页)时,脚本都会检查队列中应该现在已经完成的作业。如果有任何 EXPIRE 低于 NOW 的作业,那么它会完成这项工作(或者,对于更大的作业,分叉一个 php cli 进程来完成这项工作)。

假设现在是2012-12-28 12:00,游戏有两个玩家A和B,其中A向B发起攻击需要6个小时。使用 EXPIRE=2012-12-28 18:00 和内容“Fleet foobar Attack B”创建作业。

案例 A:现在,A 退出,直到 19:00 才发生任何事情。B 登录,在其他任何事情发生之前(这对于确保“通知”或收件箱不会出现不同步很重要),脚本会看到工作在表中并且过期。该脚本执行作业并向 B 创建通知,通知他被来自 A 的庞大舰队淹没。作业完成,一切都很好(除了 B 的情绪)。

案例 B:A 退出。18:30,一位匿名用户访问了起始页。该脚本再次查看作业表并执行作业。B 在 19:00 登录并看到他丢失的通知。任务完成。

于 2012-12-30T03:25:50.377 回答
0

在我的项目中,无 CRON 事件队列背后的想法很简单:

  1. 所有事件都有“结束”时间。我正在使用原始 UNIX time() 时间戳来轻松进行比较操作。

  2. 当用户“点击”(打开任何游戏页面)时,队列引擎根据优先级获取所有“结束”<= 当前时间()的事件。在同一秒发生的事件从高优先级到低优先级执行。

  3. 如果游戏中没有用户 - 没有人需要事件。就这么简单:) 游戏会一直休眠,直到有人登录游戏并回滚事件队列,如第二步所述。

您可以在任何网站上添加相同的功能,这些网站具有定期事件和可观的每日网站流量。

(其实我也是按需求做了cron.php后端)

于 2013-11-12T08:19:56.570 回答