Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new <see cref="UfoController"/>.
        /// </summary>
        public UfoController()
        {
            JsonObject jsonObject = MainGame.Context.Content.Load <JsonObject>("UfoScores");

            scores            = JsonConvert.DeserializeObject <int[]>(jsonObject.JsonSource);
            spaceInvadersFont = MainGame.Context.Content.Load <SpriteFont>("SpaceInvadersFont");

            timeToSpawn       = Random.Range(MinimumSpawnTime, MaximumSpawnTime);
            ufoTexture        = MainGame.Context.MainTextureAtlas["ufo"];
            BoundingRectangle = new RectangleF(0, 0, ufoTexture.Width * MainGame.ResolutionScale,
                                               ufoTexture.Height * MainGame.ResolutionScale);

            flashScore = false;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Update the <see cref="UfoController"/>.
        /// </summary>
        /// <param name="deltaTime"></param>
        public void Update(float deltaTime)
        {
            if (MainGame.Context.GetGameScreen <GameplayScreen>(GameScreenType.Gameplay).IsFrozen)
            {
                return;
            }

            float ufoWidth = ufoTexture.Width * MainGame.ResolutionScale;

            if (flashScore)
            {
                UpdateScoreFlash(deltaTime);
                return;
            }

            if (isUfoActive)
            {
                BoundingRectangle.X += HorizontalSpeed * movementDirection * deltaTime;

                // Check if the UFO has gone out of bounds
                if (movementDirection == 1 && BoundingRectangle.X - ufoWidth * MainGame.ResolutionScale > MainGame.GameScreenWidth ||
                    movementDirection == -1 && BoundingRectangle.X < -ufoWidth)
                {
                    Destroy(false);
                }
            }
            else
            {
                timeToSpawn -= deltaTime;
                if (!(timeToSpawn <= 0))
                {
                    return;
                }

                // A 50% chance to spawn on the left side.
                bool left = Random.Value() > 0.5f;
                movementDirection = left ? 1 : -1;
                isUfoActive       = true;

                float positionY = GameplayScreen.TopVerticalBoundary + ufoTexture.Height * MainGame.ResolutionScale + VerticalSpawnPadding;
                float positionX = left ? -ufoWidth : MainGame.GameScreenWidth + ufoWidth;
                BoundingRectangle.Position = new Vector2(positionX, positionY);
                timeToSpawn = Random.Range(MinimumSpawnTime, MaximumSpawnTime);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// <para>
        /// Gets the time until an <see cref="Enemy"/> can attack, in seconds, implemented as a range
        /// between a pair of exponential functions.
        /// </para>
        /// <remarks>
        /// More formally, the upper and lower bounds of the enemy attack times are given by a pair of functions
        /// f(x) and g(x) where f(x) represents the maximum time, g(x) represents the minimum time, and x represents the
        /// change in the vertical distance, in pixels (x in [0, d] where d represents the max vertical distance).
        /// The enemy attack time, t(x), is defined as a random value uniformly distributed on [f(x), g(x)]: t(x) ~ U([f(x), g(x)])
        /// where U represents the distribution function. For the full equations, see <see href="https://www.desmos.com/calculator/wzpbqmwmwt"></see>.
        /// </remarks>
        /// </summary>
        /// <returns></returns>
        private float GetEnemyAttackTime()
        {
            // The initial maximum time until an enemy attacks, in seconds; the value of g(0).
            const float initialMaximumTime = 30;
            // The initial minimum time until an enemy attacks, in seconds; the value of f(0).
            const float initialMinimumTime = 2;
            // The final maximum time until an enemy attacks, in seconds; the value of g(d).
            const float finalMaximumTime = 6;
            // The final minimum time until an enemy attacks, in seconds; the value of f(d).
            const float finalMinimumTime = 1;

            float validVerticalDistance = 1 / (MainGame.Context.GetGameScreen <GameplayScreen>(GameScreenType.Gameplay).BarrierGroup[0].Rectangle.Top - StartingPosition.Y);
            float b1 = (float)Math.Pow(initialMinimumTime / initialMaximumTime, validVerticalDistance);
            float b2 = (float)Math.Pow(finalMinimumTime / finalMaximumTime, validVerticalDistance);

            float distance    = boundingRectangle.Y - StartingPosition.Y;
            float maximumTime = initialMaximumTime * (float)Math.Pow(b1, distance);
            float minimumTime = finalMaximumTime * (float)Math.Pow(b2, distance);

            return(Random.Range(minimumTime, maximumTime));
        }
 /// <summary>
 /// Retrieves a random projectile prototype with the specified type.
 /// </summary>
 /// <param name="type">The type of the projectile prototype.</param>
 private Projectile GetRandomProjectilePrototype(ProjectileType type) =>
 projectilePrototypes[type][Random.Range(projectilePrototypes[type].Count)];