public void CheckAndApplyUnitCollision(PhysicalUnit other)
        {
            if (!Collides)
            {
                return;     //don't check collision if unit shouldn't collide
            }
            //special shattered collision detection
            if (_lifeState == LifeState.Shattered)
            {
                tempRec.Width  = _hitRect.Width / ICE_DIVISIONS;
                tempRec.Height = _hitRect.Height / ICE_DIVISIONS;
                for (int i = 0; i < ICE_DIVISIONS; i++)
                {
                    for (int j = 0; j < ICE_DIVISIONS; j++)
                    {
                        tempRec.X = (int)(_fragments[i, j].Position.X - tempRec.Width / 2);
                        tempRec.Y = (int)(_fragments[i, j].Position.Y - tempRec.Height / 2);
                        if (tempRec.Intersects(other.HitRect))
                        {
                            Vector2 fVel  = _fragments[i, j].Velocity;
                            float   fMass = (float)Mass / (ICE_DIVISIONS * ICE_DIVISIONS);
                            temp            = other.Velocity;
                            other._velocity = (other._velocity * (other.Mass - fMass) + 2 * fMass * fVel) /
                                              (fMass + other.Mass);
                            _fragments[i, j].Velocity = (fVel * (fMass - other.Mass) + 2 * other.Mass * temp) /
                                                        (fMass + other.Mass);
                        }
                    }
                }
                return; //ignore normal collision detection
            }

            //check if fire should be transferred
            float dist = XnaHelper.DistanceBetweenRects(HitRect, other.HitRect);

            if (dist < FIRE_SPREAD_DISTANCE)
            {
                if (_statusEffects.Fire > other._statusEffects.Fire)
                {
                    StatEffect transfer = new StatEffect()
                    {
                        Fire = FIRE_SPREAD_FACTOR * dist / FIRE_SPREAD_DISTANCE * _statusEffects.Fire
                    };
                    other.ApplyStatus(transfer);
                    ApplyStatus(transfer * -FIRE_SPREAD_LOSS);
                }
            }

            if (XnaHelper.RectsCollide(HitRect, other.HitRect))
            {
                temp = other._velocity; //temp is a static reusable vector

                other._velocity = (other._velocity * (other.Mass - this.Mass) + 2 * this.Mass * this._velocity) /
                                  (this.Mass + other.Mass);
                this._velocity = (this._velocity * (this.Mass - other.Mass) + 2 * other.Mass * temp) /
                                 (this.Mass + other.Mass);
            }
        }
예제 #2
0
파일: HookShot.cs 프로젝트: rcorre/MSH-win8
 public override void CheckAndApplyCollision(PhysicalUnit unit, TimeSpan time)
 {
     if (_hookState == HookState.Fired || _hookState == HookState.Retracting)
     {
         if (XnaHelper.RectsCollide(_hookHitRect, unit.HitRect))
         {
             _hookedUnit = unit;
             _hookState  = HookState.Attached;
         }
     }
 }