Ejemplo n.º 1
0
            public static XYPosition CellToGrid(int x, int y)               //求格子的中心坐标
            {
                XYPosition ret = new XYPosition(x * Constant.numOfGridPerCell + Constant.numOfGridPerCell / 2,
                                                y * Constant.numOfGridPerCell + Constant.numOfGridPerCell / 2);

                return(ret);
            }
Ejemplo n.º 2
0
 public virtual void Move(MoveEventArgs e)
 {
     if (e.distance == 0)
     {
         return;
     }
     lock (privateLock)
     {
         if (!this._movable)
         {
             return;
         }
         if ((DateTime.Now - lastMoveTime).TotalSeconds < 1 / _frameRate)
         {
             return;
         }
         MoveStart?.Invoke(this);
         XYPosition previousPosition = _position;
         _position = _position + new XYPosition(e.distance * Math.Cos(e.angle), e.distance * Math.Sin(e.angle));
         Debug(this, "Move from " + previousPosition.ToString() + " angle : " + e.angle + " distance : " + e.distance + " aim : " + _position.ToString());
         OnMove?.Invoke(this, e, previousPosition);
         Debug(this, "Move result poition : " + this._position.ToString());
         MoveComplete?.Invoke(this);
     }
 }
Ejemplo n.º 3
0
 protected virtual void PositionChanged(PositionChangedEventArgs e)
 {
     lock (privateLock)
     {
         _position = e.position;
         OnPositionChanged?.Invoke(this, e);
     }
     PositionChangeComplete?.Invoke(this);
 }
Ejemplo n.º 4
0
 void ToolRefresh(object?o)
 {
     THUnity2D.XYPosition tempPosition = new THUnity2D.XYPosition(Program.Random.Next(1, map.GetLength(0) - 1), Program.Random.Next(1, map.GetLength(1) - 1));;
     for (int i = 0; i < 10 && !WorldMap.Grid[(int)tempPosition.x, (int)tempPosition.y].IsEmpty(); i++)//加入次数限制,防止后期地图过满疯狂Random
     {
         tempPosition = new THUnity2D.XYPosition(Program.Random.Next(1, map.GetLength(0) - 1), Program.Random.Next(1, map.GetLength(1) - 1));
     }
     new Tool(tempPosition.x + 0.5, tempPosition.y + 0.5, (ToolType)Program.Random.Next(1, (int)ToolType.ToolSize - 1)).Parent = WorldMap;
 }
Ejemplo n.º 5
0
 public void SetLaid(XYPosition pos)
 {
     if (laid)
     {
         return;
     }
     laid     = true;
     Position = pos;
     shape    = ShapeType.Circle;
 }
Ejemplo n.º 6
0
        //返回爆炸范围,相对自己的相对距离
        public XYPosition[] GetAttackRange()
        {
            XYPosition[] range;
            switch (bulletType)
            {
            case BulletType.Bullet0:
            case BulletType.Bullet1:
            case BulletType.Bullet5:
            case BulletType.Bullet6:
                range = new XYPosition[9];
                for (int i = 0; i < 3; ++i)
                {
                    for (int j = 0; j < 3; ++j)
                    {
                        range[i * 3 + j].x = i - 1;
                        range[i * 3 + j].y = j - 1;
                    }
                }
                break;

            case BulletType.Bullet2:
                range = new XYPosition[25];
                for (int i = 0; i < 5; ++i)
                {
                    for (int j = 0; j < 5; ++j)
                    {
                        range[i * 5 + j].x = i - 2;
                        range[i * 5 + j].y = j - 2;
                    }
                }
                break;

            case BulletType.Bullet4:
                range = new XYPosition[49];
                for (int i = 0; i < 7; ++i)
                {
                    for (int j = 0; j < 7; ++j)
                    {
                        range[i * 7 + j].x = i - 3;
                        range[i * 7 + j].y = j - 3;
                    }
                }
                break;

            case BulletType.Bullet3:
                range      = new XYPosition[1];
                range[0].x = range[0].y = 0;
                break;

            default:
                range = new XYPosition[0];
                break;
            }
            return(range);
        }
Ejemplo n.º 7
0
        //检查childrenGameObject的位置是否合法
        //目前只能检查边长为1的方块
        //检查规则:任何方块的任何部分不能超出地图边界
        //如果方块为可碰撞的,则方块不能与其他可碰撞方块有重叠部分。
        public bool XYPositionIsLegal(XYPosition position, int objectWidth = 0, int objectHeight = 0, Layer?objectLayer = null)
        {
            DebugWithoutEndline(this, "Checking position : " + position.ToString() + " width : " + objectWidth + " height : " + objectHeight + " layer : " + objectLayer);

            if (!XIsLegal(position.x, objectWidth) || !YIsLegal(position.y, objectHeight))
            {
                DebugWithoutID(this, "false");
                return(false);
            }
            if (objectLayer != null && !_layerSet.ContainsKey(objectLayer))
            {
                throw new Exception("Does not contain layer");
            }
            for (int x = (int)position.x - 1; x <= (int)position.x + 1; x++)
            {
                for (int y = (int)position.y - 1; y <= (int)position.y + 1; y++)
                {
                    if (!XIsLegal(x) || !YIsLegal(y))
                    {
                        continue;
                    }
                    if (objectLayer != null)
                    {
                        foreach (var layer in objectLayer.CollisionLayers.Keys)
                        {
                            if (!_grid[x, y].Layers.ContainsKey(layer))
                            {
                                continue;
                            }
                            foreach (var gameObject in _grid[x, y].Layers[layer].Keys)
                            {
                                if (Math.Abs(gameObject.Position.x - position.x) < 1 &&
                                    Math.Abs(gameObject.Position.y - position.y) < 1)
                                {
                                    DebugWithoutID(this, "false");
                                    return(false);
                                }
                            }
                        }
                    }
                }
            }
            DebugWithoutID(this, "true");
            return(true);
        }
Ejemplo n.º 8
0
        public Bullet(XYPosition initPos, int radius, int basicMoveSpeed, BulletType bulletType, int ap, bool hasSpear)
            : base(initPos, radius, false, basicMoveSpeed, ObjType.Bullet, ShapeType.Circle)
        {
            this.ap         = ap;
            this.hasSpear   = hasSpear;
            this.bulletType = bulletType;
            switch (bulletType)
            {
            default:
            case BulletType.Bullet0:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed;
                IsRigid   = true;
                break;

            case BulletType.Bullet1:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed * 2;
                IsRigid   = false;
                break;

            case BulletType.Bullet2:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed / 2;
                IsRigid   = true;
                break;

            case BulletType.Bullet3:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed / 2;
                IsRigid   = true;
                break;

            case BulletType.Bullet4:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed * 4;
                IsRigid   = false;
                break;

            case BulletType.Bullet5:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed;
                IsRigid   = true;
                break;

            case BulletType.Bullet6:
                MoveSpeed = OrgMoveSpeed = basicMoveSpeed;
                IsRigid   = true;
                break;
            }
        }
Ejemplo n.º 9
0
 public static double ManhattanDistance(XYPosition position1, XYPosition position2)
 {
     return(Math.Abs(position1.x - position2.x) + Math.Abs(position1.y - position2.y));
 }
Ejemplo n.º 10
0
 public static double Distance(XYPosition position1, XYPosition position2)
 {
     return(Math.Sqrt(Math.Pow(Math.Abs(position1.x - position2.x), 2) + Math.Pow(Math.Abs(position1.y - position2.y), 2)));
 }
Ejemplo n.º 11
0
 public static bool IntEqual(XYPosition xy1, XYPosition xy2)
 {
     return((int)xy1.x == (int)xy2.x && (int)xy1.y == (int)xy2.y);
 }
Ejemplo n.º 12
0
 public Amplifier(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 13
0
 public Bike(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 14
0
 public PositionChangedEventArgs(XYPosition previousPosition, XYPosition position)
 {
     this.previousPosition = previousPosition;
     this.position         = position;
 }
Ejemplo n.º 15
0
 public JinKeLa(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 16
0
        //调整方块到合法位置
        //目前只能调整边长为1的方块
        //此函数内不可调用childrenGameObject的Position Setter,否则会触发死循环
        //输入:一个GameObject(不一定是地图的子GameObject)
        protected XYPosition CorrectPosition(XYPosition position, int objectWidth = 1, int objectHeight = 1, Layer?objectLayer = null)
        {
            Debug(this, "Correcting Position : " + position.ToString() + " width : " + objectWidth + " height : " + objectHeight + " layer : " + objectLayer);

            if (XYPositionIsLegal(position, objectWidth, objectHeight, objectLayer))
            {
                return(position);
            }

            XYPosition newCenterPosition = position.GetMid();

            if (newCenterPosition.x < 0.5)
            {
                newCenterPosition = new XYPosition(0.5, newCenterPosition.y);
            }
            else if (newCenterPosition.x > (double)this._width - 0.5)
            {
                newCenterPosition = new XYPosition((double)this._width - 0.5, newCenterPosition.y);
            }
            if (newCenterPosition.y < 0.5)
            {
                newCenterPosition = new XYPosition(newCenterPosition.x, 0.5);
            }
            else if (newCenterPosition.y > (double)this._height - 0.5)
            {
                newCenterPosition = new XYPosition(newCenterPosition.x, (double)this._height - 0.5);
            }

            if (XYPositionIsLegal(newCenterPosition, objectWidth, objectHeight, objectLayer))
            {
                return(newCenterPosition);
            }

            XYPosition testPosition = newCenterPosition;

            for (int round = 1; round < Math.Max(this._width, this._height); round++)
            {
                //Debug(this,"round : " + round);
                for (double ySearch = newCenterPosition.y - (double)round; ySearch <= newCenterPosition.y + (double)round + 0.1; ySearch += 2 * (double)round)
                {
                    if (!YIsLegal(ySearch))
                    {
                        continue;
                    }
                    for (double xSearch = newCenterPosition.x - (double)round; xSearch <= newCenterPosition.x + (double)round + 0.1; xSearch++)
                    {
                        if (!XIsLegal(xSearch))
                        {
                            continue;
                        }
                        testPosition = new XYPosition(xSearch, ySearch);
                        if (XYPositionIsLegal(testPosition, objectWidth, objectHeight, objectLayer))
                        {
                            return(testPosition);
                        }
                    }
                }
                for (double xSearch = newCenterPosition.x - round; xSearch <= newCenterPosition.x + round + 0.1; xSearch += 2 * round)
                {
                    if (!XIsLegal(xSearch))
                    {
                        continue;
                    }
                    for (double ySearch = newCenterPosition.y - (round - 1); ySearch <= newCenterPosition.y + (round - 1) + 0.1; ySearch++)
                    {
                        if (!YIsLegal(ySearch))
                        {
                            continue;
                        }
                        testPosition = new XYPosition(xSearch, ySearch);
                        if (XYPositionIsLegal(testPosition, objectWidth, objectHeight, objectLayer))
                        {
                            return(testPosition);
                        }
                    }
                }
            }
            return(new XYPosition(0, 0));//找不到合法位置,返回无效值
        }
Ejemplo n.º 17
0
 public GameObject(XYPosition position, GameObject?parent = null) : this(parent)
 {
     this.Position = position;
 }
Ejemplo n.º 18
0
 public Spear(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 19
0
 public Totem(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 20
0
 public Shield(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 21
0
 protected virtual void OnChildrenMove(GameObject gameObject, MoveEventArgs e, XYPosition previousPosition)
 {
 }
Ejemplo n.º 22
0
 public Prop(XYPosition initPos, int radius) : base(initPos, radius, true, 0, ObjType.Prop, ShapeType.Sqare)
 {
 }
Ejemplo n.º 23
0
 public Attenuator(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 24
0
        protected override void OnChildrenPositionChanged(GameObject childrenGameObject, XYPosition previousPosition, XYPosition targetPosition)
        {
            Debug(this, "Children object " + childrenGameObject.ID + " position change. from : " + previousPosition.ToString() + " aim : " + targetPosition.ToString());
            //base.OnChildrenPositionChanged(childrenGameObject, e, out eOut);

            if (XIsLegal((int)previousPosition.x) && YIsLegal((int)previousPosition.y))
            {
                this._grid[(int)previousPosition.x, (int)previousPosition.y].DeleteGameObject(childrenGameObject);//如果需要把childrenGameObject从Grid上拿掉且可以拿掉
            }
            childrenGameObject._position = CorrectPosition(targetPosition, childrenGameObject.Width, childrenGameObject.Height, childrenGameObject.Layer);
            _grid[(int)childrenGameObject.Position.x, (int)childrenGameObject.Position.y].AddGameObject(childrenGameObject);
            TryToTrigger(childrenGameObject);
        }
Ejemplo n.º 25
0
        //为提高代码复用性,此函数内大量采用长度为2的数组表示X和Y,0表示X,1表示Y
        protected override void OnChildrenMove(GameObject childrenGameObject, MoveEventArgs e, XYPosition previousPosition)
        {
            Debug(this, "Attempting to move Children : " + childrenGameObject.ID);
            //base.OnChildrenMove(childrenGameObject, e, out eOut);
            //XYPosition aim;
            double resultDistance = e.distance;

            double[] delta = new double[2];
            delta[0] = e.distance * Math.Cos(e.angle);
            if (Math.Abs(delta[0]) < 1E-8)
            {
                delta[0] = 0;
            }
            delta[1] = e.distance * Math.Sin(e.angle);
            if (Math.Abs(delta[1]) < 1E-8)
            {
                delta[1] = 0;
            }
            bool[] IsDirectionPositive = { (delta[0] < 0) ? false : true, (delta[1] < 0) ? false : true };
            HashSet <GameObject>?CollisionGameObjects = null;
            SortedDictionary <double, HashSet <GameObject> > triggerDistanceAndGameObjects = new SortedDictionary <double, HashSet <GameObject> >();
            Direction collisionDirection = Direction.Size;

            void RefreshCollisionDirection(double[] Distance)
            {
                if (Distance[0] < Distance[1])
                {
                    collisionDirection = IsDirectionPositive[0] ? Direction.Right : Direction.Left;
                }
                else if (Distance[1] < Distance[0])
                {
                    collisionDirection = IsDirectionPositive[1] ? Direction.Up : Direction.Down;
                }
                else
                {
                    if (IsDirectionPositive[0])
                    {
                        collisionDirection = IsDirectionPositive[1] ? Direction.RightUp : Direction.RightDown;
                    }
                    else
                    {
                        collisionDirection = IsDirectionPositive[1] ? Direction.LeftUp : Direction.LeftDown;
                    }
                }
            }

            Debug(this, "initialize resultDistance : " + resultDistance);

            double ClosestGreater0_5(double d)
            {
                return((int)(d - 0.5) + 1.5);
            }

            double ClosestSmaller0_5(double d)
            {
                return(Math.Ceiling(d + 0.5) - 1.5);
            }

            double[] initial       = new double[2];
            double[] middleInitial = new double[2];
            double[] BeginToSearch = new double[2];
            for (int i = 0; i < 2; i++)
            {
                if (IsDirectionPositive[i])
                {
                    initial[i]       = previousPosition.GetProperty(i) - (((double)childrenGameObject.GetLength(i) / 2) + 1);
                    middleInitial[i] = initial[i] + 3;
                    BeginToSearch[i] = ClosestGreater0_5(initial[i]);
                }
                else
                {
                    initial[i]       = previousPosition.GetProperty(i) + (((double)childrenGameObject.GetLength(i) / 2) + 1);
                    middleInitial[i] = initial[i] - 3;
                    BeginToSearch[i] = ClosestSmaller0_5(initial[i]);
                }
            }
            double[] end       = new double[2];
            double[] middleEnd = new double[2];
            double[] Search    = new double[2];
            for (int i = 0; i < 2; i++)
            {
                end[i]       = middleInitial[i] + delta[i];
                middleEnd[i] = initial[i] + delta[i];
                Search[i]    = BeginToSearch[i];
            }

            void RefreshResultDistance(double newResultDistance)
            {
                if (newResultDistance >= resultDistance || newResultDistance < 0)
                {
                    return;
                }
                Debug(this, "Refresh resultDistance : " + newResultDistance);
                for (int i = 0; i < 2; i++)
                {
                    delta[i]     = DivisionWithoutNaN(delta[i] * newResultDistance, resultDistance);
                    end[i]       = middleInitial[i] + delta[i];
                    middleEnd[i] = initial[i] + delta[i];
                }
                resultDistance = newResultDistance;
            }

            {//这段代码检查是否准备移动到地图外,若是,把它移回地图内
                double[] aim        = { previousPosition.x + delta[0], previousPosition.y + delta[1] };
                double[] Distance   = { resultDistance, resultDistance };
                double[] HalfLength = { (double)childrenGameObject.Width / 2.0, (double)childrenGameObject.Height / 2.0 };
                for (int i = 0; i < 2; i++)
                {
                    if (aim[i] < HalfLength[i])
                    {
                        Distance[i] = (HalfLength[i] - previousPosition.GetProperty(i)) / delta[i] * resultDistance;
                    }
                    else if (aim[i] > this.GetLength(i) - HalfLength[i])
                    {
                        Distance[i] = (this.GetLength(i) - HalfLength[i] - previousPosition.GetProperty(i)) / delta[i] * resultDistance;
                    }
                }
                RefreshResultDistance(Math.Min(Distance[0], Distance[1]));
                RefreshCollisionDirection(Distance);
            }

            //======================
            //这段代码返回一个距离,childrenGameObject需要运行多远才能“碰到”gameObject
            double[] toCheckAdd    = { IsDirectionPositive[0] ? -0.5 : 0.5, IsDirectionPositive[1] ? -0.5 : 0.5 };
            double[] startPointAdd = { -toCheckAdd[0], -toCheckAdd[1] };
            double[] infinityBound = { IsDirectionPositive[0] ? 1.0 / 0.0 : -1.0 / 0.0, IsDirectionPositive[1] ? 1.0 / 0.0 : -1.0 / 0.0 };
            double GameObjectMaxReachDistance(GameObject gameObject, ref double[] Distance)
            {
                Distance[0] = 1.0 / 0.0; Distance[1] = 1.0 / 0.0;
                double[] toCheck    = new double[2];
                double[] startPoint = new double[2];

                for (int i = 0; i < 2; i++)//分别检查X和Y
                {
                    int j = Convert.ToInt32(!Convert.ToBoolean(i));
                    toCheck[i]    = gameObject.Position.GetProperty(i) + toCheckAdd[i];
                    startPoint[i] = previousPosition.GetProperty(i) + startPointAdd[i];
                    if (IsInCloseOpenInterval(toCheck[i], startPoint[i], infinityBound[i]) &&
                        delta[i] != 0)   //如果平行四边形是一条线,就跳过
                    {
                        //Debug(this,"delta[" + i + "] : " + delta[i]);
                        double temp = previousPosition.GetProperty(j) - 0.5 + (toCheck[i] - startPoint[i]) * delta[j] / delta[i];
                        //Debug(this, "temp : " + temp);
                        if (IsInOpenInterval(temp, gameObject.Position.GetProperty(j) - 0.5 - 1, gameObject.Position.GetProperty(j) + 0.5))
                        {
                            //Debug(this, "!");
                            Distance[i] = (toCheck[i] - startPoint[i]) * resultDistance / delta[i];
                        }
                    }
                    //Debug(this, "Distance[" + i + "] : " + Distance[i]);
                }
                double maxReachDistance = Math.Min(Distance[0], Distance[1]);

                {
                    //Debug(this, "toCheck[0]=" + toCheck[0]);
                    //Debug(this, "startPoint[0]=" + startPoint[0]);
                    //Debug(this, "delta[0]=" + delta[0]);
                    //Debug(this, "toCheck[1]=" + toCheck[1]);
                    //Debug(this, "startPoint[1]=" + startPoint[1]);
                    //Debug(this, "delta[1]=" + delta[1]);
                    if (Math.Abs((toCheck[0] - startPoint[0]) * delta[1] - (toCheck[1] - startPoint[1]) * delta[0]) < 1E-10)
                    {
                        if (Math.Abs(toCheck[0] - startPoint[0]) < 1E-10 && Math.Abs(toCheck[1] - startPoint[1]) < 1E-10 &&
                            delta[0] != 0 && delta[1] != 0)
                        {
                            maxReachDistance = 0;
                        }
                        else if (Math.Abs(toCheck[0] - startPoint[0]) >= 1E-10 && Math.Abs(toCheck[1] - startPoint[1]) >= 1E-10)
                        {
                            maxReachDistance = resultDistance * (toCheck[0] - startPoint[0]) / delta[0];
                        }
                    }
                }
                Debug(this, "maxReachDistance : " + maxReachDistance);
                return(maxReachDistance);
            }

            //=================


            //核心代码,检查(x,y)位置的方块与childrenGameObject的关系,并检查碰撞
            LinkedList <object> lockList = new LinkedList <object>();

            void CheckBlockAndAdjustPosition(int x, int y)
            {
                if (!(XIsLegal(x) && YIsLegal(y)))
                {
                    return;
                }
                Monitor.Enter(_grid[x, y].publicLock);
                lockList.AddLast(_grid[x, y].publicLock);
                if (x != (int)previousPosition.x || y != (int)previousPosition.y)
                {
                    foreach (var layer in childrenGameObject.Layer.CollisionLayers.Keys)
                    {
                        if (!_grid[x, y].ContainsLayer(layer))
                        {
                            continue;
                        }
                        foreach (var toCheckGameObject in _grid[x, y].Layers[layer].Keys)
                        {
                            double[] Distance         = new double[2];
                            double   maxReachDistance = GameObjectMaxReachDistance(toCheckGameObject, ref Distance);

                            //检查是否与toCheckGameObject碰撞,若是,更新resultDistance并获取碰撞方向
                            //当与多个GameObject碰撞时会出现不合逻辑的地方,暂时无法解决
                            if (maxReachDistance < resultDistance)
                            {
                                RefreshResultDistance(maxReachDistance);
                                RefreshCollisionDirection(Distance);
                                if (CollisionGameObjects == null)
                                {
                                    CollisionGameObjects = new HashSet <GameObject>();
                                }
                                CollisionGameObjects.Clear();
                                CollisionGameObjects.Add(toCheckGameObject);
                                //collisionDistance = resultDistance;
                            }
                            else if (maxReachDistance == resultDistance)
                            {
                                if (CollisionGameObjects != null)
                                {
                                    CollisionGameObjects.Add(toCheckGameObject);
                                }
                            }
                            //检查是否与toCheckGameObject碰撞,若是,更新resultDistance并获取碰撞方向
                        }
                    }
                }
                foreach (var layer in childrenGameObject.Layer.TriggerLayers.Keys)
                {
                    if (!_grid[x, y].ContainsLayer(layer))
                    {
                        continue;
                    }
                    foreach (var gameObject in _grid[x, y].Layers[layer].Keys)
                    {
                        double[] Distance = new double[2];
                        double   maxReachDistance;
                        if (Math.Abs(gameObject.Position.x - previousPosition.x) < 1.0 &&
                            Math.Abs(gameObject.Position.y - previousPosition.y) < 1.0)
                        {
                            maxReachDistance = 0;
                        }
                        else
                        {
                            maxReachDistance = GameObjectMaxReachDistance(gameObject, ref Distance);
                        }
                        if (maxReachDistance >= resultDistance)
                        {
                            continue;
                        }
                        if (!triggerDistanceAndGameObjects.ContainsKey(maxReachDistance))
                        {
                            triggerDistanceAndGameObjects.Add(maxReachDistance, new HashSet <GameObject>());
                        }
                        triggerDistanceAndGameObjects[maxReachDistance].Add(gameObject);
                    }
                }
            }

            {//这段代码检查是否准备移动到地图外,若是,把它移回地图内
                double[] aim        = { previousPosition.x + delta[0], previousPosition.y + delta[1] };
                double[] Distance   = { resultDistance, resultDistance };
                double[] HalfLength = { (double)childrenGameObject.Width / 2.0, (double)childrenGameObject.Height / 2.0 };
                for (int i = 0; i < 2; i++)
                {
                    if (aim[i] < HalfLength[i])
                    {
                        Distance[i] = (HalfLength[i] - previousPosition.GetProperty(i)) / delta[i] * resultDistance;
                    }
                    else if (aim[i] > this.GetLength(i) - HalfLength[i])
                    {
                        Distance[i] = (this.GetLength(i) - HalfLength[i] - previousPosition.GetProperty(i)) / delta[i] * resultDistance;
                    }
                }
                RefreshResultDistance(Math.Min(Distance[0], Distance[1]));
                RefreshCollisionDirection(Distance);
            }

            //搜索可能碰撞的GameObject
            //建议不要尝试读懂这段代码
            bool[] SearchCompleted = { false, false };
            Func <double, double, bool>[]   Compare  = new Func <double, double, bool> [2];
            Func <double, double, double>[] MinOrMax = new Func <double, double, double> [2];
            double[] Step = new double[2];
            for (int i = 0; i < 2; i++)
            {
                if (IsDirectionPositive[i])
                {
                    Compare[i]  = (d1, d2) => { return(d1 < d2); };
                    Step[i]     = 1;
                    MinOrMax[i] = (d1, d2) => { return(Math.Min(d1, d2)); };
                }
                else
                {
                    Compare[i]  = (d1, d2) => { return(d1 > d2); };
                    Step[i]     = -1;
                    MinOrMax[i] = (d1, d2) => { return(Math.Max(d1, d2)); };
                }
            }
            ;
            for (; ;)
            {
                for (int i = 0; i < 2; i++)
                {
                    int j = Convert.ToInt32(!Convert.ToBoolean(i));
                    if (Compare[i](Search[i], end[i]))
                    {
                        for (double z = Compare[i](Search[i], middleInitial[i]) ?
                                        BeginToSearch[j] :
                                        IsDirectionPositive[j] ?
                                        ClosestGreater0_5(initial[j] + DivisionWithoutNaN((Search[i] - middleInitial[i]) * delta[j], delta[i])) :
                                        ClosestSmaller0_5(initial[j] + DivisionWithoutNaN((Search[i] - middleInitial[i]) * delta[j], delta[i]));
                             Compare[j](z,
                                        MinOrMax[j](BeginToSearch[j] + Step[j] * (Math.Abs(Search[i] - BeginToSearch[i]) + (i == 0 ? 0.1 : -0.1)),
                                                    Compare[i](Search[i], middleEnd[i]) ?
                                                    end[j] + DivisionWithoutNaN(Search[i] - middleEnd[i], delta[i]) * delta[j] :
                                                    end[j]));
                             z = z + Step[j])
                        {
                            Debug(this, "Checking : (" + (i == 0 ? Search[i] : z) + "," + (i == 0 ? z : Search[i]) + ")");
                            CheckBlockAndAdjustPosition(i == 0 ? (int)Search[i] : (int)z, i == 0 ? (int)z : (int)Search[i]);
                        }
                        Search[i] = Search[i] + Step[i];
                    }
                    else
                    {
                        SearchCompleted[i] = true;
                    }
                }
                if (SearchCompleted[0] && SearchCompleted[1])
                {
                    break;
                }
            }
            //搜索可能碰撞的GameObject
            //建议不要尝试读懂这段代码

            //调整位置
            Debug(this, "resultDistance : " + resultDistance);
            childrenGameObject._position = previousPosition + new XYPosition(resultDistance * Math.Cos(e.angle), resultDistance * Math.Sin(e.angle));
            this._grid[(int)previousPosition.x, (int)previousPosition.y].DeleteGameObject(childrenGameObject);
            this._grid[(int)childrenGameObject.Position.x, (int)childrenGameObject.Position.y].AddGameObject(childrenGameObject);
            //调整位置 End

            //解除锁的占用
            for (; lockList.Count != 0;)
            {
                object o = lockList.First.Value;
                lockList.RemoveFirst();
                Monitor.Exit(o);
            }
            //解除锁的占用 End

            //Trigger
            HashSet <GameObject> triggerGameObjects = new HashSet <GameObject>();

            foreach (var item in triggerDistanceAndGameObjects)
            {
                if (item.Key >= resultDistance)
                {
                    break;
                }
                foreach (var gameObject in item.Value)
                {
                    triggerGameObjects.Add(gameObject);
                    gameObject.Trigger(new HashSet <GameObject> {
                        childrenGameObject
                    });
                }
            }
            childrenGameObject.Trigger(triggerGameObjects);
            //Trigger End

            //Collide
            if (resultDistance < e.distance)
            {
                childrenGameObject.Collide(new CollisionEventArgs(collisionDirection, CollisionGameObjects));
                if (CollisionGameObjects != null)
                {
                    foreach (var gameObject in CollisionGameObjects)
                    {
                        gameObject.Collide(new CollisionEventArgs((Direction)(((int)collisionDirection + 4) % 8), new HashSet <GameObject> {
                            childrenGameObject
                        }));
                    }
                }

                //Check Bouncable
                //检查是否可反弹
                if (childrenGameObject.Bouncable)
                {
                    double bounceAngle;
                    switch (collisionDirection)
                    {
                    case Direction.Left:
                    case Direction.Right: bounceAngle = Math.PI - e.angle; break;

                    case Direction.Up:
                    case Direction.Down: bounceAngle = -e.angle; break;

                    default: bounceAngle = Math.PI + e.angle; break;
                    }
                    childrenGameObject.Move(new MoveEventArgs(bounceAngle, e.distance - resultDistance));
                    childrenGameObject.Velocity = new Vector(bounceAngle, childrenGameObject.Velocity.length);
                }
                else
                {
                    if (childrenGameObject.Velocity.length > 0)
                    {
                        childrenGameObject.Velocity = new Vector(e.angle, 0);
                    }
                }
                //Check Bouncable End
            }
            //Collide End
        }
Ejemplo n.º 26
0
 public Divider(XYPosition initPos, int radius) : base(initPos, radius)
 {
 }
Ejemplo n.º 27
0
 public static int GridToCellY(XYPosition pos)                  //求坐标所在的格子的y坐标
 {
     return(pos.y / Constant.numOfGridPerCell);
 }
Ejemplo n.º 28
0
 public void ResetPosition(XYPosition pos)
 {
     Position = pos;
 }