예제 #1
0
        public void Update(float deltaTime)
        {
            if (GameMain.Client != null)
            {
                if (memPos.Count == 0)
                {
                    return;
                }

                Vector2 newVelocity = Body.LinearVelocity;
                Vector2 newPosition = Body.SimPosition;

                Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition);
                Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition);
                newVelocity = newVelocity.ClampLength(100.0f);
                if (!MathUtils.IsValid(newVelocity))
                {
                    return;
                }

                List <Submarine> subsToMove = submarine.GetConnectedSubs();
                foreach (Submarine dockedSub in subsToMove)
                {
                    if (dockedSub == submarine)
                    {
                        continue;
                    }
                    //clear the position buffer of the docked subs to prevent unnecessary position corrections
                    dockedSub.SubBody.memPos.Clear();
                }

                Submarine closestSub = null;
                if (Character.Controlled == null)
                {
                    closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter);
                }
                else
                {
                    closestSub = Character.Controlled.Submarine;
                }

                bool displace = moveAmount.Length() > 100.0f;
                foreach (Submarine sub in subsToMove)
                {
                    sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);
                    sub.PhysicsBody.LinearVelocity = newVelocity;

                    if (displace)
                    {
                        sub.SubBody.DisplaceCharacters(moveAmount);
                    }
                }

                if (closestSub != null && subsToMove.Contains(closestSub))
                {
                    GameMain.GameScreen.Cam.Position += moveAmount;
                    if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero)
                    {
                        GameMain.GameScreen.Cam.TargetPos += moveAmount;
                    }

                    if (Character.Controlled != null)
                    {
                        Character.Controlled.CursorPosition += moveAmount;
                    }
                }

                return;
            }

            //if outside left or right edge of the level
            if (Position.X < 0 || Position.X > Level.Loaded.Size.X)
            {
                Rectangle worldBorders = Borders;
                worldBorders.Location += MathUtils.ToPoint(Position);

                //push the sub back below the upper "barrier" of the level
                if (worldBorders.Y > Level.Loaded.Size.Y)
                {
                    Body.LinearVelocity = new Vector2(
                        Body.LinearVelocity.X,
                        Math.Min(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.Size.Y - worldBorders.Y)));
                }
                else if (worldBorders.Y - worldBorders.Height < Level.Loaded.BottomPos)
                {
                    Body.LinearVelocity = new Vector2(
                        Body.LinearVelocity.X,
                        Math.Max(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.BottomPos - (worldBorders.Y - worldBorders.Height))));
                }
            }

            //-------------------------

            Vector2 totalForce = CalculateBuoyancy();

            if (Body.LinearVelocity.LengthSquared() > 0.000001f)
            {
                float dragCoefficient = 0.01f;

                float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length();
                float drag        = speedLength * speedLength * dragCoefficient * Body.Mass;

                totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag;
            }

            ApplyForce(totalForce);

            UpdateDepthDamage(deltaTime);
        }