コード例 #1
0
        public void Initialise()
        {
            if (PhysicsEntity == null)
            {
                if (PhysicsMeshType == PhysicsMeshType.box)
                {
                    GenerateBoxCollider();
                }
                if (PhysicsMeshType == PhysicsMeshType.sphere)
                {
                    GenerateSphereCollider();
                }

                if (!movable)
                {
                    PhysicsEntity.BecomeKinematic();
                }
            }

            PhysicsEntity.Tag = ParentObject;
            PhysicsEntity.CollisionInformation.Tag = ParentObject;

            if (!SystemCore.PhysicsOnBackgroundThread)
            {
                PhysicsEntity.WorldTransform =
                    MonoMathHelper.GenerateBepuMatrixFromMono(ParentObject.Transform.AbsoluteTransform);
                SystemCore.PhysicsSimulation.Add(PhysicsEntity);
            }
            else
            {
                PhysicsEntity.BufferedStates.States.WorldTransform =
                    MonoMathHelper.GenerateBepuMatrixFromMono(ParentObject.Transform.AbsoluteTransform);
                SystemCore.PhysicsSimulation.SpaceObjectBuffer.Add(PhysicsEntity);
            }
        }
コード例 #2
0
ファイル: JointVehicleMotor.cs プロジェクト: MoTo1496/Voxalia
 public JointVehicleMotor(PhysicsEntity e1, PhysicsEntity e2, Location dir, bool isSteering)
 {
     Ent1       = e1;
     Ent2       = e2;
     Direction  = dir;
     IsSteering = isSteering;
 }
コード例 #3
0
 public JointPullPush(PhysicsEntity e1, PhysicsEntity e2, Location axis, bool mode)
 {
     Ent1 = e1;
     Ent2 = e2;
     Axis = axis;
     Mode = mode;
 }
コード例 #4
0
 public JointSwivelHinge(PhysicsEntity e1, PhysicsEntity e2, Location hinge, Location twist)
 {
     Ent1       = e1;
     Ent2       = e2;
     WorldHinge = hinge;
     WorldTwist = twist;
 }
コード例 #5
0
    public void Awake()
    {
        PhysicsEntity pe = new PhysicsEntity(initialSpeed);

        pe.initialSpeed          += new float3(0, UnityEngine.Random.Range(-rand, rand), UnityEngine.Random.Range(-rand, rand));
        pba.InitialLinearVelocity = pe.initialSpeed;
    }
コード例 #6
0
        /// <inheritdoc />
        protected override void EntityInteract(PhysicsEntity entity, Vector3i position, uint data)
        {
            Decode(data, out BlockColor color, out int height);
            var next = (BlockColor)((int)color + 1);

            entity.World.SetBlock(this.AsInstance(Encode(next, height)), position);
        }
コード例 #7
0
ファイル: Region.cs プロジェクト: BlackCoyote/Voxalia
 /// <summary>
 /// Spawns an entity in the world.
 /// </summary>
 /// <param name="e">The entity to spawn.</param>
 public void SpawnEntity(Entity e)
 {
     Entities.Add(e);
     if (e.Ticks)
     {
         Tickers.Add(e);
     }
     if (e.CastShadows)
     {
         ShadowCasters.Add(e);
     }
     if (e is PhysicsEntity)
     {
         PhysicsEntity pe = e as PhysicsEntity;
         pe.SpawnBody();
         if (pe.GenBlockShadows)
         {
             // TODO: Effic?
             PhysicsEntity[] neo = new PhysicsEntity[GenShadowCasters.Length + 1];
             Array.Copy(GenShadowCasters, neo, GenShadowCasters.Length);
             neo[neo.Length - 1] = pe;
             GenShadowCasters    = neo;
             Chunk ch = TheClient.TheRegion.GetChunk(TheClient.TheRegion.ChunkLocFor(e.GetPosition()));
             if (ch != null)
             {
                 ch.CreateVBO(); // TODO: nearby / all affected chunks!
             }
         }
     }
     else if (e is PrimitiveEntity)
     {
         ((PrimitiveEntity)e).Spawn();
     }
 }
コード例 #8
0
        /// <summary>
        /// Updates pose for our entity. We override default implementation
        /// since we control our own rendering when no file mesh is supplied, which means
        /// we dont need world transform updates
        /// </summary>
        /// <param name="update"></param>
        public override void Update(FrameUpdate update)
        {
            float leftFront  = _leftFrontWheel.Wheel.AxleSpeed + _leftFrontTargetVelocity;
            float rightFront = _rightFrontWheel.Wheel.AxleSpeed + _rightFrontTargetVelocity;
            float leftRear   = _leftRearWheel.Wheel.AxleSpeed + _leftRearTargetVelocity;
            float rightRear  = _rightRearWheel.Wheel.AxleSpeed + _rightRearTargetVelocity;

            float timeStep = (float)update.ElapsedTime;

            ModulateWheelSpeed(leftFront, _leftFrontWheel, timeStep);
            ModulateWheelSpeed(rightFront, _rightFrontWheel, timeStep);
            ModulateWheelSpeed(leftRear, _leftRearWheel, timeStep);
            ModulateWheelSpeed(rightRear, _rightRearWheel, timeStep);

            // update state for us and all the shapes that make up the rigid body
            PhysicsEntity.UpdateState(true);

            // update entities in fields
            _leftFrontWheel.Update(update);
            _rightFrontWheel.Update(update);
            _leftRearWheel.Update(update);
            _rightRearWheel.Update(update);

            // sim engine will update children
            base.Update(update);
        }
コード例 #9
0
ファイル: PhysicsWorld.cs プロジェクト: zacx-z/BoundBox
    private void SendCollisionMessage(Vector3 normal, PhysicsEntity obj, PhysicsEntity other)
    {
        var collisionInfo = new CollisionInfo(obj, other, normal);

        obj.SendMessage("OnCollide", collisionInfo, SendMessageOptions.DontRequireReceiver);
        other.SendMessage("OnCollide", collisionInfo.GetOtherInfo(), SendMessageOptions.DontRequireReceiver);
    }
コード例 #10
0
ファイル: Region.cs プロジェクト: BlackCoyote/Voxalia
 Location SkyMod(Location pos, Location norm, float light)
 {
     if (light > 0 && TheClient.CVars.r_treeshadows.ValueB)
     {
         BoundingBox bb = new BoundingBox(pos.ToBVector(), (pos + new Location(1, 1, 300)).ToBVector());
         if (GenShadowCasters != null)
         {
             for (int i = 0; i < GenShadowCasters.Length; i++) // TODO: Accelerate somehow! This is too slow!
             {
                 PhysicsEntity pe = GenShadowCasters[i];
                 if (pe.GenBlockShadows && pe.ShadowCenter.DistanceSquared_Flat(pos) < pe.ShadowRadiusSquaredXY)
                 {
                     light -= 0.05f;
                     if (pe.ShadowMainDupe.Intersects(bb))
                     {
                         light = 0;
                         break;
                     }
                     if (pe.ShadowCastShape.Intersects(bb))
                     {
                         light -= 0.1f;
                     }
                     if (light <= 0)
                     {
                         light = 0;
                         break;
                     }
                 }
             }
         }
     }
     return(Math.Max(norm.Dot(SunLightPathNegative), 0.5) * new Location(light) * SkyLightMod);
 }
コード例 #11
0
ファイル: OpenHandItem.cs プロジェクト: BlackCoyote/Voxalia
        public override void Click(Entity entity, ItemStack item)
        {
            if (!(entity is PlayerEntity))
            {
                // TODO: non-player support
                return;
            }
            PlayerEntity    player = (PlayerEntity)entity;
            Location        end    = player.ItemSource() + player.ItemDir * 5;
            CollisionResult cr     = player.TheRegion.Collision.CuboidLineTrace(new Location(0.1, 0.1, 0.1), player.GetEyePosition(), end, player.IgnoreThis);

            if (cr.Hit && cr.HitEnt != null)
            {
                // TODO: handle static world impact
                PhysicsEntity pe = (PhysicsEntity)cr.HitEnt.Tag;
                if (pe.GetMass() > 0 && pe.GetMass() < 200)
                {
                    Grab(player, pe, cr.Position);
                }
                else
                {
                    // If (HandHold) { Grab(player, pe, cr.Position); }
                }
            }
        }
コード例 #12
0
        private void KeepAttitude()
        {
            pidControllerAttitudeX.Control(globalRotation.X, ref attitude_dx);
            pidControllerAttitudeZ.Control(globalRotation.Z, ref attitude_dz);

            PhysicsEntity.ApplyTorque(new Vector3(attitude_dx, 0.0f, attitude_dz), false);
        }
コード例 #13
0
        /// <summary>
        /// Reset the values, the position, rotation etc.
        /// </summary>
        public void Reset()
        {
            // Reset the raw values
            raw_thrust = 0.0f;
            raw_yaw    = 0.0f;
            raw_pitch  = 0.0f;
            raw_roll   = 0.0f;

            //keepHeight = false;
            //autoHover = false;
            attitude_dx = 0.0f;
            attitude_dz = 0.0f;
            pidControllerAltitude.Reset();
            pidControllerAttitudeX.Reset();
            pidControllerAttitudeZ.Reset();

            // Reset rotation and position
            Rotation = new xna.Vector3();
            Position = TypeConversion.ToXNA(initialPos);

            // Reset the linear and the angular velocity
            PhysicsEntity.SetAngularVelocity(new Vector3());
            PhysicsEntity.SetLinearVelocity(new Vector3());

            // Reset the camera to the initial view
            cameraView.EyePosition = MulticopterSimulationService.INITIAL_CAMERA_EYEPOS;
            cameraView.LookAtPoint = MulticopterSimulationService.INITIAL_CAMERA_LOOKAT;
            SimulationEngine.GlobalInstancePort.Update(cameraView);
        }
コード例 #14
0
ファイル: JointTwist.cs プロジェクト: MoTo1496/Voxalia
 public JointTwist(PhysicsEntity e1, PhysicsEntity e2, Location a1, Location a2)
 {
     Ent1    = e1;
     Ent2    = e2;
     AxisOne = a1;
     AxisTwo = a2;
 }
コード例 #15
0
ファイル: GamePlay.cs プロジェクト: DioMuller/defend-uranus
        /// <summary>
        /// Creates a new GamePlay based on the user setup.
        /// </summary>
        /// <param name="game">Current game.</param>
        /// <param name="setup">Setup configuration.</param>
        public GamePlay(MainGame game, GamePlaySetup.Result setup)
            : base(game)
        {
            const int guiHMargin = 10;
            var       guiSize    = new Point(100, 160);

            var p1Ship = new Ship(this, setup.Player1Selection)
            {
                Position = new Vector2(-100, 0)
            };
            var p2Ship = new Ship(this, setup.Player2Selection)
            {
                Position = new Vector2(100, 0)
            };

            p1Ship.Behaviors.Add(new ShipInputBehavior(PlayerIndex.One, p1Ship));
            p2Ship.Behaviors.Add(new ShipInputBehavior(PlayerIndex.Two, p2Ship));

            _baseEntity = new PhysicsEntity();
            _ships      = new List <Ship> {
                p1Ship, p2Ship
            };
            _entities           = new List <GamePlayEntity>(_ships);
            _nonPhysicsEntities = new List <Entity>();
            _duration           = TimeSpan.Zero;

            _spawnAsteroids = new AsyncOperation(SpawnAsteroids);

            _p1Gui = new PlayerGUI("Player 1", p1Ship, new Point(guiHMargin, 0), guiSize);
            _p2Gui = new PlayerGUI("Player 2", p2Ship, new Point(GraphicsDevice.Viewport.Width - guiSize.X - guiHMargin, 0), guiSize);
        }
コード例 #16
0
ファイル: ManipulatorItem.cs プロジェクト: MoTo1496/Voxalia
        public override void Click(Entity entity, ItemStack item)
        {
            if (!(entity is PlayerEntity))
            {
                return; // TODO: non-player support?
            }
            PlayerEntity player = (PlayerEntity)entity;

            if (player.Manipulator_Grabbed != null)
            {
                return;
            }
            Location        eye = player.ItemSource();
            CollisionResult cr  = player.TheRegion.Collision.RayTrace(eye, eye + player.ItemDir * 50, player.IgnoreThis);

            if (!cr.Hit || cr.HitEnt == null || cr.HitEnt.Mass <= 0)
            {
                return;
            }
            PhysicsEntity target = (PhysicsEntity)cr.HitEnt.Tag;

            player.Manipulator_Grabbed  = target;
            player.Manipulator_Distance = (double)(eye - target.GetPosition()).Length();
            player.Manipulator_Beam     = new ConnectorBeam()
            {
                type = BeamType.MULTICURVE
            };
            player.Manipulator_Beam.One   = player;
            player.Manipulator_Beam.Two   = target;
            player.Manipulator_Beam.color = Colors.BLUE;
            player.TheRegion.AddJoint(player.Manipulator_Beam);
        }
コード例 #17
0
        public override void Click(Entity entity, ItemStack item)
        {
            if (!(entity is CharacterEntity))
            {
                // TODO: Non-character support?
                return;
            }
            CharacterEntity character = (CharacterEntity)entity;
            double          range     = RangeBase * item.GetAttributeF("range_mod", 1f);
            double          strength  = StrengthBase * item.GetAttributeF("strength_mod", 1f) * GetStrength();
            Location        start     = character.GetEyePosition(); // TODO: ItemPosition?
            Location        forw      = character.ForwardVector();
            Location        mid       = start + forw * range;
            // TODO: base the pull on extent of the entity rather than its center. IE, if the side of a big ent is targeted, it should be rotated by the force.
            List <Entity> ents = character.TheRegion.GetEntitiesInRadius(mid, range);

            foreach (Entity ent in ents)
            {
                if (ent is PhysicsEntity) // TODO: Support for primitive ents?
                {
                    PhysicsEntity pent   = (PhysicsEntity)ent;
                    Location      rel    = (start - ent.GetPosition());
                    double        distsq = rel.LengthSquared();
                    if (distsq < 1)
                    {
                        distsq = 1;
                    }
                    pent.ApplyForce((rel / distsq) * strength);
                }
            }
        }
コード例 #18
0
        private void applyPhysics(PhysicsEntity entity, float elapsedTime)
        {
            //Update gravity if required
            if ((entity.Mass != 0f) && (entity.IsOnGround == false))
            {
                entity.Velocity += Gravity * entity.Mass;
            }

            Vector2 friction = entity.IsOnGround ? groundFriction : airFriction;

            // Apply air or ground friction
            if (entity.Velocity.X > 0)
            {
                entity.Flip      = SpriteEffects.None;
                entity.Velocity -= new Vector2(friction.X * elapsedTime, 0);
                if (entity.Velocity.X < 0f)
                {
                    entity.Velocity = new Vector2(0f, entity.Velocity.Y);
                }
            }

            if (entity.Velocity.X < 0)
            {
                entity.Flip      = SpriteEffects.FlipHorizontally;
                entity.Velocity += new Vector2(friction.X * elapsedTime, 0);
                if (entity.Velocity.X > 0f)
                {
                    entity.Velocity = new Vector2(0f, entity.Velocity.Y);
                }
            }

            if (entity.Velocity.Y > 0)
            {
                entity.Velocity -= new Vector2(0f, friction.Y * elapsedTime);
                if (entity.Velocity.Y < 0f)
                {
                    entity.Velocity = new Vector2(entity.Velocity.X, 0f);
                }
            }

            if (entity.Velocity.Y < 0)
            {
                entity.Velocity += new Vector2(0f, friction.Y * elapsedTime);
                if (entity.Velocity.Y > 0f)
                {
                    entity.Velocity = new Vector2(entity.Velocity.X, 0f);
                }
            }

            // Keep velocity in [-speed, speed]
            if (entity.Speed.X != 0f)
            {
                entity.Velocity = new Vector2(MathHelper.Clamp(entity.Velocity.X, -entity.Speed.X, entity.Speed.X), entity.Velocity.Y);
            }

            if (entity.Speed.Y != 0f)
            {
                entity.Velocity = new Vector2(entity.Velocity.X, MathHelper.Clamp(entity.Velocity.Y, -entity.Speed.Y, entity.Speed.Y));
            }
        }
コード例 #19
0
ファイル: Physics.cs プロジェクト: masums/libTech
 static void SpawnPhysicsEntity(PhysicsEntity E)
 {
     if (E.Body != null)
     {
         PhysWorld.AddRigidBody(E.Body);
     }
 }
コード例 #20
0
ファイル: OpenHandItem.cs プロジェクト: BlackCoyote/Voxalia
        public void Grab(PlayerEntity player, PhysicsEntity pe, Location hit)
        {
            AltClick(player, null);
            JointBallSocket jbs = new JointBallSocket(player.CursorMarker, pe, hit);

            player.TheRegion.AddJoint(jbs);
            player.GrabJoint = jbs;
        }
コード例 #21
0
 public JointDistance(PhysicsEntity e1, PhysicsEntity e2, float min, float max, Location e1pos, Location e2pos)
 {
     Ent1    = e1;
     Ent2    = e2;
     Min     = min;
     Max     = max;
     Ent1Pos = e1pos;
     Ent2Pos = e2pos;
 }
コード例 #22
0
ファイル: JointDistance.cs プロジェクト: Fortifier42/Voxalia
 public JointDistance(PhysicsEntity e1, PhysicsEntity e2, double min, double max, Location e1pos, Location e2pos)
 {
     Ent1    = e1;
     Ent2    = e2;
     Min     = min;
     Max     = max;
     Ent1Pos = e1pos - e1.GetPosition();
     Ent2Pos = e2pos - e2.GetPosition();
 }
コード例 #23
0
 public PhysicsComponent(Entity physicsEntity, bool movable, bool simulated)
 {
     Enabled            = true;
     Simulated          = simulated;
     this.PhysicsEntity = physicsEntity;
     if (!movable)
     {
         PhysicsEntity.BecomeKinematic();
     }
 }
コード例 #24
0
ファイル: GridPoint.cs プロジェクト: joeywodarski/Electric
 public void collide(PhysicsEntity entity)
 {
     //pull the grid
     float distance = Vector3.SqrMagnitude(entity.transform.position - position);
     if (distance <= entity.ringRadius * entity.ringRadius)
     {
         //get pulled!
         position = Vector3.Lerp(position, entity.transform.position, (entity.mass * Mathf.Abs(entity.charge) / 125000f));
     }
 }
コード例 #25
0
 public JointLAxisLimit(PhysicsEntity e1, PhysicsEntity e2, double min, double max, Location cpos1, Location cpos2, Location axis)
 {
     Ent1  = e1;
     Ent2  = e2;
     Min   = min;
     Max   = max;
     CPos1 = cpos1;
     CPos2 = cpos2;
     Axis  = axis;
 }
コード例 #26
0
        /// <summary>
        /// Apply the velocity to make the entity move
        /// </summary>
        /// <param name="ent"></param>
        /// <param name="step"></param>
        private void applyVelocity(PhysicsEntity entity, float elapsedTime)
        {
            //Update location
            if ((entity.Velocity.X != 0 || entity.Velocity.Y != 0) || (entity.MovingFloorMovement.X != 0 || entity.MovingFloorMovement.Y != 0))
            {
                var deltaMove = new Vector2(entity.Velocity.X * elapsedTime, entity.Velocity.Y * elapsedTime);

                entity.Location += deltaMove + entity.MovingFloorMovement;
            }
        }
コード例 #27
0
        public override bool ParseBytesAndExecute(byte[] data)
        {
            if (data.Length != 24 + 24 + 16 + 24 + 1 + 8)
            {
                SysConsole.Output(OutputType.WARNING, "Invalid physentupdtpacket: invalid length!");
                return(false);
            }
            Location pos = Location.FromDoubleBytes(data, 0);
            Location vel = Location.FromDoubleBytes(data, 24);

            BEPUutilities.Quaternion ang = Utilities.BytesToQuaternion(data, 24 + 24);
            Location angvel = Location.FromDoubleBytes(data, 24 + 24 + 16);
            bool     active = (data[24 + 24 + 16 + 24] & 1) == 1;
            long     eID    = Utilities.BytesToLong(Utilities.BytesPartial(data, 24 + 24 + 16 + 24 + 1, 8));

            for (int i = 0; i < TheClient.TheRegion.Entities.Count; i++)
            {
                if (TheClient.TheRegion.Entities[i] is PhysicsEntity)
                {
                    PhysicsEntity e = (PhysicsEntity)TheClient.TheRegion.Entities[i];
                    if (e.EID == eID)
                    {
                        if (e is ModelEntity && ((ModelEntity)e).PlanePilot == TheClient.Player)
                        {
                            float lerp = TheClient.CVars.n_ourvehiclelerp.ValueF;
                            e.SetPosition(e.GetPosition() + (pos - e.GetPosition()) * lerp);
                            e.SetVelocity(e.GetVelocity() + (vel - e.GetVelocity()) * lerp);
                            e.SetAngularVelocity(e.GetAngularVelocity() + (angvel - e.GetAngularVelocity()) * lerp);
                            e.SetOrientation(BEPUutilities.Quaternion.Slerp(e.GetOrientation(), ang, lerp));
                        }
                        else
                        {
                            e.SetPosition(pos);
                            e.SetVelocity(vel);
                            e.SetOrientation(ang);
                            e.SetAngularVelocity(angvel);
                        }
                        if (e.Body != null && e.Body.ActivityInformation != null && e.Body.ActivityInformation.IsActive && !active) // TODO: Why are the first two checks needed?
                        {
                            if (e.Body.ActivityInformation.SimulationIsland != null)                                                // TODO: Why is this needed?
                            {
                                e.Body.ActivityInformation.SimulationIsland.IsActive = false;
                            }
                        }
                        else if (e.Body != null && e.Body.ActivityInformation != null && !e.Body.ActivityInformation.IsActive && active) // TODO: Why are the first two checks needed?
                        {
                            e.Body.ActivityInformation.Activate();
                        }
                        return(true);
                    }
                }
            }
            TheClient.Network.SendPacket(new PleaseRedefinePacketOut(eID));
            return(true);
        }
コード例 #28
0
ファイル: PhysicsWorld.cs プロジェクト: zacx-z/BoundBox
 public void Remove(PhysicsEntity obj)
 {
     if (!obj.immovable)
     {
         dynList.Remove(obj);
     }
     else
     {
         stcList.Remove(obj);
     }
 }
コード例 #29
0
    // public float delete_speed;

    // Use this for initialization
    void Start()
    {
        MaxHealth          = 20f;
        CurrentHealth      = MaxHealth;
        healthbar.value    = CalculateHealth();
        m_physicsEntity    = GetComponent <PhysicsEntity>();
        m_rb               = GetComponent <Rigidbody>();
        text_Speed.text    = movement.ToString();
        text_Distance.text = Vector3.Distance(transformA.position, transformB.position).ToString();
        text_Winner.text   = "";
    }
コード例 #30
0
        /// <inheritdoc />
        protected override void EntityInteract(PhysicsEntity entity, Vector3i position, uint data)
        {
            uint height = data & 0b00_1111;

            height++;

            if (height <= IHeightVariable.MaximumHeight)
            {
                entity.World.SetBlock(this.AsInstance(height), position);
            }
        }
コード例 #31
0
 void GeneratePhysicsEntity()
 {
     if (physicsEntity != null)
     {
         // This will happen if SetStartingVelocity() has been called already
         //  as this will be the second time this is being generated
         return;
     }
     // Add physics entity
     physicsEntity = new PhysicsEntity(transform, stats.height, stats.width);
 }
コード例 #32
0
    // Checks and handles collisions with other massed entities.
    public virtual void collide(PhysicsEntity entity)
    {
        float D = Vector3.SqrMagnitude(entity.transform.position - transform.position);

        if (D < (ringRadius + entity.ringRadius) * (ringRadius + entity.ringRadius))
        {
            //find the direction from your center to the other center
            Vector3 tempDirection = Vector3.Normalize(entity.transform.position - transform.position);

            //if the collision is betwen two opposite charges or a null charge
            float cDiff = Mathf.Sign(entity.charge) + Mathf.Sign(charge);
            if (cDiff <= 1 && cDiff >= -1 && charge != 0)
            {
                //attract
                velocity = ((velocity * mass) + (tempDirection * (entity.mass))) / mass;
            }
            else
            {
                //repel
                velocity = ((velocity * (mass)) - (tempDirection * (entity.mass))) / mass;
            }

            // Did bodies collide or just charge radii?
            if (D <= (radius + entity.radius)*(radius + entity.radius))
            {
                // Take mass damage.
                mass -= entity.mass/2f;

                // Create particles.

                // Check if dead.
                if (mass < 1)
                {
                    // If we die, our killer eats our mass and charge.
                    entity.mass += mass;
                    entity.charge += charge;
                    entity.charge = Mathf.Clamp(entity.charge, -80, 80);
                    explode();
                }
            }
        }
    }
コード例 #33
0
        private bool handleEntityFloorCollisions(PhysicsEntity regEnt, IEnumerable<Floor> floors)
        {
            bool collisionDetected = false;

            foreach (Floor floor in floors)
            {
                Vector2 collision;

                // Do not cross the floor
                if (Hitbox.Collide(regEnt.Hitbox, floor.Rectangle, out collision))
                {
                    float absDepthX = Math.Abs(collision.X);
                    float absDepthY = Math.Abs(collision.Y);

                    // Resolve the collision along the shallow axis.
                    if (absDepthY <= absDepthX)
                    {
                        bool floorOnTop = floor.Rectangle.Y < regEnt.Hitbox.Dimensions.Y;

                        // If we crossed the top of a tile, we are on the ground.
                        if (floorOnTop == false)
                        {
                            // Hack for passable platforms
                            if (floor.IsPassable == false)
                            {
                                regEnt.IsOnGround = true;
                            }
                            else if (regEnt.Velocity.Y >= 0)
                            {
                                regEnt.IsOnGround = true;
                            }
                        }

                        if (floor.IsPassable == false || regEnt.IsOnGround)
                        {
                            regEnt.Location = new Vector2(regEnt.Location.X, regEnt.Location.Y + collision.Y);

                            if (absDepthY != 0)
                            {
                                regEnt.Velocity = new Vector2(regEnt.Velocity.X, 0f);
                            }
                        }
                    }
                    else
                    {
                        regEnt.Location = new Vector2(regEnt.Location.X + collision.X, regEnt.Location.Y);

                        bool passable = (floor.IsPassable == true);

                        if (!passable)
                        {
                            // If going in the direction of the collision
                            if (floor.Rectangle.X > regEnt.Hitbox.Dimensions.X)
                            {
                                regEnt.IsStuckRight = true;
                            }
                            else if (floor.Rectangle.X < regEnt.Hitbox.Dimensions.X)
                            {
                                regEnt.IsStuckLeft = true;
                            }

                            if (absDepthX != 0)
                            {
                                regEnt.Velocity = new Vector2(0f, regEnt.Velocity.Y);
                            }
                        }
                    }

                    regEnt.Hitbox.UpdateBounds();

                    if (regEnt.FloorCollisionDetected != null)
                    {
                        regEnt.FloorCollisionDetected(collision);
                    }

                    if (regEnt.IsAlive == false) break;
                    collisionDetected = true;
                }
            }

            return collisionDetected;
        }
コード例 #34
0
 /// <summary>
 /// Remove an entity from the collision detection
 /// </summary>
 /// <param name="ent"></param>
 public void UnregisterEntity(PhysicsEntity ent)
 {
     _unregisteredEntities.Add(ent);
 }
コード例 #35
0
        private void applyPhysics(PhysicsEntity entity, float elapsedTime)
        {
            //Update gravity if required
            if ((entity.Mass != 0f) && (entity.IsOnGround == false))
            {
                entity.Velocity += Gravity * entity.Mass;
            }

            Vector2 friction = entity.IsOnGround ? groundFriction : airFriction;

            // Apply air or ground friction
            if (entity.Velocity.X > 0)
            {
                entity.Flip = SpriteEffects.None;
                entity.Velocity -= new Vector2(friction.X * elapsedTime, 0);
                if (entity.Velocity.X < 0f) entity.Velocity = new Vector2(0f, entity.Velocity.Y);
            }

            if (entity.Velocity.X < 0)
            {
                entity.Flip = SpriteEffects.FlipHorizontally;
                entity.Velocity += new Vector2(friction.X * elapsedTime, 0);
                if (entity.Velocity.X > 0f) entity.Velocity = new Vector2(0f, entity.Velocity.Y);
            }

            if (entity.Velocity.Y > 0)
            {
                entity.Velocity -= new Vector2(0f, friction.Y * elapsedTime);
                if (entity.Velocity.Y < 0f) entity.Velocity = new Vector2(entity.Velocity.X, 0f);
            }

            if (entity.Velocity.Y < 0)
            {
                entity.Velocity += new Vector2(0f, friction.Y * elapsedTime);
                if (entity.Velocity.Y > 0f) entity.Velocity = new Vector2(entity.Velocity.X, 0f);
            }

            // Keep velocity in [-speed, speed]
            if (entity.Speed.X != 0f)
            {
                entity.Velocity = new Vector2(MathHelper.Clamp(entity.Velocity.X, -entity.Speed.X, entity.Speed.X), entity.Velocity.Y);
            }

            if (entity.Speed.Y != 0f)
            {
                entity.Velocity = new Vector2(entity.Velocity.X, MathHelper.Clamp(entity.Velocity.Y, -entity.Speed.Y, entity.Speed.Y));
            }
        }
コード例 #36
0
        /// <summary>
        /// Apply the velocity to make the entity move
        /// </summary>
        /// <param name="ent"></param>
        /// <param name="step"></param>
        private void applyVelocity(PhysicsEntity entity, float elapsedTime)
        {
            //Update location
            if ((entity.Velocity.X != 0 || entity.Velocity.Y != 0) || (entity.MovingFloorMovement.X != 0 || entity.MovingFloorMovement.Y != 0))
            {
                var deltaMove = new Vector2(entity.Velocity.X * elapsedTime, entity.Velocity.Y * elapsedTime);

                entity.Location += deltaMove + entity.MovingFloorMovement;
            }
        }