一款帧同步游戏代码设计思路

前言:从4月份至5月份学习了一下unity   目的:为了能够看懂客户端代码最好能够自己写一份属于自己的游戏。

第一次写这类型的代码 也是第一次用unity引擎  写游戏 目前完成了 服务器的设计  当前坦克大战的移动(还存在玩家位置不对的问题)

一张简单的图片概括了 设计思路 

 

 简单概括一下  就是客户端做出行为操作  不直接修改行为 而是等待服务器的返回  在updata 脚本里 展示出来

服务器这边代码设计:

一旦有两个 以上的玩家那么就开始分配房间   这一块位置使用的是协程创建协程 分配房间 

 public Void run() throws SuspendExecution, InterruptedException {
        Logger.MLOG.info("#######room:[" + roomId + "]tick start########");
        do {
            moves.swap();
            Queue<PersonMove.CSPlayerMove> dealQueue = moves.first();
            while (!dealQueue.isEmpty()) {
                PersonMove.CSPlayerMove msg = dealQueue.poll();
                if (null == msg) {
                    break;
                }
                sc.setPlayerId(msg.getPlayerId());
                sc.setMove(msg.getMove());
                long sTime = System.currentTimeMillis(); //服务器的时间
                sc.getMove().toBuilder().setStime(sTime);
                byte[] bytes = sc.build().toByteArray();
                Protocal protocal = new Protocal(SCUDP, bytes.length, 0, bytes);
                for (Player player : this.players) {
                    protocal.setPid(player.getPlayerId());
                    Global.serverChannel.writeAndFlush(protocal);
                }
                Logger.MLOG.info("msg" + msg + "发送成功");
            }

            Strand.sleep(40);
        } while (true);
    }

对于每个client 不停的进行广播  (其实可以进行优化 可以节省一些网络带宽资源 ) 

帧同步设计思路:

对于打过那种 Xbox 机顶盒的人来说  可以理解手柄 和 显示器是 客户端 

机顶盒是服务器  手柄接收到多个玩家操作 然后消息发送至机顶盒 然后再同步到屏幕

 

客户端的设计:

结构设计

结构分析 GameBegain 是入口函数

CallBack 是处理消息的回调

net层处理消息接收

player 层处理tank 数据

ui 层处理 ui 的消息

 

创建一个空对象:
挂上脚本GameBegain里初始化 MainManager 在awake 方法里初始化

 private void Awake()
    {
        MainManager mainManager =MainManager.Instance;
        MainManager.Instance.State = (int)State.begain;
        mainManager.UiMananger=new UIMananger();
        mainManager.NetManager=new NetManager("192.168.1.9",12306,"192.168.1.9",12310);
        mainManager.PlayerManager=new PlayerManager(new Dictionary<long, Player>());
        mainManager.CallBack =new CallBack();
        
    }

创建一个消息队列 放入Tank 的脚本里

当玩家有消息就会往消息队列里存放数据  玩家每次操作的代码

 void Update()
    {
        //调用方法
        long playerId = MainManager.Instance.PlayerManager.PlayerId;
        float horizontal = Input.GetAxisRaw("Horizontal" + id);
        float vertical = Input.GetAxisRaw("Vertical" + id);

        if (id == playerId)
        {
            CSPlayerMove csPlayerMove = new CSPlayerMove();
            csPlayerMove.PlayerId = id;
            csPlayerMove.Move = new MoveInfo();
            csPlayerMove.Move.Ctime = 0;
            csPlayerMove.Move.Dir = vertical;
            csPlayerMove.Move.Spinning = horizontal;
            csPlayerMove.Move.Fire = "";
            csPlayerMove.Move.Stime = 0;
            byte[] bytes = csPlayerMove.ToByteArray();
            Protocol protocol = new Protocol((int) CodeNet.CSPlayerMove, bytes.Length, playerId, bytes);
            MainManager.Instance.NetManager.UdpManager.write(protocol);
        }

        //占时效果的代码
        int i = 0;
        while (!_SCPlayerQueue.IsEmpty)
        {
            SCPlayerMove playerMove;
            _SCPlayerQueue.TryDequeue(out playerMove);
            long playerid = playerMove.PlayerId;
            float horizontalc = playerMove.Move.Spinning;
            float verticalc = playerMove.Move.Spinning;
            if (playerid == id)
            {
                rig.velocity = transform.forward * verticalc * speed;
                if (verticalc > 0)
                    rig.angularVelocity = transform.up * horizontalc * speed;
                else
                    rig.angularVelocity = transform.up * -horizontalc * speed;
            }
            //最多一次处理20次消息
            if (i == 20) {
                Debug.Log("当前服务器消息过多");
                break;
            }
            i++;
        }


        //Debug.Log(t);
        //TanksMove();
        //TanksAttack();
    }

 

当前问题 可能由于时间的问题或者分辨率的问题导致 数据有微弱的不同步? 

解决方法待定

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值