/// <summary>
        /// Advance the current position some distance on the flight path.
        /// </summary>
        /// <param name="distance"></param>
        /// <param name="destination">position after the advance</param>
        /// <param name="cCfinalDirection">direction of the segment that the position is on after the advance</param>
        internal void Advance(CCPoint currentPosition, float distance, out CCPoint destination, out float CCfinalDirection)
        {
            int   currentIndex = (int)AdvancementAsQuasiIndex;
            float relativeAdvancementToNextPoint = AdvancementAsQuasiIndex % 1;

            if (currentIndex == Path.Length - 1)  // if you've already reached the end you're done
            {
                destination      = EndPoint;
                CCfinalDirection = DirectionAt(currentIndex);
                return;
            }
            float absoluteAdvancementToNextPoint = relativeAdvancementToNextPoint * CCPoint.Distance(Path[currentIndex], Path[currentIndex + 1]);
            float directionToNextPointInRadians  = Constants.CCDegreesToMathRadians(DirectionAt(currentIndex));
            float absoluteXAdvancement           = absoluteAdvancementToNextPoint * (float)Math.Cos(directionToNextPointInRadians);
            float absoluteYAdvancement           = absoluteAdvancementToNextPoint * (float)Math.Sin(directionToNextPointInRadians);
            //CCPoint currentPosition = new CCPoint(Path[currentIndex].X + absoluteXAdvancement, Path[currentIndex].Y + absoluteYAdvancement);
            // try to advance from the current position to the next point on the Path
            float distanceToNextPoint = CCPoint.Distance(currentPosition, Path[currentIndex + 1]);

            while (distanceToNextPoint < distance)
            {
                currentIndex            = currentIndex + 1;
                currentPosition         = Path[currentIndex];
                distance               -= distanceToNextPoint;
                AdvancementAsQuasiIndex = currentIndex;
                if (currentIndex == Path.Length - 1)
                {
                    break;
                }
                distanceToNextPoint = CCPoint.Distance(currentPosition, Path[currentIndex + 1]);
            }
            // if you can't go far enough just move towards the point
            if (distance > 0 && currentIndex != Path.Length - 1)
            {
                // update the direction
                directionToNextPointInRadians = Constants.CCDegreesToMathRadians(DirectionAt(currentIndex));
                // calculate how far you can go
                // relative between the points
                float relativeAdvanche = distance / distanceToNextPoint;
                // in x direction
                float newX = currentPosition.X + distance * (float)Math.Cos(directionToNextPointInRadians);
                // in y direction
                float newY = currentPosition.Y + distance * (float)Math.Sin(directionToNextPointInRadians);
                AdvancementAsQuasiIndex = (float)currentIndex + relativeAdvanche;
                destination             = new CCPoint(newX, newY);
                CCfinalDirection        = Constants.RadiansToCCDegrees(directionToNextPointInRadians);
            }
            else
            {
                destination      = Path[currentIndex];
                CCfinalDirection = DirectionAt(currentIndex);
            }
            //
        }
        /// <summary>
        /// Advance the life cycles of all clouds and possibly add a new cloud.
        /// Rotate the given angle by 45° before creating clouds.
        /// </summary>
        /// <param name="dt">how far to advance the lifecycle</param>
        /// <param name="currentPosition">the position at which to add a possible new cloud</param>
        /// <param name="decayOnly">if true, no new clouds are added (i.e. this just advances the cloud life cycles)</param>
        internal override void Advance(float dt, CCPoint currentPosition, float currentCCRotation, bool decayOnly = false)
        {
            // advance the lifecycle of each cloud
            foreach (var cloud in clouds)
            {
                cloud.LifeTime += dt;
                cloud.MatchLifeCycle();
            }
            CCPoint pos;

            if (AddRing)   // add a special ring cloud, only one
            {
                pos     = CCPoint.RotateByAngle(RelativePosition, CCPoint.Zero, Constants.CCDegreesToMathRadians(currentCCRotation));
                pos    += currentPosition;
                AddRing = false;
                clouds.Add(new RingCloud(pos, 0, CCColor4B.White, DrawLow, 100f, 1f));
            }
            // check if it is time for a new cloud
            float timePlusDt = TimeSinceLastCloud + dt;

            if (AutoAddClouds && timePlusDt > CloudDelay)
            {
                // reset the timer to 0 + overshoot
                TimeSinceLastCloud = timePlusDt % CloudDelay;
                // add a new cloud
                if (!decayOnly)
                {
                    // calculate the total position based on the saved relative position, the currentPosition and the current CCrotation
                    pos  = CCPoint.RotateByAngle(RelativePosition, CCPoint.Zero, Constants.CCDegreesToMathRadians(currentCCRotation));
                    pos += currentPosition;
                    // move the spawn of the cloud a little in a random direction for a nice little bonus effect
                    // also make the cloud size a bit random
                    var cloud = new Cloud(Constants.RandomPointNear(pos, ReferenceSize), currentCCRotation + 45f, CloudColor, DrawLow, ReferenceSize + (float)(new Random()).NextDouble() * ReferenceSize * 2, CloudLifeTime);
                    //var cloud = new DamageCloud(Constants.RandomPointNear(pos, ReferenceSize), currentCCRotation+45f, CloudColor, ReferenceSize + (float)(new Random()).NextDouble() * ReferenceSize, CloudLifeTime);
                    //cloud.FireColor = FireColor;
                    clouds.Add(cloud);
                }
            }
            else
            {
                // let the timer run
                TimeSinceLastCloud = timePlusDt;
            }
            // remove all clouds that have gone beyond their lifecycle
            for (int i = 0; i < clouds.Count; i++)
            {
                if (clouds[i].LifeTime > clouds[i].TotalLifeTime)
                {
                    clouds.RemoveAt(i--);
                }
            }
        }
Exemplo n.º 3
0
        internal void AddSquadron(Squadron squadron, CCPoint position, float CCdirection)
        {
            squadron.Leader.Position = position;
            squadron.Leader.RotateTo(CCdirection);
            // rotate all formation positions correctly around the leader and set everyone to their positions
            float angle = Constants.CCDegreesToMathRadians(CCdirection);

            foreach (var entry in squadron.AircraftsWithRelPositions)
            {
                var formationPoint = CCPoint.RotateByAngle(entry.Value, CCPoint.Zero, angle);
                entry.Key.Position = position + formationPoint;
                entry.Key.RotateTo(CCdirection);
                AddAircraft(entry.Key);
            }
            squadron.GenerateWayPoint();
            Squadrons.Add(squadron);
        }
Exemplo n.º 4
0
        internal void ReactToHit(float damage, CCPoint collisionPos)
        {
            const float MAX_DISTANCE_FROM_COLLISION = 200f;
            float       maxDistanceFromCollision    = ((ContentSize.Width + ContentSize.Height) / 4) * GetTotalScale();

            if (maxDistanceFromCollision > MAX_DISTANCE_FROM_COLLISION)
            {
                maxDistanceFromCollision = MAX_DISTANCE_FROM_COLLISION;
            }
            // generate a random point near the collisionPos
            // and show an effect there
            Random rng = new Random();

            for (int tries = 0; tries < 5; tries++)
            {
                CCPoint randomPoint = Constants.RandomPointNear(collisionPos, maxDistanceFromCollision, rng);
                //CCPoint randomPoint = collisionPos;
                if (Collisions.CollidePositionPolygon(randomPoint, this) || tries == 4)   // check whether the random point is inside the collision polygon
                {
                    CCPoint relativePosition = randomPoint - PositionWorldspace;
                    relativePosition = CCPoint.RotateByAngle(relativePosition, CCPoint.Zero, -Constants.CCDegreesToMathRadians(TotalRotation));
                    // react differently depending upon how damaged you now are
                    float refSize    = DamageToReferenceSize(damage);
                    var   damageTail = new DamageCloudTailNode(refSize, relativePosition);
                    if (Aircraft.SelectedPower != PowerUp.PowerType.SHIELD)
                    {
                        if (Health / MaxHealth > 0.7f)
                        {
                            damageTail.AutoAddClouds = false;
                        }
                        if (Health / MaxHealth < 0.5f)
                        {
                            var planeColor     = ((PlayLayer)Layer).CurrentPlaneColor;
                            var baseFlameColor = new CCColor4B((byte)rng.Next(0, 256), 0, 0);
                            var h = (new SKColor(planeColor.R, planeColor.G, planeColor.B)).Hue;
                            damageTail.CloudColor = Constants.MoveHue(baseFlameColor, h);
                        }
                        damageTail.CloudLifeTime += (refSize - 8f) * 0.1f;
                    }
                    else
                    {
                        damageTail.AutoAddClouds = false;
                    }
                    DamageCloudTailNodes.Add(damageTail);
                    break;
                }
            }
            // shake!
            if (Aircraft.ControlledByPlayer && Aircraft.SelectedPower != PowerUp.PowerType.SHIELD)
            {
                // the shake amount depends on the damage, but mostly on how the damage relates to the max health
                float baseRefSize  = DamageToReferenceSize(damage, 10f);
                float specialBonus = 0f;
                float healthFactor = damage / MaxHealth;
                if (healthFactor > 1)
                {
                    healthFactor = 1;
                }
                if (Health <= 0)
                {
                    baseRefSize  *= (1 + TotalParts.Count()) * 0.8f;
                    specialBonus += (float)Math.Sqrt(TotalMaxHealth) * 3;
                }
                float shakeAmount = baseRefSize * 10 * healthFactor + specialBonus;
                ((PlayLayer)Layer).AddScreenShake(shakeAmount, shakeAmount);
            }
        }
 private float AircraftVelocityBoost()
 {
     return MyPart.Aircraft.VelocityVector.Length * (float)Math.Cos(Constants.CCDegreesToMathRadians(Constants.AngleFromToDeg(MyPart.TotalRotation, MyPart.Aircraft.TotalRotation)));
 }