示例#1
0
        /// <summary>
        ///  当寻路需要RCPF的时候,调用这个继续寻路
        ///  This Move is used when the pathing finding requires continues finding
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        void Move(int x, int y)
        {
            int sx, sy;
            Map.GetMapCoord(longtitude, latitude, out sx, out sy);

            destX = x;
            destY = y;

            finder.Reset();
            currentPath = finder.FindPath(sx, sy, x, y);
            currentNode = 0;
            nodeMotionProgress = 0;
        }
示例#2
0
        public override void Update(GameTime dt)
        {
            float ddt = (float)dt.ElapsedGameTimeSeconds;

            #region 装货卸货
            // Process the loading/unloading
            if (isLoading && exRes != null)
            {
                if (harvStorage < props.Storage)
                {
                    // 计算开矿倍数,保证能够完成卸货
                    // calculate the loading/unloading ratio, to ensure with this speed multiplier
                    // the harvester can finish the job in time.
                    float scale = props.Storage / (RulesTable.HarvLoadingSpeed * RulesTable.HarvLoadingTime);

                    harvStorage += exRes.Exploit(RulesTable.HarvLoadingSpeed * ddt * scale);

                }
                loadingTime -= ddt;

                // 开矿loadingTime时间之后,停止并引发事件
                // when the time runs out, stop to raise the event
                if (loadingTime < 0)
                {
                    isFullLoaded = harvStorage >= props.Storage;
                    isLoading = false;
                    if (GotThere != null)
                        GotThere(this, EventArgs.Empty);
                }
            }
            
            //else
            //{
            //    isFullLoaded = true;
            //    loadingTime = 0;
            //    if (GotThere != null)
            //        GotThere(this, EventArgs.Empty);
            //}
            if (isUnloading)
            {
                // 计算开矿倍数,保证能够完成卸货
                // calculate the loading/unloading ratio, to ensure with this speed multiplier
                // the harvester can finish the job in time.
                float scale = props.Storage / (RulesTable.HarvLoadingSpeed * RulesTable.HarvLoadingTime);

                float change = RulesTable.HarvLoadingSpeed * ddt * scale;

                // 检查车上的存量是否足够
                // check if remaining storage is enough
                if (harvStorage - change > 0)
                {
                    // 足够时定量卸下
                    // unload all when enough
                    harvStorage -= change;
                    // 并且通知城市得到资源
                    // and tell the city the amount of resource obtained
                    parent.NotifyGotResource(change);
                }
                else
                {
                    // 不够时把剩下的都卸了
                    // otherwise, unload all the remains
                    parent.NotifyGotResource(harvStorage);
                    harvStorage = 0;
                    
                }

                loadingTime -= ddt;

                // 一定时间后停止
                // when the time runs out, stop to raise the event
                if (loadingTime < 0)
                {
                    isUnloading = false;
                    if (GotHome != null)
                        GotHome(this, EventArgs.Empty);
                }
            }
            #endregion

            float altitude = map.GetHeight(longtitude, latitude);

            if (currentPath != null)
            {
                int nextNode = currentNode + 1;

                if (nextNode >= currentPath.NodeCount)
                {
                    #region 寻路完毕,状态转换
                    // when the path following is finished, by reaching the final node
                    // switch to new state
                    nextNode = 0;
                    nodeMotionProgress = 0;

                    if (currentPath.RequiresPathFinding)
                    {
                        // continues path finding
                        Move(destX, destY);
                    }
                    else
                    {
                        // stop by setting null
                        currentPath = null;

                        if (movePurpose == MovePurpose.Gather)
                        {
                            isLoading = true;
                            loadingTime = RulesTable.HarvLoadingTime;
                        }
                        else if (movePurpose == MovePurpose.Home)
                        {
                            isUnloading = true;
                            loadingTime = RulesTable.HarvLoadingTime;
                        }
                    }
                    #endregion
                }
                else
                {
                    #region 路径节点插值
                    // calculate the interpolation between 2 nodes


                    // 采集车在每两个节点之间移动都是一定过程
                    // 其位置/朝向是插值结果。差值参数为nodeMotionProgress
                    // The locomotion of harvester between 2 MoveNode is a process in time.
                    // Its position and orientation is the result of interpolation, where 
                    // nodeMotionProgress is the interpolation amount.

                    Point cp = currentPath[currentNode];
                    Point np = currentPath[nextNode];

                    // 在一开始就尝试获取下一节点位置
                    // Check if the position in the next 2 MoveNodes need to be updated,
                    // as parameters to calculate translation
                    if (!stateUpdated)
                    {
                        if (isAdjustingDirection)
                        {
                            // 在调整方向时,车是位置不动的
                            // The car does not move when changing direction

                            Map.GetCoord(np.X, np.Y, out src.Longitude, out src.Latitude);

                            src.Alt = map.GetHeight(src.Longitude, src.Latitude);

                            target.Longitude = src.Longitude;
                            target.Latitude = src.Latitude;
                            target.Alt = src.Alt;
                        }
                        else
                        {
                            Map.GetCoord(cp.X, cp.Y, out src.Longitude, out src.Latitude);
                            Map.GetCoord(np.X, np.Y, out target.Longitude, out target.Latitude);

                            src.Alt = map.GetHeight(src.Longitude, src.Latitude);
                            target.Alt = map.GetHeight(target.Longitude, target.Latitude);
                        }
                        stateUpdated = true;
                    }
                    
                    // 在进行了一半之后开始获取下一节点朝向
                    // When the interpolation amount run over 0.5, update the 
                    // information for orientation of the next 2 nodes, as parameters to calculate
                    // turning.
                    if (nodeMotionProgress > 0.5f && !rotUpdated)
                    {
                        if (isAdjustingDirection)
                        {
                            target.Ori = GetOrientation(cp, np);
                        }
                        else 
                        {
                            if (nextNode < currentPath.NodeCount - 1)
                            {
                                src.Ori = GetOrientation(cp, np);
                                target.Ori = GetOrientation(np, currentPath[nextNode + 1]);
                            }
                            else
                            {
                                target.Ori = GetOrientation(cp, np);
                                src.Ori = target.Ori;
                            }
                        }
                        rotUpdated = true;
                    }

                    if (!isAdjustingDirection)
                    {
                        float x = MathEx.LinearInterpose(cp.X, np.X, nodeMotionProgress);
                        float y = MathEx.LinearInterpose(cp.Y, np.Y, nodeMotionProgress);

                        Map.GetCoord(x, y, out longtitude, out latitude);
                    }
                    altitude = MathEx.LinearInterpose(src.Alt, target.Alt, nodeMotionProgress);

                    #region 动画控制
                    // Animate by changing the index

                    // Car have a different look when on water
                    if (altitude < 0)
                        mdlIndex++;
                    else
                        mdlIndex--;

                    if (mdlIndex < 0)
                        mdlIndex = 0;
                    if (mdlIndex >= NumModels)
                        mdlIndex = NumModels - 1;

                    if (model != null)
                    {
                        if (parent.Owner != null)
                        {
                            if (parent.Type == CityType.Oil)
                            {
                                ModelL0 = model_bad[mdlIndex];
                            }
                            else
                            {
                                ModelL0 = model[mdlIndex];
                            }
                        }
                        else
                        {
                            ModelL0 = null;
                        }                        
                    }
                    #endregion

                    // 采集车不会潜水
                    // Keep the car not diving
                    if (altitude < 0)
                        altitude = 0;

                    // 球面插值,计算出朝向
                    // Spherical interpolation for direction
                    Orientation = Matrix.RotationQuaternion(
                        Quaternion.Slerp(src.Ori, target.Ori, nodeMotionProgress > 0.5f ? nodeMotionProgress - 0.5f : nodeMotionProgress + 0.5f));

                    if (isAdjustingDirection)
                    {
                        nodeMotionProgress += 0.5f * ddt;
                    }
                    else 
                    {
                        // 挺进节点插值进度
                        // Progress the interpolation between 2 nodes
                        nodeMotionProgress += 0.05f * acceleration;
                    }

                    // 检查节点之间插值是否完成
                    // Check if the interpolation is done
                    if (nodeMotionProgress > 1)
                    {
                        nodeMotionProgress = 0;

                        if (isAdjustingDirection)
                            // 我们只允许调整方向一次,调整这次不会让车在节点上移动,currentNode不变
                            // We only allow adjust the direction once
                            isAdjustingDirection = false; 
                        else
                            currentNode++;
                        
                        rotUpdated = false;
                        stateUpdated = false;
                    }
                    #endregion

                }

                #region 加速度计算
                // Calculate the acceleration
                if (currentPath != null)
                {
                    // 检查是否是最后一个节点了
                    // Check if this is the last node
                    if (nextNode == currentPath.NodeCount - 1)
                    {
                        // 开始减速
                        // Deceleration
                        acceleration -= ddt * 1.5f;
                        // 防止减速的过慢
                        // Set the minimum
                        if (acceleration < 0.33f)
                            acceleration = 0.33f;
                    }
                    else if (!isAdjustingDirection)
                    {
                        // 平时都是加速到最大为止
                        // otherwise, increase to full speed
                        acceleration += ddt * 1.5f;
                        if (acceleration > 1)
                            acceleration = 1;
                    }
                }
                #endregion
            }
            else
            {
                acceleration = 0;
            }


            //Orientation *= PlanetEarth.GetOrientation(longtitude, latitude);

            // 通过插值计算的经纬度得到坐标
            // The position is obtained by the interpolated long-lat coordinate
            Position = PlanetEarth.GetPosition(longtitude, latitude, PlanetEarth.PlanetRadius + altitude);
            base.Update(dt);



            BattleField field = map.Field;


            if (parent != null && parent.Owner != null && parent.Owner.Type == PlayerType.LocalHuman)
            {
                field.Fog.LightArea(longtitude,
                    latitude, MathEx.Degree2Radian(5));
            }

            Visibility = field.Fog.GetVisibility(longtitude,
                   latitude);
            //if (IsSelected && IsInVisibleRange)
            //{
            //    IsSelected = false;

            //}   

        }
示例#3
0
        /// <summary>
        ///  让采集车移动到有经纬度确定的地点
        ///  Ask the harvester to move to a given location, which is represented
        ///  by longtitude and latitude
        /// </summary>
        /// <param name="lng"></param>
        /// <param name="lat"></param>
        public void Move(float lng, float lat)
        {
            //IsAuto = false;
            movePurpose = MovePurpose.None;

            int sx, sy;
            Map.GetMapCoord(longtitude, latitude, out sx, out sy);

            int tx, ty;
            Map.GetMapCoord(lng, lat, out tx, out ty);

            destX = tx;
            destY = ty;

            finder.Reset();
            currentPath = finder.FindPath(sx, sy, tx, ty);
            
            // 新的动作要先调整朝向
            // Adjust direction before going
            isAdjustingDirection = true;

            currentNode = 0;
            nodeMotionProgress = 0;
        }