游戏中实时更新数据的实现方式

来源:互联网 发布:大数据精准营销公司 编辑:程序博客网 时间:2024/05/22 02:13

在游戏中,玩家的信息会实时变动,我们需要把改变后的信息在页面中体现出来。

需求:航海游戏中,玩家出航,从港口A到港口B,目前他处于的A港口位于地中海,港口B处于太平洋,在未到B港口时,他所处的海域发生了变化,在太平洋海域。 需要在页面中实时展现玩家所处于的海域。

为了满足以上需求,需要做到2点:

1,在数据库层面上,出航的时候,更新玩家所处于的海域

2,在展现层面上,需要把玩家改变的信息显示在页面上。

问题:

QA: 玩家信息如何实时更新

ans:  玩家在航海的过程中,他的相关的数据会被修改。

QB  页面如何知道玩家的信息

ans: 页面中实现一个AJAX函数,这个函数每5秒中请求服务器,并获取玩家最新的相关数据, 如果有多个页面都涉及到实时展现玩家最新信息,建议把这个AJAX函数写在一个公共页面中,如footer,并每次都自动执行。这样,避免了在很多页面中,都写这个AJAX函数

QC: 最新的玩家信息如何被展现到页面中

ans: 页面需要重新渲染数据,一般都是刷新页面,重新给页面分配,还有一种做法就是使用JS函数,操作页面的dome结构。我们已经获取到了玩家的信息,如何把这个信息展现到页面中呢,我们使用JS函数,获取的信息作为他的参数,把获取到的信息,重新分配到页面。

这里就要求:服务器除了把玩家的信息返回给我之外,还有注册一个JS函数,并通知页面执行一个特定的JS函数 !!!!!!!!!!!! 如果要执行这个JS函数,需要调用这个函数,如果在页面刷新的前提下 我们使用:

$(function () {    specaiJsFunction(data)})

这样可以保证specailJsFunction()这个函数可以被自动执行。但是,我们的请求是AJAX,页面不会刷新,所以,这样的做法行不通。我们可以在ajax请求的回调函数里面执行这个函数,所以要求这个函数必须是AJAX函数的返回值,否则程序不知道调用那个函数!!!!!


实现流程图:



实现具体过程:

客户端 页面发起AJAX请求:

// 更新页面中的“当前海域”信息if (<?=$user.isSailing?>) {    $(function () {        setInterval(function () {            $._getJSON('/ajax/polling', null, function (resp) {                // 处理AJAX响应中的iTips                iTipsInAjaxResponse(resp)            });        }, 5000);    });}


服务器端:更新玩家的信息是在航海的这个函数中,这里,我只需要读取玩家的信息,并注册JS函数:

    public function pollingAction()    {        // 检测玩家是否处于航海状态        if (! $this->_user->isStaying()) {            // 获取玩家的最新信息            $userInfo = array(                // 输出玩家当前所在海域                'seaAreaId'     => $this->_user['sea_area_id'],                'seaAreaName'   => $this->_user['seaArea']['name'],            );            // 注册一个JS函数:updateSeaAreaName,并把玩家的信息当为函数的参数            $this->_user->tips->setTips('updateSeaAreaName', $userInfo);        }
// 在这个函数内,把所有注册的JS函数使用JSON的方式,返回给页面中AJAX的请求。        $this->jsonx('OK');    }

tips类的实现方式:

<?php/** * 我的实时提示框 * */class Model_User_Tips extends Model_User_Trait{    private $_tips = array();    /**     * 是否立即弹出     *     * @var bool     */    private $_autoPopUp = true;    /**     * 设置iTips     *     * @param string $jsFunc     * @param mixed $jsParam     * @param int $priority 优先级     * @return $this     */    public function setTips($jsFunc, $jsParam = null, $priority = 0)    {        $this->_tips[] = array(            'jsFunc'    => $jsFunc,            'jsParam'   => $jsParam,            'autoPopUp' => $this->_autoPopUp,            'priority'  => $priority,        );        return $this;    }    public function getTips()    {        return $this->_tips;    }    public function getJsonTips()    {        return $this->_tips ? json_encode($this->_tips) : 0;    }    /**     * 设置是否立即弹出,否则手动弹出     *     * @param int $bool     * @return $this     */    public function setAutoPopUp($bool)    {        $this->_autoPopUp = (bool) $bool;        return $this;    }}

jonsx的实现方式:

    /**     * 用于 AJAX 响应输出 JSON     *     * @param string $msg     * @param string $resultType success|error|warnings|tips     * @param array $extra     * @param bool $obClean 是否先清除之前的缓冲区     */    public function jsonx($msg, $resultType = 'success', array $extra = array(), $obClean = false)    {        // 实时提示框信息,如果有JS函数被注册则把注册的JS函数作为返回值返回给页面        if ($this->_user && $iTips = $this->_user->tips->getTips()) {            $extra['iTips'] = $iTips;        }        // 清除之前的缓冲区,防止多余输出        $obClean && ob_clean();        header('Content-type: text/json');        header('Content-type: application/json; charset=UTF-8');        exit(json_encode(array('msg' => $msg, 'status' => $resultType, 'extra' => $extra)));    }


在JS函数中,函数 function iTipsInAjaxResponse (resp){} 专门用于处于返回的JS函数数组 实现方式为:

// 处理AJAX响应中的iTipsfunction iTipsInAjaxResponse(resp){    // 处理 iTips 实时提示框    // 例如经验值、等级提升等提示    if (resp.extra && resp.extra.iTips) {        var iTipsInstant = iTips.filter(resp.extra.iTips, 'autoPopUp', true);        if (iTipsInstant.length > 0) {            // 立即弹出实时提示框            iTips.popUp(iTipsInstant);        }    }}


实时弹出框的实现方式:

// 实时提示框var iTips = {    filter : function (iTips, fieldName, fieldValue)    {        var result = [];        if (! iTips || iTips.length < 0) {            return result;        }        for (i in iTips) {            if (iTips[i][fieldName] == fieldValue) {                if (iTips[i]['priority'] == undefined) {                    iTips[i]['priority'] = 0;                }
// 需要自动执行的JS函数                result.push(iTips[i]);            }        }        // 按弹窗优先级升序排(优先级数字越小越前面,默认0表示最高级)        result.sort(function (x, y) {            return x.priority - y.priority;        });        return result;    },
// 过滤到不需要执行的函数    remove : function (iTips, fieldName, fieldValue)    {        var result = [];        if (! iTips || iTips.length < 0) {            return result;        }        for (i in iTips) {            if (iTips[i][fieldName] != fieldValue) {                result.push(iTips[i]);            }        }        return result;    },    popUp : function (iTips)    {        if (! iTips || iTips.length < 0) {            return false;        }        for (i in iTips) {            if (iTips[i]) {
// 转化成执行的JS函数,并执行                eval('var jsFunc = ' + iTips[i]['jsFunc'] + ';');                jsFunc(iTips[i]['jsParam']);            }        }    }};


在服务器注册JS函数,在页面中执行,这样的做法,还有一个用处就是实时弹框,例如,玩家升级的时候,需要弹框提示玩家升级,但是这个提示升级框JS函数,不确定在这个页面中,那个时候会被调用执行到。所以,不能把这个JS“写死”在某个页面中。

如果采用我的方法,就可以动态的调用某个JS函数并执行,不受页面的时间的限制。


这种实现方式,类似于观察者。


原创粉丝点击