Ejemplo n.º 1
0
        /// <summary>
        /// 计算并输出一个伤害.若只对护盾造成伤害而无法对护甲造成伤害则为0,若需要对护甲按
        /// 剩余护盾比例造成伤害则介于0~1之间 默认为0.02 若m为单位护盾值与最大护盾值得比对单位的伤害计算式为:
        /// 护盾伤害=foldShield*BasicDamage*(1-crossValue)护甲伤害=foldArmor*BasicDamage*crossValue
        /// </summary>
        /// <param name="unit">伤害的单位</param>
        /// <param name="shield">对护盾的伤害</param>
        /// <param name="armor">对护甲的伤害</param>
        public void OutDamage(VioableUnit unit, ref float shield, ref float armor)
        {
            shield = 0.0f;
            armor  = 0.0f;
            float dmg = BasicDamage * Fold;

            if (IsShieldUseless == false)
            {
                if (unit.Shield > FoldShield * dmg * (1 - CrossValue))
                {
                    shield = FoldShield * dmg * (1 - CrossValue);
                    armor  = FoldArmor * dmg * CrossValue;
                }
                else
                {
                    shield = unit.Shield;
                    if (FoldShield != 0 && CrossValue != 0 && CrossValue != 1)
                    {
                        float d = shield / FoldShield;
                        armor = (dmg - d) * FoldArmor;
                    }
                }
            }
            else
            {
                shield = 0.0f;
                armor  = dmg * FoldArmor;
            }
        }
Ejemplo n.º 2
0
 public static bool IsCollided(VioableUnit unit, BoundingSphere boundingSphere)
 {
     if (Vector3.Distance(unit.Position, boundingSphere.Center) <= GameConsts.BoundingDistance)
     {
         if (isCollided(unit.Model.TransformedMajorSphere, boundingSphere))
         {
             foreach (BoundingSphere k in unit.Model.TransformedBoundingSpheres)
             {
                 if (k != null)
                 {
                     if (isCollided(k, boundingSphere))
                     {
                         return(true);
                     }
                 }
             }
         }
     }
     return(false);
 }
Ejemplo n.º 3
0
        public static bool IsCollided(VioableUnit unit, Barrel b)
        {
            bool ins = false;

            if (b.Intersects(unit.Model.TransformedMajorSphere))
            {
                foreach (BoundingSphere k in unit.Model.TransformedBoundingSpheres)
                {
                    if (k != null)
                    {
                        if (b.Intersects(k))
                        {
                            ins = true;
                            return(ins);
                        }
                    }
                }
            }

            return(ins);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 处理弹药和单位的碰撞,返回碰撞点
        /// </summary>
        /// <param name="unit"></param>
        /// <param name="bullet"></param>
        /// <returns></returns>
        public static Vector3?IsCollided(VioableUnit unit, Bullet bullet)
        {
            if (Vector3.Distance(unit.Position, bullet.position) <= GameConsts.BoundingDistance)
            {
                if (bullet.position != bullet.positionl)
                {
                    Ray ray1;
                    Ray ray2;
                    if (bullet.weapon.isInstant == false)
                    {
                        ray1 = new Ray(bullet.positionl, Vector3.Normalize(bullet.position - bullet.positionl));
                        ray2 = new Ray(bullet.position, Vector3.Normalize(bullet.positionl - bullet.position));
                    }
                    else
                    {
                        Vector3 v1 = bullet.position;
                        Vector3 v2 = bullet.position + Vector3.Normalize(bullet.velocity) * bullet.Range;

                        ray1 = new Ray(v1, Vector3.Normalize(v2 - v1));
                        ray2 = new Ray(v2, Vector3.Normalize(v1 - v2));
                    }


                    if (unit.Model.TransformedMajorSphere.Intersects(ray1) != null && unit.Model.TransformedMajorSphere.Intersects(ray2) != null)
                    {
                        foreach (BoundingSphere k in unit.Model.TransformedBoundingSpheres)
                        {
                            if (k.Intersects(ray1) != null && k.Intersects(ray2) != null)
                            {
                                return(k.GetCollisionPoint(ray1));
                            }
                        }
                    }
                }
                return(null);
            }
            return(null);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 通过球体的碰撞检测检查出目标是否在导弹爆炸范围内
        /// </summary>
        /// <param name="unit">目标</param>
        /// <param name="missile">导弹</param>
        /// <param name="explosionRadiusFold">半径缩放倍数,在是否爆炸判断时可比1稍小</param>
        /// <returns></returns>
        public static bool IsCollided(VioableUnit unit, Missile missile, float explosionRadiusFold)
        {
            if (Vector3.Distance(unit.Position, missile.Position) <= GameConsts.BoundingDistance)
            {
                BoundingSphere b = new BoundingSphere(missile.Position, missile.missileType.explosionRadius * explosionRadiusFold);

                ContainmentType ct  = b.Contains(unit.Model.TransformedMajorSphere);
                ContainmentType ct2 = unit.Model.TransformedMajorSphere.Contains(b);
                if (ct != ContainmentType.Disjoint || ct2 != ContainmentType.Disjoint)
                {
                    foreach (BoundingSphere k in unit.Model.TransformedBoundingSpheres)
                    {
                        ContainmentType ct3 = b.Contains(k);
                        ContainmentType ct4 = k.Contains(b);
                        if (ct3 != ContainmentType.Disjoint || ct4 != ContainmentType.Disjoint)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 6
0
        public override void Update(GameTime gameTime)
        {
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            #region 更新单位

            removingUnits.Clear();

            for (int i = 0; i < units.Count; i++)
            {
                Unit u = units[i];

                if (u != null)
                {
                    u.Update(gameTime);
                    if (u.UnitState == UnitState.dead)
                    {
                        removingUnits.Add(u);//收集要被移除的单位
                    }
                }
            }


            #endregion

            #region 回收多余的单位
            foreach (Unit u in removingUnits)
            {
                if (u != null)
                {
                    units.Remove(u);
                }
            }
            #endregion

            #region 环境物

            removingDecorations.Clear();//晕,终于发现这里居然错误地写成了removingMissiles.Clear();
            foreach (Decoration d in decorations)
            {
                if (AODGameLibrary.Helpers.RandomHelper.WithinRange(d.Position, GameWorld.CurrentStage.Player.Position, GameConsts.GameViewDistance) || d.Far)
                {
                    d.Update(gameTime);
                    if (d.UnitState == UnitState.dead)
                    {
                        removingDecorations.Add(d);//收集要被移除的单位
                    }
                }
            }

            #endregion

            #region 回收多余的单位
            foreach (Decoration d in removingDecorations)
            {
                if (d != null)
                {
                    decorations.Remove(d);
                }
            }
            #endregion



            #region 更新导弹
            removingMissiles.Clear();
            foreach (Missile m in missiles)
            {
                if (m != null)
                {
                    m.Update(gameTime);
                    if (m.UnitState == UnitState.dead)
                    {
                        removingMissiles.Add(m);
                    }
                }
            }
            foreach (Missile m in removingMissiles)
            {
                if (m != null)
                {
                    missiles.Remove(m);
                }
            }
            #endregion

            #region 更新LOOT
            {
                removingLoots.Clear();
                foreach (LootItem loot in lootItems)
                {
                    if (AODGameLibrary.Helpers.RandomHelper.WithinRange(loot.Position, GameWorld.CurrentStage.Player.Position, GameConsts.GameViewDistance))
                    {
                        loot.Update(gameTime);
                        if (loot.UnitState == UnitState.dead)
                        {
                            removingLoots.Add(loot);
                        }
                    }
                }
                foreach (LootItem loot in removingLoots)
                {
                    if (loot != null)
                    {
                        lootItems.Remove(loot);
                    }
                }
                if (lootItems.Count > GameConsts.MaxLootNum)
                {
                    lootItems.Remove(lootItems[0]);
                }
            }
            #endregion

            #region 更新弹药
            removingBullets.Clear(); //终于。。不再慢了。。。
            foreach (Bullet bullet in bullets)
            {
                if (bullet != null)
                {
                    bullet.Update(gameTime);


                    if (bullet.IsDead)
                    {
                        removingBullets.Add(bullet);
                    }
                }
            }
            foreach (Bullet bullet in removingBullets)
            {
                if (bullet != null)
                {
                    bullets.Remove(bullet);
                }
            }
            #endregion

            #region 单位间碰撞检测

            VioableUnit a;
            VioableUnit b;
            for (int m = 0; m < boundingCollection.Count; m++)
            {
                a = boundingCollection[m];
                if (a.Dead)
                {
                    continue;
                }
                for (int n = m + 1; n < boundingCollection.Count; n++)
                {
                    b = boundingCollection[n];
                    if (b.Dead)
                    {
                        continue;
                    }
                    if (b != null && a != b)
                    {
                        bool ts = b.Heavy || a.Heavy;
                        if (a.Bounding && b.Bounding && (AODGameLibrary.Helpers.RandomHelper.WithinRange(a.Position, b.Position, GameConsts.BoundingDistance) || ts))
                        {
                            if (Collision.IsCollided(a, b))
                            {
                                if ((!a.Heavy && !b.Heavy) || (a.Heavy && b.Heavy && a is Unit && b is Unit))
                                {
                                    //float t = Vector3.Dot(a.Thrust, Vector3.Normalize(b.position - a.position));//推力在两单位中心线的投影
                                    //if (t > 0)
                                    //    //a.GetThrust(-1 * t * Vector3.Normalize(b.position - a.position));
                                    //    a.Thrust = Vector3.Zero;
                                    //float x = Vector3.Dot(a.velocity, Vector3.Normalize(b.position - a.position));//速度在两单位中心线的投影
                                    //if (x > 0)
                                    //    a.GetThrust(-2f * x * Vector3.Normalize(b.position - a.position) * a.mass);
                                    if (a.collided == false && b.collided == false)
                                    {
                                        if (a.Position != b.Position)
                                        {
                                            {
                                                float s1 = Vector3.Dot(a.Velocity, Vector3.Normalize(b.Position - a.Position));
                                                float s2 = Vector3.Dot(b.Velocity, Vector3.Normalize(a.Position - b.Position));
                                                if (s1 > 0)
                                                {
                                                    a.GetImpulse(-1 * Vector3.Normalize(b.Position - a.Position) * s1 * a.Mass);
                                                    a.GetImpulse(Vector3.Normalize(a.Position - b.Position) * s2 * b.Mass);
                                                }
                                            }
                                            {
                                                float s1 = Vector3.Dot(b.Velocity, Vector3.Normalize(a.Position - b.Position));
                                                float s2 = Vector3.Dot(a.Velocity, Vector3.Normalize(b.Position - a.Position));
                                                if (s1 > 0)
                                                {
                                                    b.GetImpulse(-1 * Vector3.Normalize(a.Position - b.Position) * s1 * b.Mass);
                                                    b.GetImpulse(Vector3.Normalize(b.Position - a.Position) * s2 * a.Mass);
                                                }
                                            }
                                        }
                                    }
                                    if (a.Position != b.Position)
                                    {
                                        a.GetImpulse(-1 * Vector3.Normalize(b.Position - a.Position) * a.FrictionForce * elapsedTime);
                                        b.GetImpulse(-1 * Vector3.Normalize(a.Position - b.Position) * b.FrictionForce * elapsedTime);
                                    }
                                    else
                                    {
                                        a.GetImpulse(Vector3.Left * a.FrictionForce * elapsedTime);
                                        b.GetImpulse(Vector3.Right * b.FrictionForce * elapsedTime);
                                    }
                                    a.collided = true;
                                    b.collided = true;
                                }
                                else
                                {
                                    VioableUnit l = null;
                                    VioableUnit h = null;
                                    if (a.Heavy != b.Heavy)
                                    {
                                        if (b.Heavy)
                                        {
                                            h = b;
                                            l = a;
                                        }
                                        else
                                        {
                                            h = a;
                                            l = b;
                                        }
                                    }
                                    else
                                    {
                                        if (b is Decoration && !(a is Decoration))
                                        {
                                            h = b;
                                            l = a;
                                        }
                                        if (a is Decoration && !(b is Decoration))
                                        {
                                            h = a;
                                            l = b;
                                        }
                                    }
                                    if (l != null && h != null)
                                    {
                                        if (l.Position != h.Position)
                                        {
                                            float t = Vector3.Dot(l.Thrust, Vector3.Normalize(h.Position - l.Position));//推力在两单位中心线的投影
                                            if (t > 0)
                                            {
                                                // a.GetThrust(-1 * t * Vector3.Normalize(b.position - a.position));
                                                l.Thrust = Vector3.Zero;
                                            }
                                            float x = Vector3.Dot(l.Velocity, Vector3.Normalize(h.Position - l.Position));//速度在两单位中心线的投影
                                            if (x > 0)
                                            {
                                                l.GetImpulse(-1 * x * Vector3.Normalize(h.Position - l.Position) * l.Mass);
                                            }
                                            l.GetImpulse(-1 * Vector3.Normalize(h.Position - l.Position) * l.FrictionForce * elapsedTime);
                                            //if (a.Thrust != Vector3.Zero)
                                            //    if (Collision.IsCollided(b, new Ray(a.position, Vector3.Normalize(a.Thrust))))
                                            //        a.Thrust = Vector3.Zero;
                                            //if (a.velocity != Vector3.Zero)
                                            //    if (Collision.IsCollided(b, new Ray(a.position, Vector3.Normalize(a.velocity))))
                                            //        a.velocity *= -1.1f;
                                        }
                                    }

                                    else
                                    {
                                        l.GetThrust(-1 * l.Velocity * Vector3.Forward * l.Mass / elapsedTime);
                                    }
                                }
                            }
                        }
                    }
                }
            }


            #endregion


            #region 更新位置
            foreach (Unit u in units)
            {
                if (u != null)
                {
                    u.UpdateLocation(gameTime);
                }
            }
            foreach (Decoration d in decorations)
            {
                if (AODGameLibrary.Helpers.RandomHelper.WithinRange(d.Position, GameWorld.CurrentStage.Player.Position, GameConsts.GameViewDistance) || d.Far)
                {
                    d.UpdateLocation(gameTime);
                }
            }
            foreach (Missile m in missiles)
            {
                if (m != null)
                {
                    m.UpdateLocation(gameTime);
                }
            }
            foreach (LootItem loot in lootItems)
            {
                if (AODGameLibrary.Helpers.RandomHelper.WithinRange(loot.Position, GameWorld.CurrentStage.Player.Position, GameConsts.GameViewDistance))
                {
                    loot.UpdateLocation(gameTime);
                }
            }
            for (int i = 0; i < units.Count; i++)
            {
                Unit u = units[i];
                if (u != null)
                {
                    u.UpdateWeapons(gameTime);
                }
            }
            #endregion

            base.Update(gameTime);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 将弹药和附近的单位单位做碰撞检测,对是敌方且发生碰撞的最近单位造成伤害且弹药消失
        /// </summary>
        /// <param name="unit">做碰撞检测的目标</param>
        public void CheckCollision(List <VioableUnit> units)
        {
            VioableUnit hitingUnit      = null;
            float       hitingUnitRange = 0;
            Vector3     hittingPoint    = Vector3.Zero;
            Vector3?    v1;

            foreach (VioableUnit unit in units)
            {
                if (unit != null)
                {
                    if (Vector3.Distance(unit.Position, this.position) <= GameConsts.BulletCheckingRange)
                    {
                        //if (weapon.isInstant == false)
                        //{

                        //    if (bulletOver == false)
                        //    {

                        //        if (Collision.IsCollided(unit, this) && unit.Group != Group && unit.Dead != true)
                        //        {
                        //            Damage result;
                        //            result = new Damage(weapon, num);
                        //            unit.GetDamage(result);
                        //            Hit();
                        //        }

                        //    }


                        //}
                        //else{}
                        v1 = Collision.IsCollided(unit, this);
                        if (v1 != null && unit.Group != Group && unit.UnitState != UnitState.dead)
                        {
                            if (hitingUnit != null)
                            {
                                float k = Vector3.Dot(v1.Value - this.positionl, this.Face);
                                if (k < hitingUnitRange)
                                {
                                    hitingUnitRange = k;
                                    hitingUnit      = unit;
                                    hittingPoint    = v1.Value;
                                }
                            }
                            else
                            {
                                hitingUnit      = unit;
                                hitingUnitRange = Vector3.Dot(unit.Position - this.positionl, this.Face);
                                hittingPoint    = v1.Value;
                            }
                        }
                    }
                }
            }
            if (hitingUnit != null)
            {
                Damage result;
                result = new Damage(weapon, num);
                hitingUnit.GetDamage(result);
                //position = (positionl + position) / 2;
                if (hitingUnit.Model != null && position0 != position)
                {
                    Ray     br = new Ray(position0, Vector3.Normalize(position - position0));
                    Vector3?v  = hittingPoint;
                    if (v != null)
                    {
                        position  = v.Value;
                        positionl = v.Value;
                    }
                }
                Hit();
            }
        }