“灵剑出鞘”小游戏开发日志(10)---- 与服务端交互,获取奖励资源

背景

前面我们已经实现了游戏的胜利和失败,并做了游戏结束后的资源释放。接下来就是与服务端交互,记录玩家的资源,给与玩家资源,留住玩家,让他对游戏有占有感。先简单实现金币的奖励。

目标

记录玩家资源(金币),胜利后奖励玩家资源(金币)

开发过程

目前设定的有三种资源

体力(ps): 上限共3点,每小时回复一点

金币(gold): 可购买基础资源

钻石(diamond): 可购买高级资源

1、登录页,登录成功后,显示资源数据

2、结算页,获得奖励,显示更新后的资源

1、登录页,登录成功后,显示资源数据

这里主要是vm的视图与数据的双向绑定,原先oops是有一个vm的组件来做的,我就试着问gpt.

js如何监听一个Object内的一个属性变化

gpt回答

你可以使用ES6中引入的 Proxy 对象来监听一个Object内的一个属性变化。以下是一个示例代码:

const object = { 
  a: 1, 
  b: 2 
};

const handler = { 
  set(obj, prop, value) { 
    console.log(`${prop} 的值由 ${obj[prop]} 变为 ${value}`); 
    obj[prop] = value; 
  } 
};

const proxy = new Proxy(object, handler);

proxy.a = 3;

上面的代码中,我们创建了一个名为"object"的对象和一个名为"handler"的处理器。之后,我们使用Proxy对象来包装object对象,并将handler作为参数传入,并将结果存储在一个名为"proxy"的变量中。handler中的set方法会在object中的属性被设置时被调用,并输出相关的日志信息。在示例中,我们监测了a属性的变化,并将其从1改为3。

需要注意的是,美观打印对象中的属性变化需要借助一些控制台输出格式化的工具库,例如 prettyprint 或者 json-stringify-pretty-compact等等。

 好的,结合gpt,我们就做一个简单的vm数据监听

我在GateViewComp组件中加了一个初始化监听

            GateViewSystem.onVMPlayerInfo(this, () => {
                let playerInfo = ooxh.game.playerEntity.getComponent(PlayerStateComp).playerInfo
                this.vmPlayerInfo.gold = playerInfo.gold
                this.vmPlayerInfo.diamond = playerInfo.diamond
                this.vmPlayerInfo.ps = playerInfo.ps
                this.vmPlayerInfo.last_battle_id = playerInfo.last_battle_id
            })

实现

    static onVMPlayerInfo(comp: GateViewComp, callback) {
        const playerInfo = ooxh.game.playerEntity.getComponent(PlayerStateComp).playerInfo
        if (!playerInfo) {
            setTimeout(() => {
                this.onVMPlayerInfo(comp, callback)
            }, 200)
            return
        }
        const handler = {
            set(obj, prop, value) {
                console.log(`${prop} 的值由 ${obj[prop]} 变为 ${value}`);
                if (prop == 'ps') {
                    comp.node.getChildByName('top').getChildByName('value').getComponent(Label).string = value + '/3'
                }
                if (prop == 'gold') {
                    comp.node.getChildByName('top').getChildByName('gold').getChildByName('value').getComponent(Label).string = value
                }
                if (prop == 'diamond') {
                    comp.node.getChildByName('top').getChildByName('diamond').getChildByName('value').getComponent(Label).string = value
                }
                if (prop == 'last_battle_id') {
                    comp.node.getChildByName('bottom').getChildByName('curBattleIdText').getComponent(Label).string = '当前第' + value + '关'
                }
                obj[prop] = value;
                return true
            }
        };
        comp.vmPlayerInfo = new Proxy(playerInfo, handler);
        callback && callback()
    }

上面因为PlayerStateComp内的数据获取不确定什么时候完成做了简单循环检测

这样我只要在任何地方改变ooxh.game.playerEntity.getComponent(PlayerStateComp).playerInfo内的值,页面就会自动去更新ui

2、结算页,获得奖励,显示更新后的资源

向后端发起请求后,将获得的奖励数据,追加到用户数据中

    public function overBattle($param, $tokenUser)
    {
        $log = $this->dao->get(['id' => $param['battleLogId']]);
        if (!$log) {
            return ['status' => 0, 'msg' => '错误的战役记录id'];
        }
        if ($log['fans_id'] != $tokenUser['id']) {
            return ['status' => 0, 'msg' => '不能结束别人的战役' . $log['fans_id'] . '.' . $tokenUser['id']];
        }
        if ($log['over_datetime']) {
            return ['status' => 0, 'msg' => '已结束的战役'];
        }
        $battle = Db::name('jianchuqiao_battle_online')->where('battle_id', '=', $log['battle_id'])->find();

        try {
            $save['gold'] = $battle['gold'];
            if ($log['is_frist']) {
                $save['diamond'] = $battle['diamond'];
            } else {
                $save['diamond'] = 0;
            }
            $save['over_datetime'] = Date('Y-m-d H:i:s');
            $log->save($save);
            // 玩家战役向后一个
            $fans = app()->make(FansDao::class)->get(['id' => $tokenUser['id']]);

            $update['gold'] = $fans['gold'] + $save['gold'];
            $update['diamond'] = $fans['diamond'] + $save['diamond'];
            $update['last_battle_id'] = $log['battle_id'] + 1;
            $fans->save($update);

            return ['status' => 1, 'msg' => 'ok', 'data' => $log];
        } catch (\Exception $e) {
            Log::error('createBattleLog error' . $e->getMessage());
            return ['status' => 0, 'msg' => '失败-' . $e->getMessage()];
        }
    }

前端 

                    // 记录
                    HttpUtil.Post('/appletapi/jianchuqiao/overBattle',
                        {
                            battleLogId: ooxh.game.playerEntity.getComponent(PlayerStateComp).battleLogId
                        },
                        (res) => {
                            if (res.code == 200) {
                                // 显示胜利结算页面
                                ooxh.game.battleEntity.attachComponent(BattleWinViewComp).callback = () => {
                                    const playerInfo = ooxh.game.playerEntity.getComponent(PlayerStateComp).playerInfo
                                    playerInfo.ps += res.data.ps
                                    playerInfo.gold += res.data.gold
                                    playerInfo.diamond += res.data.diamond
                                };
                            } else {
                                // 暂不处理
                            }
                        })

测试显示

胜利后,返回首页,数据自动改为了新值

 下一个开发计划

激励广告后的额外奖励

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值