网站设计:如何用成就奖励用户任务?

3
我想在我的网站上设置一个成就系统。人们完成任务并上传信息,这些信息将存储在数据库中(例如“时间”,“日期”,“任务”等)。最好的检查他们信息和授予成就的方法是什么?我是否只需要像achievement.php一样,一旦上传了信息,它就会触发此文档运行所有检查以确定是否需要授予用户成就?还是我应该设置服务器端来奖励用户?
感谢任何帮助或建议,评论等:D
编辑:我目前在数据库中列出了成就(id,名称,类)。
任务被存储为('date_time','time','device','user_id [fk]')
编辑2:许多成就将根据用户当前提交的任务以及考虑到以前的任务而计算。例如:如果用户在连续3天内完成了3个任务,则将为其授予成就。
3个回答

2

您最好的选择可能是创建一个任务点值表,然后创建一个存储过程,可以从适当的表中获取适当的计数,并将它们乘以点值。这就是我过去所做的-它允许您从数据库中随时修改点值。


2
在数据库中使用存储过程?我强烈建议不要这样做。 - dynamic
任务并没有真正的点值,它们只是根据稀有度分为3个不同的类别。我打算设置一个PHP文件,根据用户完成的最新任务执行一系列条件。很多奖励都是基于数据积累的。(例如:人在5天内完成5个任务,或者1天内完成5个任务等等)然而,这种在用户上传任务后执行这些条件的方法似乎并不是最优解决方案。 - daveomcd
那么,废弃 pointValue 表格,手动计算稀有度? - Dutchie432

1
你可以在任务提交过程中创建一个触发器(或者无论用户何时完成任务时插入数据的方式),然后执行必要的操作来确定该用户是否获得成就,并相应地更新成就表。这样,每次在前端加载用户信息时,他/她的数据将已经存在于成就表中,你可以直接访问它(我相信你已经这样做了)。

1

这真的取决于您在业务逻辑放置方面的偏好以及您希望成就达到多实时。如果您想要将大量业务逻辑卸载到 SQL 服务器上,请将其放在存储过程中,否则,请将计算类分离到 PHP 类中,并使用该类确定新成就。

我肯定建议在正常页面响应之外进行处理。也许启动一个服务器端调用 PHP cli,或设置一个 cron 作业以在某个间隔内运行所有个人检查成就。

编辑:

至于授予成就的实际方法,我认为您最灵活且简单的实现(我相信您会找到更简单/不太灵活和更灵活/不太简单的选项)是创建一个 AwardRunner 类、一个 IAward 接口以及每个奖项都有一堆独立的 IAward 实现。基本思想是:

<?php
    class AwardRunner {
        var $UserId = 0;

        function AwardRunner($userId) {
            $this->UserId = $userId;

            $dir = "/path/to/your/folder/full/of/IAwards/";
            $includes = read_dir($dir);

            //include all files that exist
            foreach($includes as $include)
            {
                if (is_file($include))
                {
                  require($include);
                }
            }
        }

        public function Run() {
            $classList = get_declared_classes();

            foreach($classList as $key => $className)
            {
                if (in_array('IAward', class_implements($className))) {
                    $award = $className();
                    $award->UserId = $this->UserId; 
                    $award->GrantIfUserQualifies();
                }
            }

        }

        //function for reading all files in a directory.
        //this is recursive, so any files in subfolders will also make it in
        function read_dir($dir) 
        {
            $array = array();
            $d = dir($dir); 
            while (false !== ($entry = $d->read())) {
                if($entry!='.' && $entry!='..') {
                    $entry = $dir.'/'.$entry;
                    if(is_dir($entry)) {
                        $array = array_merge($array, read_dir($entry));
                    } else {
                        $array[] = $entry;
                    }
                }
            }
            $d->close();
            return $array;
        }   
}
?>

我认为从使用情况来看,IAward接口的外观应该是相当清晰的,尽管您可能会添加来自表格的Id字段,以便它能够插入数据库,以及调用AwardRunner类的方式。

无论您是否有批处理奖项流程循环遍历所有用户,或者只是在每次任务提交后启动它,这个想法都应该可行。


在服务器上运行成就检查,独立于用户的体验,对我来说似乎是最好的解决方案。我只是不确定如何让它检查成就以授予奖励。现在,我有一个页面,其中包含一堆成就条件。然而,出于各种原因,这似乎不是最佳解决方案。有什么想法吗? - daveomcd
1
@daveomcd,请查看修订后的答案。 - nathan gonzalez
非常感谢,我觉得在这方面我还是一个完全的新手,但我相信我能够理解你上面所做的一切。我以前从未考虑过用这种方式来做,至少目前看来这是一种非常棒的设置方式!:) 感谢你的所有帮助,现在我要开始设置它了! - daveomcd
1
@daveomcd,没问题。我最近在C#中做了类似的事情,所以我只需要让它在PHP中有意义即可。真正好的是,要添加新奖项,您只需将文件放入文件夹中,下一批处理过程就会捡起并应用它。 - nathan gonzalez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接