示例#1
0
        private void UpdateMultiFrame()
        {
            Singleton <GameLogic> .GetInstance().UpdateTails();

            // 预测本次更新value次
            int value = (int)((this.EndFrameNum - this.CurFrameNum) / (uint)this.nDriftFactor);

            // 本次尝试更新次数
            this.tryCount = Mathf.Clamp(value, 1, 100);
            int i = this.tryCount;
            // 客户端游戏开始到现在的时间长度
            long clientTime = (long)((double)(Time.realtimeSinceStartup - this.startFrameTime) * 1000.0);
            // 客户端与服务器的时差
            long nDelayMs = clientTime - (long)((ulong)((this.SvrFrameIndex + 1u) * this.SvrFrameDelta));

            // 本次平均网络延时
            this.nJitterDelay = this.CalculateJitterDelay(nDelayMs);
            clientTime       *= (long)this.frameSpeed;
            int num2 = 0;

            while (i > 0)
            {
                long num3 = (long)((ulong)this.CurFrameNum * (ulong)this.FrameDelta);
                this.nMultiFrameDelta  = clientTime - num3;
                this.nMultiFrameDelta -= (long)this.nJitterDelay;
                if (this.nMultiFrameDelta < (long)((ulong)this.FrameDelta))
                {
                    break;
                }
                if (this.CurFrameNum >= this.EndFrameNum)
                {
                    this.EndBlockWaitNum     += 1u;
                    this.m_maxEndBlockWaitNum = Mathf.Max(this.m_maxEndBlockWaitNum, (int)this.EndBlockWaitNum);
                    break;
                }
                this.EndBlockWaitNum = 0u;
                this.CurFrameNum    += 1u;
                num2++;
                this.LogicFrameTick += (ulong)this.FrameDelta;
                this.isCmdExecuting  = true;
                while (this.commandQueue.get_Count() > 0)
                {
                    IFrameCommand frameCommand = this.commandQueue.Peek();
                    uint          num4         = (frameCommand.frameNum + this.SvrFrameLater) * this.KeyFrameRate;
                    if (num4 > this.CurFrameNum)
                    {
                        break;
                    }
                    frameCommand.frameNum = num4;
                    frameCommand          = this.commandQueue.Dequeue();
                    frameCommand.ExecCommand();
                }
                this.isCmdExecuting = false;
                Singleton <GameLogic> .GetInstance().UpdateLogic((int)this.FrameDelta, i == 1 && this.nMultiFrameDelta < (long)(2uL * (ulong)this.FrameDelta));

                i--;
            }
            this.m_maxExcuteFrameOnce = Mathf.Max(this.m_maxExcuteFrameOnce, num2);
        }
示例#2
0
        private void UpdateMultiFrame()
        {
            Singleton <GameLogic> .GetInstance().UpdateTails();

            int value = (int)((this.EndFrameNum - this.CurFrameNum) / (uint)this.nDriftFactor);

            this.tryCount = Mathf.Clamp(value, 1, 100);
            int   i = this.tryCount;
            float realtimeSinceStartup = Time.realtimeSinceStartup;
            long  num      = (long)((double)(realtimeSinceStartup - this.startFrameTime) * 1000.0);
            long  nDelayMs = num - (long)((ulong)((this.SvrFrameIndex + 1u) * this.SvrFrameDelta));

            this.nJitterDelay = this.CalculateJitterDelay(nDelayMs);
            num *= (long)this.frameSpeed;
            while (i > 0)
            {
                long num2 = (long)((ulong)this.CurFrameNum * (ulong)this.FrameDelta);
                this.nMultiFrameDelta  = num - num2;
                this.nMultiFrameDelta -= (long)this.nJitterDelay;
                if (this.nMultiFrameDelta >= (long)((ulong)this.FrameDelta))
                {
                    if (this.CurFrameNum >= this.EndFrameNum)
                    {
                        this.EndBlockWaitNum += 1u;
                        i = 0;
                    }
                    else
                    {
                        this.EndBlockWaitNum = 0u;
                        this.CurFrameNum    += 1u;
                        this.LogicFrameTick += (ulong)this.FrameDelta;
                        this.isCmdExecuting  = true;
                        while (this.commandQueue.get_Count() > 0)
                        {
                            IFrameCommand frameCommand = this.commandQueue.Peek();
                            uint          num3         = (frameCommand.frameNum + this.SvrFrameLater) * this.KeyFrameRate;
                            if (num3 > this.CurFrameNum)
                            {
                                break;
                            }
                            frameCommand.frameNum = num3;
                            frameCommand          = this.commandQueue.Dequeue();
                            frameCommand.ExecCommand();
                        }
                        this.isCmdExecuting = false;
                        Singleton <GameLogic> .GetInstance().UpdateLogic((int)this.FrameDelta, i == 1 && this.nMultiFrameDelta < (long)(2uL * (ulong)this.FrameDelta));

                        i--;
                    }
                }
                else
                {
                    i = 0;
                }
            }
        }
示例#3
0
        private void UpdateSingleFrame()
        {
            Singleton <GameLogic> .GetInstance().UpdateTails();

            long num = (long)(Time.deltaTime * 1000f);

            num = (long)Mathf.Clamp((int)num, 0, 100);
            this.CurFrameNum    += 1u;
            this.LogicFrameTick += (ulong)num;
            this.isCmdExecuting  = true;
            while (this.commandQueue.get_Count() > 0)
            {
                IFrameCommand frameCommand = this.commandQueue.Dequeue();
                frameCommand.ExecCommand();
            }
            this.isCmdExecuting = false;
            if (num > 0L)
            {
                Singleton <GameLogic> .GetInstance().UpdateLogic((int)num, false);
            }
        }
示例#4
0
        /// <summary>
        /// 该方法每个渲染帧会执行一次,但是会以逻辑帧间隔,经过平均延迟计算,触发逻辑帧的执行
        /// </summary>
        /// <param name="bLocalTimeDriver"></param>
        private void UpdateMultiFrame(bool bLocalTimeDriver = false)
        {
            {
                MEObjDeliver e = ObjectCachePool.instance.Fetch <MEObjDeliver>();
                e.opcode = (int)EObjDeliverOPCode.E_OP_UPDATE_TAILS_OF_GAME_LOGIC;
                Mercury.instance.Broadcast(EventTokenTable.et_framesynchr, this, e);
            }

            int drift = (int)((EndFrameNum - CurFrameNum) / (uint)nDriftFactor);

            tryCount = Mathf.Clamp(drift, 1, 100);
            int   i  = tryCount;
            float rt = Time.realtimeSinceStartup;

            if (bLocalTimeDriver)
            {
                rt = fLocalRunTime + startFrameTime;
            }

            //帧同步开始后经过了多少时间。nowtime 是渲染帧间隔,小于一个逻辑帧
            long nowTime = (long)((rt - startFrameTime) * 1000f);

            long nDelayMs = nowTime - (long)((SvrFrameIndex + 1u) * SvrFrameDelta);
            //平均延迟(以30帧计算)
            int smoothDelay = CalculateJitterDelay(nDelayMs);

            nowTime *= (long)frameSpeed;
            while (i > 0)
            {
                long lastTime  = (long)(CurFrameNum * FrameDelta);
                long deltaTime = nowTime - lastTime;
                deltaTime -= (long)smoothDelay;
                //这里是处理核心,如果 deltaTime 随着渲染帧的增长而增长,当他小于一个逻辑帧时,则不做任何处理,当他大于一个逻辑帧时,则触发一次逻辑帧处理
                if (deltaTime >= (long)FrameDelta)
                {
                    //假设一直没有收到新的逻辑帧,则每次都会执行到这里
                    if (CurFrameNum >= EndFrameNum)
                    {
                        EndBlockWaitNum += 1u;
                        i = 0;
                    }
                    else
                    {
                        EndBlockWaitNum = 0u;
                        CurFrameNum    += 1u;
                        LogicFrameTick += (ulong)FrameDelta;

                        //先执行命令,再刷新游戏逻辑
                        while (commandQueue.Count > 0)
                        {
                            IFrameCommand frameCommand = commandQueue.Peek();
                            uint          commandFrame = (frameCommand.frameNum + SvrFrameLater) * KeyFrameRate;
                            if (commandFrame > CurFrameNum)
                            {
                                break;
                            }

                            frameCommand          = commandQueue.Dequeue();
                            frameCommand.frameNum = commandFrame;
                            frameCommand.ExecCommand();

                            AbstractSmartObj obj = (AbstractSmartObj)frameCommand;
                            if (obj != null)
                            {
                                obj.Release();
                            }
                        }
                        if (!bEscape)
                        {
                            //通知刷新游戏逻辑层
                            MEObjDeliver e = ObjectCachePool.instance.Fetch <MEObjDeliver>();

                            e.args[0] = (int)FrameDelta;
                            e.args[1] = i == 1 && deltaTime < (long)(2u * FrameDelta); //false;
                            e.opcode  = (int)EObjDeliverOPCode.E_OP_UPDATE_GAME_LOGIC;

                            Mercury.instance.Broadcast(EventTokenTable.et_framesynchr, this, e);
                        }
                        i--;
                    }
                }
                else
                {
                    i = 0;
                }
            }
        }