Ejemplo n.º 1
0
        private void applyTo(Character Interactor, Entity Interactee)
        {
            double dx = Interactor.GetBoundingRectangle().X - Interactee.GetBoundingRectangle().X;
            double dy = Interactor.GetY() - Interactee.GetY();
            double yVel = ((Character)Interactor).YVel;
            double xVel = ((Character)Interactor).XVel;

            double interactorAngle = Math.Atan2(yVel, xVel);
            double minimumReboundVelocity = 0.75;
            double friction = Engine.MarioControl ? 0.8 : 0.75;

            ///
            /// The collision mechanism will detect which side the collision has occurred on
            /// by inferring that the axis with least distance between centres of objects will
            /// therefore have been the first to collide. We then split each axis into the two
            /// cases of the cardinal direction of approach, again inferred from the difference
            /// in centres. Then, we apply a velocity and acceleration in the opposite direction
            /// of that of the collision. We ensure that multiple collisions occuring in the same
            /// interaction queue do not repeatedly flip the velocities and accelerations (i.e. by
            /// repearatedly multiplying by -1) by using a ternary to ensure that the resultant direction
            /// will always be opposite of the incoming collision direction. As the collisions are
            /// proportional to the speed of the colliding entities, we need to make sure we have a
            /// minimum possible ejection speed to avoid an entity appearing to be trapped in a collision
            /// with very low speed.
            ///
            /// Note also that in collisions between two characters, we apply the same collision to
            /// both interactor and interactee. The asture reader will note this will apply the collision
            /// ejection vectors twice to each character, which will nullify the apparent relative velocity
            /// being twice as high as that of a vs. static collision.
            ///

            if (Math.Abs(dx) > Math.Abs(dy))
            {

                Interactor.YVel *= friction; //Friction

                if (dx > 0)
                {
                    Interactor.PosX -= Math.Min(xVel, -minimumReboundVelocity);
                    Interactor.XVel *= 0.3 * (Interactor.XAcc < 0 ? -1 : 1);
                    Interactor.XAcc *= 0.3 * (this.Interactor.XAcc < 0 ? -1 : 1); //bounce a little
                }
                else
                {
                    Interactor.PosX -= Math.Max(xVel, minimumReboundVelocity);
                    Interactor.XVel *= 0.3 * (Interactor.XAcc > 0 ? -1 : 1);
                    Interactor.XAcc *= 0.3 * (this.Interactor.XAcc > 0 ? -1 : 1); ; //bounce a little
                }
                if (SoundEffects.sounds["hurt"].State == SoundState.Stopped && Interactor is Player && Interactor.XVel >0.5)
                {
                    SoundEffects.sounds["hurt"].Volume = 0.75f;
                    // soundInstance.IsLooped = False;
                    SoundEffects.sounds["hurt"].Play();
                }
            }
            else
            {

                Interactor.XVel *= friction; //Apply a small friction coefficient

                if (dy > 0)
                {
                    Interactor.PosY -= Math.Min(yVel, -minimumReboundVelocity);
                    Interactor.YVel *= 0.3 * (Interactor.YVel > 0 ? -1 : 1);
                    Interactor.YAcc = 0.3 * Interactor.YAcc * (Interactor.YAcc < 0 ? -1 : 1); //bounce a little
                }
                else
                {
                    Interactor.PosY -= yVel;
                    Interactor.YVel = 0;
                    Interactor.YAcc = 0.3 * Interactor.YAcc * (Interactor.YAcc > 0 ? -1 : 1); //bounce a little
                    Interactor.Jumping = false;
                }

            }
        }