コード例 #1
0
        static IEnumerator receive(byte[] data)
        {
            yield return(LSUtility.WaitRealTime(UnityEngine.Random.Range(Latency, Latency + Jitter)));

            receivedBytes.AddRange(data);
            yield break;
        }
コード例 #2
0
        static IEnumerator send(byte[] data)
        {
            yield return(LSUtility.WaitRealTime(UnityEngine.Random.Range(Latency, Latency + Jitter)));

            ClientManager.HandleFrameData(data);
            yield break;
        }
コード例 #3
0
        public static void Setup()
        {
            IAgentDataProvider database;

            if (LSDatabaseManager.TryGetDatabase <IAgentDataProvider> (out database))
            {
                AgentData = database.AgentData;

                //AgentInterfacer[] agentInters = (LSDatabaseManager.CurrentDatabase as DefaultLSDatabase).AgentData;
                AgentCodes = new string[AgentData.Length];

                CachedAgents = new Dictionary <string, FastStack <LSAgent> > (AgentData.Length);

                OrganizerObject = LSUtility.CreateEmpty().transform;
                OrganizerObject.gameObject.name = "OrganizerObject";
                OrganizerObject.gameObject.SetActive(false);

                GameObject.DontDestroyOnLoad(OrganizerObject);
                for (int i = 0; i < AgentData.Length; i++)
                {
                    IAgentData interfacer = AgentData [i];
                    string     agentCode  = interfacer.Name;
                    AgentCodes [i] = agentCode;

                    CachedAgents.Add(agentCode, new FastStack <LSAgent> (2));
                    CodeInterfacerMap.Add(agentCode, interfacer);
                    CodeIndexMap.Add(agentCode, (ushort)i);
                }
            }
            else
            {
                Debug.Log("Database does no provide AgentData. Make sure it implements IAgentDataProvider.");
            }
        }
コード例 #4
0
        internal static void Initialize(GameManager gameManager)
        {
            MainGameManager = gameManager;

            if (!Loaded)
            {
                Setup();
                Loaded = true;
            }

            InitializeHelpers();


            DefaultMessageRaiser.EarlyInitialize();
            SimulationTimer.Stop();
            SimulationTimer.Reset();
            SimulationTimer.Start();
            LSDatabaseManager.Initialize();
            LSUtility.Initialize(1);
            InfluenceCount = 0;
            Time.timeScale = 1f;
            Stalled        = true;

            FrameCount          = 0;
            InfluenceFrameCount = 0;

            ClientManager.Initialize(MainGameManager.MainNetworkHelper);

            TriggerManager.Initialize();

            GridManager.Initialize();

            TeamManager.Initialize();

            CoroutineManager.Initialize();
            FrameManager.Initialize();

            CommandManager.Initialize();

            AgentController.Initialize();
            TeamManager.LateInitialize();

            PhysicsManager.Initialize();
            PlayerManager.Initialize();
            SelectionManager.Initialize();
            InfluenceManager.Initialize();
            ProjectileManager.Initialize();

            DefaultMessageRaiser.LateInitialize();

            BehaviourHelperManager.LateInitialize();
            if (onInitialize != null)
            {
                onInitialize();
            }
        }
コード例 #5
0
        public static void Initialize(GameManager gameManager)
        {
            MainGameManager = gameManager;
            Managers        = gameManager.Managers;

            if (!Loaded)
            {
                Setup();
                Loaded = true;
            }


            SimulationTimer.Reset();
            SimulationTimer.Start();
            LSDatabaseManager.Initialize();
            LSUtility.Initialize(1);
            Interfacing.Initialize();
            InfluenceCount = 0;
            Time.timeScale = 1f;
            Stalled        = true;

            FrameCount          = 0;
            InfluenceFrameCount = 0;

            GridManager.Generate();
            GridManager.Initialize();

            TeamManager.Initialize();

            CoroutineManager.Initialize();
            FrameManager.Initialize();

            CommandManager.Initialize();
            BehaviourHelper.GlobalInitialize();

            AgentController.Initialize();
            TeamManager.LateInitialize();

            PhysicsManager.Initialize();
            PlayerManager.Initialize();
            SelectionManager.Initialize();
            InfluenceManager.Initialize();
            ProjectileManager.Initialize();

            foreach (LSManager manager in Managers)
            {
                manager.Initialize();
            }

            LoadSceneObjects();

            Started = true;
            ClientManager.Initialize();
        }
コード例 #6
0
        public static int GetStateHash()
        {
            int hash = LSUtility.PeekRandom(int.MaxValue);

            hash += 1;
            hash ^= AgentController.GetStateHash();
            hash += 1;
            hash ^= ProjectileManager.GetStateHash();
            hash += 1;
            return(hash);
        }
コード例 #7
0
        internal static void Initialize(ILockstepEventsHandler[] helpers, NetworkHelper networkHelper)
        {
            PlayRate = FixedMath.One;
            //PauseCount = 0;

            if (!Loaded)
            {
                Setup();
                Loaded = true;
            }



            DefaultMessageRaiser.EarlyInitialize();

            LSDatabaseManager.Initialize();
            LSUtility.Initialize(1);
            InfluenceCount = 0;
            Time.timeScale = 1f;

            Stalled = true;

            FrameCount          = 0;
            InfluenceFrameCount = 0;
            MainNetworkHelper   = networkHelper;
            AgentController.Initialize();
            ClientManager.Initialize(MainNetworkHelper);

            BehaviourHelperManager.Initialize(helpers);

            GridManager.Initialize();


            CoroutineManager.Initialize();
            FrameManager.Initialize();

            CommandManager.Initialize();


            PhysicsManager.Initialize();
            PlayerManager.Initialize();
            SelectionManager.Initialize();
            InfluenceManager.Initialize();
            ProjectileManager.Initialize();

            DefaultMessageRaiser.LateInitialize();
            BehaviourHelperManager.LateInitialize();
            if (onInitialize != null)
            {
                onInitialize();
            }
        }
コード例 #8
0
 protected override void OnInitialize()
 {
     basePriority     = Agent.Body.Priority;
     searchCount      = LSUtility.GetRandom(SearchRate) + 1;
     attackCount      = 0;
     HasTarget        = false;
     Target           = null;
     isAttackMoving   = false;
     inRange          = false;
     isFocused        = false;
     CycleCount       = 0;
     this.Destination = Vector2d.zero;
 }
コード例 #9
0
 private bool _Remove(int hashCode)
 {
     if (ForceStop)
     {
         return(false);
     }
     if (ConfirmSlot(hashCode))
     {
         LSUtility.SetBitFalse(ref bucketAllocation [bigIndex], smallIndex);
         return(true);
     }
     return(_Remove(hashCode * CollisionResolver));
 }
コード例 #10
0
 static IEnumerator Tick()
 {
     while (true)
     {
         if (IsSimulating && LockstepManager.GameStarted)
         {
             bufferBytes.FastClear();
             bufferBytes.AddRange(BitConverter.GetBytes(InfluenceFrameCount));
             InfluenceFrameCount++;
             bufferBytes.AddRange(receivedBytes);
             receivedBytes.FastClear();
             Send(bufferBytes.ToArray());
         }
         yield return(LSUtility.WaitRealTime(LockstepManager.BaseDeltaTime * LockstepManager.InfluenceResolution));
     }
 }
コード例 #11
0
        public static Vector2d GenerateRandomPointOnCircle(bool evenDistribution = false)
        {
            long angle    = LSUtility.GetRandomOne().Mul(FixedMath.TwoPi);
            long distance = LSUtility.GetRandomOne();

            if (evenDistribution)
            {
                distance = FixedMath.Sqrt(distance);
            }

            Vector2d randomOffset = new Vector2d(
                FixedMath.Trig.Cos(angle),
                FixedMath.Trig.Sin(angle)
                ) * distance;

            return(randomOffset);
        }
コード例 #12
0
        public static void Initialize()
        {
            Time.fixedDeltaTime = FixedMath.ToFloat(Timestep);
            FrameCount          = 0;
            LSUtility.Initialize(1);
            CoroutineManager.Initialize();

            NetworkManager.Initialize();
            FrameManager.Initialize();
            AgentController.Initialize(Instance.AgentObjects);
            PhysicsManager.Initialize();
            InputManager.Initialize();
            PlayerManager.Initialize();

            MovementGroup.Initialize();

            Initialized = true;
        }
コード例 #13
0
        protected override void OnInitialize()
        {
            basePriority     = Agent.Body.Priority;
            searchCount      = LSUtility.GetRandom(SearchRate) + 1;
            attackCount      = 0;
            Target           = null;
            IsAttackMoving   = false;
            inRange          = false;
            isFocused        = false;
            CycleCount       = 0;
            this.Destination = Vector2d.zero;
            repathTimer.Reset(repathInterval);
            repathRandom = LSUtility.GetRandom(repathInterval);

            //caching parameters
            var spawnVersion = Agent.SpawnVersion;
            var controller   = Agent.Controller;

            CachedOnHit = (target) => OnHit(target, spawnVersion, controller);
        }
コード例 #14
0
        public static int GetStateHash()
        {
            int operationToggle = 0;
            int hash            = LSUtility.PeekRandom(int.MaxValue);

            for (int i = 0; i < PeakGlobalID; i++)
            {
                if (GlobalAgentActive [i])
                {
                    LSAgent agent = GlobalAgents [i];
                    int     n1    = agent.Body._position.GetStateHash() + agent.Body._rotation.GetStateHash();
                    switch (operationToggle)
                    {
                    case 0:
                        hash ^= n1;
                        break;

                    case 1:
                        hash += n1;
                        break;

                    default:
                        hash ^= n1 * 3;
                        break;
                    }
                    operationToggle++;
                    if (operationToggle >= 2)
                    {
                        operationToggle = 0;
                    }
                    if (agent.Body.IsNotNull())
                    {
                        hash ^= agent.Body._position.GetStateHash();
                        hash ^= agent.Body._position.GetStateHash();
                    }
                }
            }


            return(hash);
        }
コード例 #15
0
 private bool _Add(int hashCode, TValue item)
 {
     if (ForceStop)
     {
         return(false);
     }
     GenerateIndexes(hashCode);
     if (bucketAllocation [bigIndex].GetBitTrue(smallIndex))
     {
         if (bucketHashes [leIndex] == hashCode)
         {
             return(false);
         }
         //Resolve collision
         return(_Add(hashCode * CollisionResolver, item));
     }
     LSUtility.SetBitTrue(ref bucketAllocation [bigIndex], smallIndex);
     bucketValues [leIndex] = item;
     bucketHashes [leIndex] = hashCode;
     return(true);
 }
コード例 #16
0
        public void DistributeCollision()
        {
            if (!Active)
            {
                return;
            }

            if (IsColliding)
            {
                if (Body1.OnContact != null)
                {
                    Body1.OnContact(Body2);
                }
                if (Body2.OnContact != null)
                {
                    Body2.OnContact(Body1);
                }

                if (DoPhysics)
                {
                    switch (LeCollisionType)
                    {
                    case CollisionType.Circle_Circle:
                        DistX = Body1.Position.x - Body2.Position.x;
                        DistY = Body1.Position.y - Body2.Position.y;
                        dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                        if (dist == 0)
                        {
                            Body1.Position.x     += (LSUtility.GetRandom(1 << (FixedMath.SHIFT_AMOUNT - 2)) + 1);
                            Body1.Position.y     -= (LSUtility.GetRandom(1 << (FixedMath.SHIFT_AMOUNT - 2)) + 1);
                            Body1.PositionChanged = true;
                            return;
                        }

                        depth = (Body1.Radius + Body2.Radius - dist);

                        if (depth < 0)
                        {
                            return;
                        }

                        DistX = (DistX * depth / dist);
                        DistY = (DistY * depth / dist);

                        //Resolving collision
                        if (Body1.Immovable)
                        {
                            Body2.Position.x -= DistX;
                            Body2.Position.y -= DistY;

                            Body2.PositionChanged = true;
                        }
                        else if (Body2.Immovable)
                        {
                            Body1.Position.x     += DistX;
                            Body1.Position.y     += DistY;
                            Body1.PositionChanged = true;
                        }
                        else
                        {
                            DistX /= 4;
                            DistY /= 4;
                            if (Body1.Velocity.Dot(Body2.Velocity.x, Body2.Velocity.y) < 0)
                            {
                                if (Body1.Mover != null)
                                {
                                    Body1.Velocity.x     += DistX;
                                    Body1.Velocity.y     += DistY;
                                    Body1.VelocityChanged = true;
                                }
                                else
                                {
                                    Body1.Position.x     += DistX;
                                    Body1.Position.y     += DistY;
                                    Body1.PositionChanged = true;
                                }
                                if (Body2.Mover != null)
                                {
                                    Body2.Velocity.x     -= DistX;
                                    Body2.Velocity.y     -= DistY;
                                    Body2.VelocityChanged = true;
                                }
                                else
                                {
                                    Body2.Position.x     -= DistX;
                                    Body2.Position.y     -= DistY;
                                    Body2.PositionChanged = true;
                                }
                            }
                            else
                            {
                                Body1.Position.x     += DistX;
                                Body1.Position.y     += DistY;
                                Body1.PositionChanged = true;
                                Body2.Position.x     -= DistX;
                                Body2.Position.y     -= DistY;
                                Body2.PositionChanged = true;
                            }
                        }
                        break;

                    case CollisionType.Circle_AABox:
                        if (Body1.Shape == ColliderType.AABox)
                        {
                            DistributeCircle_Box(Body1, Body2);
                        }
                        else
                        {
                            DistributeCircle_Box(Body2, Body1);
                        }
                        break;

                    case CollisionType.Circle_Polygon:

                        break;
                    }
                }
            }
        }
コード例 #17
0
 static RingController()
 {
     ringTemplate = LSUtility.ResourceLoadGO("SelectionRing");
 }
コード例 #18
0
        private void DistributeCollision()
        {
            if (Body1.OnContact.IsNotNull())
            {
                Body1.OnContact(Body2);
            }
            if (Body2.OnContact.IsNotNull())
            {
                Body2.OnContact(Body1);
            }

            if (DoPhysics && Body1.HasParent == false && Body2.HasParent == false)
            {
                switch (LeCollisionType)
                {
                case CollisionType.Circle_Circle:
                    DistX = Body1.Position.x - Body2.Position.x;
                    DistY = Body1.Position.y - Body2.Position.y;
                    dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                    if (dist == 0)
                    {
                        const int randomMax = 1000;
                        Body1.Position.x     += LSUtility.GetRandom(randomMax);
                        Body1.Position.y     += LSUtility.GetRandom(randomMax);
                        Body1.PositionChanged = true;
                        Body2.Position.x     += LSUtility.GetRandom(randomMax);
                        Body2.Position.y     += LSUtility.GetRandom(randomMax);
                        Body2.PositionChanged = true;
                        return;
                    }


                    depth = (Body1.Radius + Body2.Radius - dist);

                    if (depth <= 0)
                    {
                        return;
                    }
                    DistX = (DistX * depth / dist) / 2L;
                    DistY = (DistY * depth / dist) / 2L;

                    const bool applyVelocity = true;
                    //Resolving collision
                    if (Body1.Immovable || (Body2.Immovable == false && Body1.Priority > Body2.Priority))
                    {
                        Body2.Position.x     -= DistX;
                        Body2.Position.y     -= DistY;
                        Body2.PositionChanged = true;
                        if (applyVelocity)
                        {
                            Body2._velocity.x    -= DistX;
                            Body2._velocity.y    -= DistY;
                            Body2.VelocityChanged = true;
                        }
                    }
                    else if (Body2.Immovable || Body2.Priority > Body1.Priority)
                    {
                        Body1.Position.x     += DistX;
                        Body1.Position.y     += DistY;
                        Body1.PositionChanged = true;
                        if (applyVelocity)
                        {
                            Body1._velocity.x    += DistX;
                            Body1._velocity.y    += DistY;
                            Body1.VelocityChanged = true;
                        }
                    }
                    else
                    {
                        DistX /= 2;
                        DistY /= 2;

                        Body1.Position.x += DistX;
                        Body1.Position.y += DistY;
                        Body2.Position.x -= DistX;
                        Body2.Position.y -= DistY;

                        Body1.PositionChanged = true;
                        Body2.PositionChanged = true;
                        if (applyVelocity)
                        {
                            DistX                /= 8;
                            DistY                /= 8;
                            Body1._velocity.x    += DistX;
                            Body1._velocity.y    += DistY;
                            Body1.VelocityChanged = true;

                            Body2._velocity.x    -= DistX;
                            Body2._velocity.y    -= DistY;
                            Body2.VelocityChanged = true;
                        }
                    }
                    break;

                case CollisionType.Circle_AABox:
                    if (Body1.Shape == ColliderType.AABox)
                    {
                        DistributeCircle_Box(Body1, Body2);
                    }
                    else
                    {
                        DistributeCircle_Box(Body2, Body1);
                    }
                    break;

                case CollisionType.Circle_Polygon:

                    break;
                }
            }
        }
コード例 #19
0
        private void DistributeCollision()
        {
            if (!DoPhysics)
            {
                return;
            }

            switch (LeCollisionType)
            {
            case CollisionType.Circle_Circle:
                DistX = Body1._position.x - Body2._position.x;
                DistY = Body1._position.y - Body2._position.y;
                dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                if (dist == 0)
                {
                    //If objects are on the same position, give them push in random direction
                    const long randomMax = FixedMath.One / 32;
                    Body1._position.x    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body1._position.y    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body1.PositionChanged = true;
                    Body2._position.x    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body2._position.y    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body2.PositionChanged = true;
                    return;
                }


                depth = (Body1.Radius + Body2.Radius - dist);

                if (depth <= 0)
                {
                    return;
                }
                DistX = (DistX * depth / dist);
                DistY = (DistY * depth / dist);

                //Resolving collision


                if (Body1.Immovable || (Body2.Immovable == false && Body1.Priority > Body2.Priority))
                {
                    DistX *= -1;
                    DistY *= -1;
                    DistributeCircle_CirclePriority(Body1, Body2);
                }
                else if (Body2.Immovable || Body2.Priority > Body1.Priority)
                {
                    DistributeCircle_CirclePriority(Body2, Body1);
                }
                else
                {
                    DistX /= 2;
                    DistY /= 2;
                    DistributeCircle(Body1);
                    DistX *= -1;
                    DistY *= -1;
                    DistributeCircle(Body2);
                }
                break;

            case CollisionType.Circle_AABox:
                if (Body1.Shape == ColliderType.AABox)
                {
                    DistributeCircle_Box(Body1, Body2);
                }
                else
                {
                    DistributeCircle_Box(Body2, Body1);
                }
                break;

            case CollisionType.Circle_Polygon:
                if (Body1.Shape == ColliderType.Circle)
                {
                    this.DistributeCircle_Poly(Body1, Body2);
                }
                else
                {
                    this.DistributeCircle_Poly(Body2, Body1);
                }
                break;
            }
        }
コード例 #20
0
        private void DistributeCollision()
        {
            if (Body1.OnContact.IsNotNull())
            {
                Body1.OnContact(Body2);
            }
            if (Body2.OnContact.IsNotNull())
            {
                Body2.OnContact(Body1);
            }

            if (Body1.IsTrigger || Body2.IsTrigger)
            {
                return;
            }

            switch (LeCollisionType)
            {
            case CollisionType.Circle_Circle:
                DistX = Body1._position.x - Body2._position.x;
                DistY = Body1._position.y - Body2._position.y;
                dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                if (dist == 0)
                {
                    const int randomMax = (int)((long)int.MaxValue % (FixedMath.One / 64));
                    Body1._position.x    += LSUtility.GetRandom(randomMax) - randomMax / 2;
                    Body1._position.y    += LSUtility.GetRandom(randomMax) - randomMax / 2;
                    Body1.PositionChanged = true;
                    Body2._position.x    += LSUtility.GetRandom(randomMax) - randomMax / 2;
                    Body2._position.y    += LSUtility.GetRandom(randomMax) - randomMax / 2;
                    Body2.PositionChanged = true;
                    return;
                }


                depth = (Body1.Radius + Body2.Radius - dist);

                if (depth <= 0)
                {
                    return;
                }
                DistX = (DistX * depth / dist) / 2L;
                DistY = (DistY * depth / dist) / 2L;

                const bool applyVelocity = false;
                //Resolving collision
                if (Body1.Immovable && Body1.isActiveAndEnabled || (Body2.Immovable == false && Body1.Priority > Body2.Priority))
                {
                    Body2._position.x    -= DistX;
                    Body2._position.y    -= DistY;
                    Body2.PositionChanged = true;
                    if (applyVelocity)
                    {
                        Body2._velocity.x    -= DistX;
                        Body2.VelocityChanged = true;
                    }
                }
                else if (Body2.Immovable || Body2.Priority > Body1.Priority)
                {
                    Body1._position.x    += DistX;
                    Body1._position.y    += DistY;
                    Body1.PositionChanged = true;
                    if (applyVelocity)
                    {
                        Body1._velocity.x    += DistX;
                        Body1._velocity.y    += DistY;
                        Body1.VelocityChanged = true;
                    }
                }
                else
                {
                    DistX /= 2;
                    DistY /= 2;

                    Body1._position.x += DistX;
                    Body1._position.y += DistY;
                    Body2._position.x -= DistX;
                    Body2._position.y -= DistY;

                    Body1.PositionChanged = true;
                    Body2.PositionChanged = true;
                    if (applyVelocity)
                    {
                        DistX                /= 8;
                        DistY                /= 8;
                        Body1._velocity.x    += DistX;
                        Body1._velocity.y    += DistY;
                        Body1.VelocityChanged = true;

                        Body2._velocity.x    -= DistX;
                        Body2._velocity.y    -= DistY;
                        Body2.VelocityChanged = true;
                    }
                }
                break;

            case CollisionType.Circle_AABox:
                if (Body1.Shape == ColliderType.AABox)
                {
                    DistributeCircle_Box(Body1, Body2);
                }
                else
                {
                    DistributeCircle_Box(Body2, Body1);
                }
                break;

            case CollisionType.Circle_Polygon:
                if (Body1.Shape == ColliderType.Circle)
                {
                    this.DistributeCircle_Poly(Body1, Body2);
                }
                else
                {
                    this.DistributeCircle_Poly(Body2, Body1);
                }
                break;
            }
        }
コード例 #21
0
        private void DistributeCollision()
        {
            if (!DoPhysics)
            {
                return;
            }

            switch (LeCollisionType)
            {
            case CollisionType.Circle_Circle:
                DistX = Body1._position.x - Body2._position.x;
                DistY = Body1._position.y - Body2._position.y;
                dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                if (dist == 0)
                {
                    //If objects are on the same position, give them push in random direction
                    const long randomMax = FixedMath.One / 32;
                    Body1._position.x    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body1._position.y    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body1.PositionChanged = true;
                    Body2._position.x    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body2._position.y    += LSUtility.GetRandomLong(randomMax) - randomMax / 2;
                    Body2.PositionChanged = true;
                    return;
                }


                depth = (Body1.Radius + Body2.Radius - dist);

                if (depth <= 0)
                {
                    return;
                }
                DistX = (DistX * depth / dist) / 2L;
                DistY = (DistY * depth / dist) / 2L;

                //Switch, used to be const
                bool applyVelocity = false;

                //Resolving collision
                //TODO: Less copy-paste code
                if (Body1.Immovable || (Body2.Immovable == false && Body1.Priority > Body2.Priority))
                {
                    DistX *= -1;
                    DistY *= -1;

                    if (Body1.Immovable || Body2.ImmovableCollisionDirection.EqualsZero())
                    {
                        Body2._position.x                += DistX;
                        Body2._position.y                += DistY;
                        Body2.PositionChanged             = true;
                        Body2.ImmovableCollisionDirection = new Vector2d(DistX, DistY);
                        if (applyVelocity)
                        {
                            Body2._velocity.x    += DistX;
                            Body2._velocity.y    += DistY;
                            Body2.VelocityChanged = true;
                        }
                    }
                    else
                    {
                        //Only move if there isn't an immovable object in that direction
                        if (Body2.ImmovableCollisionDirection.x.Sign() != DistX.Sign())
                        {
                            Body1._position.x += DistX;
                        }
                        if (Body2.ImmovableCollisionDirection.y.Sign() != DistY.Sign())
                        {
                            Body1._position.y += DistY;
                        }
                    }
                }

                else if (Body2.Immovable || Body2.Priority > Body1.Priority)
                {
                    if (Body2.Immovable || Body1.ImmovableCollisionDirection.EqualsZero())
                    {
                        Body2.ImmovableCollisionDirection = new Vector2d(DistX, DistY);

                        Body1._position.x    += DistX;
                        Body1._position.y    += DistY;
                        Body1.PositionChanged = true;
                        if (applyVelocity)
                        {
                            Body1._velocity.x    += DistX;
                            Body1._velocity.y    += DistY;
                            Body1.VelocityChanged = true;
                        }
                    }
                    else
                    {
                        //Only move if there isn't an immovable object in that direction
                        if (Body1.ImmovableCollisionDirection.x.Sign() != DistX.Sign())
                        {
                            Body2._position.x += DistX;
                        }
                        if (Body1.ImmovableCollisionDirection.y.Sign() != DistY.Sign())
                        {
                            Body2._position.y += DistY;
                        }
                    }
                }

                else
                {
                    DistX /= 2;
                    DistY /= 2;

                    Body1._position.x += DistX;
                    Body1._position.y += DistY;
                    Body2._position.x -= DistX;
                    Body2._position.y -= DistY;

                    Body1.PositionChanged = true;
                    Body2.PositionChanged = true;
                    if (applyVelocity)
                    {
                        DistX                /= 8;
                        DistY                /= 8;
                        Body1._velocity.x    += DistX;
                        Body1._velocity.y    += DistY;
                        Body1.VelocityChanged = true;

                        Body2._velocity.x    -= DistX;
                        Body2._velocity.y    -= DistY;
                        Body2.VelocityChanged = true;
                    }
                }
                break;

            case CollisionType.Circle_AABox:
                if (Body1.Shape == ColliderType.AABox)
                {
                    DistributeCircle_Box(Body1, Body2);
                }
                else
                {
                    DistributeCircle_Box(Body2, Body1);
                }
                break;

            case CollisionType.Circle_Polygon:
                if (Body1.Shape == ColliderType.Circle)
                {
                    this.DistributeCircle_Poly(Body1, Body2);
                }
                else
                {
                    this.DistributeCircle_Poly(Body2, Body1);
                }
                break;
            }
        }
コード例 #22
0
        private void DistributeCollision()
        {
            if (Body1.OnContact != null)
            {
                Body1.OnContact(Body2);
            }
            if (Body2.OnContact != null)
            {
                Body2.OnContact(Body1);
            }

            if (DoPhysics && Body1.HasParent == false && Body2.HasParent == false)
            {
                switch (LeCollisionType)
                {
                case CollisionType.Circle_Circle:
                    DistX = Body1.Position.x - Body2.Position.x;
                    DistY = Body1.Position.y - Body2.Position.y;
                    dist  = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT);

                    if (dist == 0)
                    {
                        Body1.Position.x += (LSUtility.GetRandom(1 << (FixedMath.SHIFT_AMOUNT - 2)) + 1);
                        Body1.Position.y -= (LSUtility.GetRandom(1 << (FixedMath.SHIFT_AMOUNT - 2)) + 1);
                        return;
                    }

                    depth = (Body1.Radius + Body2.Radius - dist);

                    if (depth < 0)
                    {
                        return;
                    }

                    DistX = (DistX * depth / dist);
                    DistY = (DistY * depth / dist);

                    //Resolving collision
                    if (physicsFavor == PhysicsFavor.Favor1)
                    {
                        Body2.Position.x     -= DistX;
                        Body2.Position.y     -= DistY;
                        Body2.PositionChanged = true;
                    }
                    else if (physicsFavor == PhysicsFavor.Favor2)
                    {
                        Body1.Position.x     += DistX;
                        Body1.Position.y     += DistY;
                        Body1.PositionChanged = true;
                    }
                    else
                    {
                        DistX /= 4;
                        DistY /= 4;
                        if (Body1.Velocity.Dot(Body2.Velocity.x, Body2.Velocity.y) <= 0)
                        {
                            Body1.Velocity.x     += DistX;                        //FixedMath.Mul(DistX, Body1.VelocityMagnitude);
                            Body1.Velocity.y     += DistY;                        //FixedMath.Mul(DistY, Body1.VelocityMagnitude);
                            Body1.VelocityChanged = true;

                            Body2.Velocity.x     -= DistX;                        //FixedMath.Mul(DistX, Body2.VelocityMagnitude);
                            Body2.Velocity.y     -= DistY;                        //FixedMath.Mul(DistY, Body2.VelocityMagnitude);
                            Body2.VelocityChanged = true;

                            Body1.Position.x += DistX;
                            Body1.Position.y += DistY;
                            Body2.Position.x -= DistX;
                            Body2.Position.y -= DistY;
                        }
                        else
                        {
                            Body1.Position.x += DistX;
                            Body1.Position.y += DistY;
                            Body2.Position.x -= DistX;
                            Body2.Position.y -= DistY;
                        }
                        Body1.PositionChanged = true;
                        Body2.PositionChanged = true;
                    }
                    break;

                case CollisionType.Circle_AABox:
                    if (Body1.Shape == ColliderType.AABox)
                    {
                        DistributeCircle_Box(Body1, Body2);
                    }
                    else
                    {
                        DistributeCircle_Box(Body2, Body1);
                    }
                    break;

                case CollisionType.Circle_Polygon:

                    break;
                }
            }
        }