Esempio n. 1
0
 public static void LoadAllMetadata()
 {
     lock (staticMutationLock) {
         for (int worldIndex = 0; worldIndex < 11; ++worldIndex)
         {
             for (int levelIndex = 0; levelIndex < 10; ++levelIndex)
             {
                 LevelID lid      = new LevelID((byte)worldIndex, (byte)levelIndex);
                 string  filename = String.Empty;
                 if (LevelExists(lid))
                 {
                     filename = Path.Combine(AssetLocator.LevelsDir, GetLevelFileName(lid));
                 }
                 if (filename == String.Empty || !File.Exists(filename))
                 {
                     StringBuilder randomStringBuilder = new StringBuilder();
                     int           strLen = RandomProvider.Next(3, 16);
                     for (int c = 0; c < strLen; ++c)
                     {
                         char x = (char)RandomProvider.Next(65, 92);
                         if (x == (char)91)
                         {
                             x = ' ';
                         }
                         randomStringBuilder.Append(x);
                     }
                     var maxTime    = 30000 + RandomProvider.Next(1, 5) * 15000;
                     var bronzeTime = maxTime - RandomProvider.Next(1, 4) * 2500;
                     var silverTime = bronzeTime - RandomProvider.Next(1, 4) * 2500;
                     var goldTime   = silverTime - RandomProvider.Next(1, 4) * 2500;
                     loadedMetadata[worldIndex * 10 + levelIndex] = new LevelMetadata(
                         randomStringBuilder.ToString(),
                         maxTime,
                         bronzeTime,
                         silverTime,
                         goldTime,
                         RandomProvider.Next(1, 51)
                         );
                 }
                 else
                 {
                     var levelDesc = (GameLevelDescription)LevelDescription.Load(filename, false);
                     loadedMetadata[worldIndex * 10 + levelIndex] = new LevelMetadata(
                         levelDesc.Title,
                         levelDesc.LevelTimerMaxMs,
                         levelDesc.LevelTimerBronzeMs,
                         levelDesc.LevelTimerSilverMs,
                         levelDesc.LevelTimerGoldMs,
                         levelDesc.GetGameObjectsByType <LizardCoin>().Count()
                         );
                     levelDesc.Dispose();
                 }
                 var coinsInLevel = loadedMetadata[worldIndex * 10 + levelIndex].TotalCoinsInLevel;
                 totalCoinsInGame += coinsInLevel;
                 totalCoinsPerWorld[worldIndex] += coinsInLevel;
             }
         }
     }
 }
Esempio n. 2
0
        private static void Sounds_LevelPass(LevelPassDetails details)
        {
            AssetLocator.RollSound.StopAllInstances();
            //AudioModule.StopSound(AssetLocator.RollSound);
            playingCountdownTimer = false;
            AssetLocator.CountdownLoopSound.StopAllInstances();
            //AudioModule.StopSound(AssetLocator.CountdownLoopSound);

            int instanceId = AudioModule.CreateSoundInstance(AssetLocator.BellSound);

            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                PASS_FAIL_VOLUME * Config.SoundEffectVolume
                );
            instanceId = AudioModule.CreateSoundInstance(AssetLocator.PassSound);
            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                PASS_FAIL_VOLUME * Config.SoundEffectVolume
                );
            instanceId = AudioModule.CreateSoundInstance(AssetLocator.EmotePassSounds[RandomProvider.Next(0, AssetLocator.EmotePassSounds.Length)]);
            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                1.7f * Config.SoundEffectVolume,
                RandomProvider.Next(0.75f, 1.25f)
                );
            switch (details.Star)
            {
            case Star.Gold:
                HUDSoundExtensions.Play(HUDSound.PostPassStarGold, 1.3f);
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.PassGoldSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    PASS_FAIL_VOLUME * Config.SoundEffectVolume
                    );
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.PostPassGoldApplauseSound.File);
                AssetLocator.PostPassGoldApplauseSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, 0.55f * Config.HUDVolume);
                break;

            case Star.Silver:
                HUDSoundExtensions.Play(HUDSound.PostPassStarGold, 1f);
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.PostPassSilverApplauseSound.File);
                AssetLocator.PostPassSilverApplauseSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, 0.35f * Config.HUDVolume);
                break;

            case Star.Bronze:
                HUDSoundExtensions.Play(HUDSound.PostPassStarGold, 0.7f);
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.PostPassBronzeApplauseSound.File);
                AssetLocator.PostPassBronzeApplauseSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, 0.3f * Config.HUDVolume);
                break;
            }
        }
Esempio n. 3
0
        private static void MaybePlayAllBounce(float speedDifference)
        {
            if (lastAllBounceSoundTime - timeRemainingMs < ALL_BOUNCE_SOUND_MIN_INTERVAL)
            {
                return;
            }
            int instanceId = AudioModule.CreateSoundInstance(AssetLocator.AllBounceSounds[RandomProvider.Next(0, AssetLocator.AllBounceSounds.Length)]);

            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                (float)MathUtils.Clamp((speedDifference / PhysicsManager.ONE_METRE_SCALED), 0f, 0.5f) * Config.SoundEffectVolume,
                RandomProvider.Next(0.5f, 1f)
                );
            lastAllBounceSoundTime = timeRemainingMs;
        }
Esempio n. 4
0
 public void Reveal()
 {
     lock (InstanceMutationLock) {
         if (Config.DynamicLightCap == null)
         {
             AssetLocator.LightPass.AddLight(attachedLight);
         }
         SetGravity(GameCoordinator.BoardDownDir.WithLength(GameplayConstants.GRAVITY_ACCELERATION));
         SetScale(SCALE);
         AngularVelocity = new Vector3(
             RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
             RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
             RandomProvider.Next(-MathUtils.PI, MathUtils.PI)
             );
     }
 }
Esempio n. 5
0
        private static void Sounds_LevelFail(LevelFailReason reason)
        {
            Sounds_LevelProgress();

            if (reason == LevelFailReason.GameCancelled)
            {
                return;
            }

            int instanceId = AudioModule.CreateSoundInstance(AssetLocator.EmoteFailSounds[RandomProvider.Next(0, AssetLocator.EmoteFailSounds.Length)]);

            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                1.3f * Config.SoundEffectVolume,
                RandomProvider.Next(0.75f, 1.25f)
                );

            instanceId = AudioModule.CreateSoundInstance(AssetLocator.FailAwwSounds[RandomProvider.Next(0, AssetLocator.FailAwwSounds.Length)]);
            AudioModule.PlaySoundInstance(
                instanceId,
                false,
                0.575f * Config.SoundEffectVolume,
                RandomProvider.Next(0.75f, 1.25f)
                );

            switch (reason)
            {
            case LevelFailReason.Dropped:
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.FailFallSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    PASS_FAIL_VOLUME * Config.SoundEffectVolume
                    );
                break;

            case LevelFailReason.TimeUp:
                instanceId = AudioModule.CreateSoundInstance(AssetLocator.FailTimeoutSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    PASS_FAIL_VOLUME * Config.SoundEffectVolume
                    );
                break;
            }
        }
        public SillyBitEntity(int bitIndex)
        {
            BitIndex = bitIndex;
            if (bitIndex < 0 || bitIndex >= AssetLocator.SillyBitsHandles.Length)
            {
                var materialArr = Enum.GetValues(typeof(LizardEggMaterial));
                var material    = (LizardEggMaterial)materialArr.GetValue(RandomProvider.Next(0, materialArr.GetLength(0)));
                SetModelInstance(AssetLocator.GameLayer, AssetLocator.LizardEggModels[0], material.Material());
                SetScale(Vector3.ONE * 0.6f);
                SetPhysicsShape(
                    AssetLocator.LizardEggPhysicsShape,
                    Vector3.ZERO,
                    0.1f,
                    restitution: 0.5f,
                    friction: 0.2f,
                    rollingFriction: 0.2f,
                    linearDamping: 0.2f,
                    angularDamping: 0.2f
                    );

                attachedLight = new Light(Vector3.ZERO, Config.SillyBitsIlluminationRadius, material.CameraIlluminationColor());
            }
            else
            {
                SetModelInstance(AssetLocator.GameLayer, AssetLocator.SillyBitsHandles[bitIndex], AssetLocator.SillyBitsMaterials[bitIndex]);
                SetPhysicsShape(
                    AssetLocator.SillyBitsPhysicsShapes[bitIndex],
                    Vector3.ZERO,
                    0.1f,
                    restitution: 1f,
                    friction: 0.2f,
                    rollingFriction: 0.2f,
                    linearDamping: 0.2f,
                    angularDamping: 0.2f
                    );

                attachedLight = new Light(Vector3.ZERO, Config.SillyBitsIlluminationRadius, Config.SillyBitsIlluminationColors[bitIndex]);
            }

            //EnableContinuousCollisionDetection(GameplayConstants.MIN_SPEED_FOR_EGG_CCD, GameplayConstants.EGG_COLLISION_RADIUS * 0.01f);

            if (Config.DynamicLightCap == null)
            {
                AssetLocator.LightPass.AddLight(attachedLight);
            }
        }
Esempio n. 7
0
 private static void Sounds_Collision(GeometryEntity geom)
 {
     if ((!ignoredEggCollisionGeoms.ContainsKey(geom) || ignoredEggCollisionGeoms[geom] - timeRemainingMs >= IMPACT_SOUND_MIN_INTERVAL_SAME_GEOM_MS) &&
         lastImpactSoundTime - timeRemainingMs >= IMPACT_SOUND_MIN_INTERVAL_MS)
     {
         int instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
         AudioModule.PlaySoundInstance(
             instanceId,
             false,
             IMPACT_VOLUME * Config.SoundEffectVolume,
             RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
             );
         if (velocityLastFrame != Vector3.ZERO && egg.Velocity != Vector3.ZERO)
         {
             MaybePlayAllBounce(Math.Abs(velocityLastFrame.Length - egg.Velocity.Length));
         }
         lastImpactSoundTime = timeRemainingMs;
     }
     ignoredEggCollisionGeoms[geom]             = timeRemainingMs;
     highspeedUpMetadata.CollidedSinceLastSound = highspeedDownMetadata.CollidedSinceLastSound = highspeedParallelMetadata.CollidedSinceLastSound = true;
 }
Esempio n. 8
0
        public CollisionBitEntity()
        {
            int bitIndex = RandomProvider.Next(0, AssetLocator.SillyBitsHandles.Length);

            SetModelInstance(AssetLocator.GameLayer, AssetLocator.SillyBitsHandles[bitIndex], AssetLocator.SillyBitsMaterials[bitIndex]);
            SetPhysicsShape(
                AssetLocator.SillyBitsPhysicsShapes[bitIndex],
                Vector3.ZERO,
                0.1f,
                restitution: 0.4f,
                friction: 0.2f,
                rollingFriction: 0.2f,
                linearDamping: 0.2f,
                angularDamping: 0.2f,
                collideOnlyWithWorld: true
                );

            attachedLight = new Light(Vector3.ZERO, LIGHT_RADIUS, Config.SillyBitsIlluminationColors[bitIndex] * LIGHT_COLOR_MOD);

            Reveal();
        }
        public static void DisseminateBits(Vector3 position, Vector3 velocity, int count)
        {
            if (velocity == Vector3.ZERO)
            {
                return;
            }
            velocity = velocity.WithLength(Math.Max(MIN_SPEED, velocity.Length));
            Quaternion veloToPerpRot = Quaternion.FromVectorTransition(velocity, velocity.AnyPerpendicular());
            Quaternion veloRot       = Quaternion.FromAxialRotation(velocity, MathUtils.TWO_PI);

            lock (staticMutationLock) {
                for (int i = 0; i < count; ++i)
                {
                    var bit = Pop();
                    bit.SetTranslation(position);
                    bit.Velocity = velocity * veloToPerpRot.Subrotation(RandomProvider.Next(0.1f, 0.5f)) * veloRot.Subrotation(RandomProvider.Next(0f, 1f));
                    usedBits.Add(bit, EntityModule.ElapsedTime);
                }

                while (usedBits.Count > maxBits)
                {
                    KeyValuePair <CollisionBitEntity, float> leastRecentKVP = new KeyValuePair <CollisionBitEntity, float>(null, Single.MaxValue);
                    foreach (var usedBit in usedBits)
                    {
                        if (usedBit.Value < leastRecentKVP.Value)
                        {
                            leastRecentKVP = usedBit;
                        }
                    }

                    if (leastRecentKVP.Key != null)
                    {
                        usedBits.Remove(leastRecentKVP.Key);
                        Push(leastRecentKVP.Key);
                    }
                }
            }
        }
Esempio n. 10
0
        private static void LoadMenuBackdrop(SkyLevelDescription preloadedSky)
        {
            UnloadMenuBackdrop();

            if (!inDeferenceMode)
            {
                cameraLight = new Light(Vector3.ZERO, CAMERA_LIGHT_RADIUS, Vector3.ONE * CAMERA_LIGHT_INTENSITY);
                AssetLocator.LightPass.AddLight(cameraLight);
                //AssetLoader.ClearCache(); // TODO work out whether we really need this line?
                if (!Single.IsPositiveInfinity(Config.DofLensMaxBlurDist))
                {
                    AssetLocator.LightPass.SetLensProperties(DOF_FOCAL_DIST, DOF_MAX_DIST);
                }
                AssetLocator.MainCamera.Position         = Vector3.ZERO + Vector3.DOWN * BACKDROP_CAM_VERTICAL_OFFSET;
                AssetLocator.ShadowcasterCamera.Position = Vector3.UP * SILLY_BIT_DROP_HEIGHT * 1.1f;
                AssetLocator.ShadowcasterCamera.LookAt(Vector3.DOWN, Vector3.FORWARD);
                AssetLocator.ShadowcasterCamera.OrthographicDimensions = new Vector3(100f, 100f, PhysicsManager.ONE_METRE_SCALED * 3f);
                Quaternion downTilt = Quaternion.FromAxialRotation(Vector3.LEFT, BACKDROP_CAM_UPWARD_TILT);
                AssetLocator.MainCamera.Orient(Vector3.FORWARD * downTilt, Vector3.UP * downTilt);
                BGMManager.CrossFadeToTitleMusic();
                mainMenuSinceLoad = false;
            }

            if (preloadedSky != null)
            {
                loadedMenuBackdrop = preloadedSky;
            }
            else
            {
                int worldIndex = RandomProvider.Next(0, PersistedWorldData.GetFurthestUnlockedWorldIndex() + 1);
                loadedMenuBackdrop = (SkyLevelDescription)LevelDescription.Load(
                    Path.Combine(AssetLocator.LevelsDir, LevelDatabase.SkyboxFileNames[worldIndex])
                    );
                loadedMenuBackdrop.ReinitializeAll();
                worldIconTex.Texture = AssetLocator.WorldIcons[worldIndex];
            }
        }
Esempio n. 11
0
        private static void TickSound(float deltaTime)
        {
            Vector3 ballVelo       = egg.Velocity;
            float   ballSpeed      = ballVelo.Length;
            float   speedLastFrame = velocityLastFrame.Length;

            const int TICK_SOUND_EARLINESS_MS = 200;

            // Tick
            int adjustedTimeRemainingMs = timeRemainingMs - TICK_SOUND_EARLINESS_MS;
            int timeRemainingSecs       = adjustedTimeRemainingMs / 1000;

            if (timeRemainingSecs != 0 && timeRemainingSecs != (int)(adjustedTimeRemainingMs + deltaTime * 1000f) / 1000)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.TickSound);
                AudioModule.PlaySoundInstance(
                    instanceId,
                    false,
                    0.2f * Config.SoundEffectVolume,
                    adjustedTimeRemainingMs > Config.TimePitchRaiseMs ? 1f : (adjustedTimeRemainingMs > Config.TimeWarningMs ? 1.1f : 1.2f)
                    );
            }

            // Bounce
            if (velocityLastFrame != Vector3.ZERO && ballSpeed >= MIN_SPEED_FOR_DIFFERENTIAL_ANGLE_BOUNCE_SOUND && Vector3.AngleBetween(ballVelo, velocityLastFrame) >= MIN_VELO_DIFFERENTIAL_ANGLE_FOR_BOUNCE_SOUND)
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.ObtuseBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 3;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 5;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }
            else if (Math.Abs(ballSpeed - speedLastFrame) >= MIN_SPEED_CHANGE_FOR_BOUNCE_SOUND)               // bounce in same direction
            {
                if (lastBounceSoundTime - timeRemainingMs >= BOUNCE_SOUND_MIN_INTERVAL)
                {
                    int instanceId = AudioModule.CreateSoundInstance(AssetLocator.AcuteBounceSound);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        BOUNCE_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(BOUNCE_PITCH_MIN, BOUNCE_PITCH_MAX)
                        );
                    instanceId = AudioModule.CreateSoundInstance(AssetLocator.ImpactSounds[RandomProvider.Next(0, AssetLocator.ImpactSounds.Length)]);
                    AudioModule.PlaySoundInstance(
                        instanceId,
                        false,
                        IMPACT_VOLUME * Config.SoundEffectVolume,
                        RandomProvider.Next(IMPACT_PITCH_MIN, IMPACT_PITCH_MAX)
                        );
                    lastBounceSoundTime = timeRemainingMs;
                }

                float speedDiff     = Math.Abs(speedLastFrame - ballSpeed);
                int   baseBitsCount = 2;
                if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 10f)
                {
                    baseBitsCount = 13;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 8f)
                {
                    baseBitsCount = 11;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 6f)
                {
                    baseBitsCount = 7;
                }
                else if (speedDiff >= PhysicsManager.ONE_METRE_SCALED * 4f)
                {
                    baseBitsCount = 3;
                }
                CollisionBitPool.DisseminateBits(egg.Transform.Translation, -boardDownDir.WithLength(speedDiff * 0.65f), baseBitsCount * (int)Config.PhysicsLevel);
                MaybePlayAllBounce(speedDiff);
            }

            // Roll
            float   rollVolFraction  = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_VOL - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_VOL);
            float   rollFreqFraction = (ballSpeed - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ) / (GameplayConstants.EGG_SPEED_FOR_MAX_ROLL_FREQ - GameplayConstants.EGG_SPEED_FOR_MIN_ROLL_FREQ);
            Vector3 eggPos           = egg.Transform.Translation;
            Ray     rollTestRay      = Ray.FromStartAndEndPoint(
                eggPos,
                eggPos + boardDownDir.WithLength(GameplayConstants.EGG_COLLISION_RADIUS + ROLL_MARGIN)
                );

            EntityModule.RayTestAllLessGarbage(rollTestRay, reusableRayTestResultsList);
            bool isRolling = false;

            for (int i = 0; i < reusableRayTestResultsList.Count; ++i)
            {
                if (reusableRayTestResultsList[i].Entity != egg)
                {
                    isRolling = true;
                    break;
                }
            }
            if (isRolling)
            {
                if (unbrokenRollTime == 0)
                {
                    unbrokenRollTime = (int)(deltaTime * 1000f);
                }
                else
                {
                    unbrokenRollTime += lastRollTime - timeRemainingMs;
                }
                lastRollTime = timeRemainingMs;
            }
            else
            {
                if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                    lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_UNBROKEN_ROLL_RESET)
                {
                    unbrokenRollTime = 0;
                }
            }

            if (unbrokenRollTime < UNBROKEN_ROLL_TIME_BEFORE_ROLL_SOUND ||
                lastRollTime - timeRemainingMs > ROLL_RAY_FAIL_MAX_TIME_BEFORE_NO_SOUND_MS ||
                rollVolFraction <= 0f ||
                rollFreqFraction <= 0f)
            {
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), 0f);
            }
            else
            {
                if (rollVolFraction > 1f)
                {
                    rollVolFraction = 1f;
                }
                if (rollFreqFraction > 1f)
                {
                    rollFreqFraction = 1f;
                }
                AudioModule.SetSoundInstanceFrequency(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_FREQ_MIN + (ROLL_FREQ_MAX - ROLL_FREQ_MIN) * rollFreqFraction);
                AudioModule.SetSoundInstanceVolume(AssetLocator.RollSound.SoundInstanceIds.First(), ROLL_VOLUME_MIN + (ROLL_VOLUME_MAX - ROLL_VOLUME_MIN) * rollVolFraction * Config.SoundEffectVolume);
            }

            // Highspeed
            if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED)
            {
                float angleToUp   = Vector3.AngleBetween(ballVelo, -boardDownDir);
                float angleToDown = Vector3.AngleBetween(ballVelo, boardDownDir);

                if (angleToUp <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    if (highspeedUpMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedUpMetadata.CollidedSinceLastSound && highspeedUpMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedUpSounds[RandomProvider.Next(0, AssetLocator.HighSpeedUpSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedUpMetadata.CollidedSinceLastSound = highspeedUpMetadata.SlowedSinceLastSound = false;
                        highspeedUpMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (angleToDown <= MathUtils.PI_OVER_TWO * 0.5f)
                {
                    Ray  downRay          = Ray.FromStartAndEndPoint(eggPos, eggPos + boardDownDir.WithLength(PARALLEL_HIGHSPEED_DOWN_BUFFER));
                    bool somethingBeneath = EntityModule.RayTestAll(downRay).Any(rtc => rtc.Entity != egg);
                    if (highspeedDownMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedDownMetadata.CollidedSinceLastSound && highspeedDownMetadata.SlowedSinceLastSound &&
                        !somethingBeneath)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedDownSounds[RandomProvider.Next(0, AssetLocator.HighSpeedDownSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedDownMetadata.CollidedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = false;
                        highspeedDownMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
                else if (ballSpeed >= HIGHSPEED_SOUND_MIN_SPEED + HIGHSPEED_SOUND_ADDITIONAL_SPEED_FOR_PARALLEL)
                {
                    if (highspeedParallelMetadata.TimeAtLastSound - timeRemainingMs >= MIN_INTERVAL_BETWEEN_HIGHSPEED_SOUNDS_MS &&
                        highspeedParallelMetadata.CollidedSinceLastSound && highspeedParallelMetadata.SlowedSinceLastSound)
                    {
                        int instanceId = AudioModule.CreateSoundInstance(AssetLocator.HighSpeedParallelSounds[RandomProvider.Next(0, AssetLocator.HighSpeedParallelSounds.Length)]);
                        AudioModule.PlaySoundInstance(
                            instanceId,
                            false,
                            HIGHSPEED_VOLUME * Config.SoundEffectVolume,
                            RandomProvider.Next(HIGHSPEED_PITCH_MIN, HIGHSPEED_PITCH_MAX)
                            );
                        highspeedParallelMetadata.CollidedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = false;
                        highspeedParallelMetadata.TimeAtLastSound        = timeRemainingMs;
                    }
                }
            }
            else
            {
                highspeedUpMetadata.SlowedSinceLastSound = highspeedDownMetadata.SlowedSinceLastSound = highspeedParallelMetadata.SlowedSinceLastSound = true;
            }

            // Countdown Timer
            if (!playingCountdownTimer && timeRemainingMs <= COUNTDOWN_TIMER_START_TIME_MS)
            {
                int instanceId = AudioModule.CreateSoundInstance(AssetLocator.CountdownLoopSound.File);
                AssetLocator.CountdownLoopSound.AddInstance(instanceId);
                AudioModule.PlaySoundInstance(instanceId, true, COUNTDOWN_VOLUME);
                playingCountdownTimer = true;
            }

            velocityLastFrame = ballVelo;
        }
Esempio n. 12
0
        protected override void Tick(float deltaTimeSeconds)
        {
            base.Tick(deltaTimeSeconds);

            if (deltaTimeSeconds > 1f)
            {
                return;
            }

            float curTime = EntityModule.ElapsedTime;

            disposalWorkspace.Clear();
            foreach (var ele in activeElements)
            {
                float eleLife = curTime - ele.SpawnTime;
                if (eleLife >= Lifetime)
                {
                    disposalWorkspace.Add(ele);
                    continue;
                }

                ele.HUDObject.AnchorOffset += ele.Velocity * deltaTimeSeconds;
                ele.HUDObject.SetAlpha(ele.InitialAlpha * (1f - eleLife / lifetime));
            }
            foreach (var toBeDisposed in disposalWorkspace)
            {
                activeElements.Remove(toBeDisposed);
                unusedObjects.Push(toBeDisposed.HUDObject);
            }

            if (targetObj == null)
            {
                return;
            }

            timeSinceLastSpawn += deltaTimeSeconds;
            while (timeSinceLastSpawn >= spawnInterval)
            {
                float alpha = targetObj.Color.W * opacityMultiplier;

                IHUDObject newObj;
                if (unusedObjects.Count == 0)
                {
                    newObj = targetObj.Clone();
                }
                else
                {
                    newObj = unusedObjects.Pop();
                    targetObj.CopyTo(newObj);
                }

                if (colorOverride != null)
                {
                    newObj.Color = new Vector4(colorOverride.Value, w: alpha);
                }
                else
                {
                    newObj.SetAlpha(alpha);
                }
                newObj.ZIndex = targetObj.ZIndex + 1;

                Vector2 velo = new Vector2(
                    RandomProvider.Next(-1f, 1f),
                    RandomProvider.Next(-1f, 1f)
                    );
                if (velo == Vector2.ZERO)
                {
                    velo = Vector2.UP;
                }
                velo = velo.WithLength(speed);

                activeElements.Add(new ObjDetails(curTime, velo, alpha, newObj));

                timeSinceLastSpawn -= spawnInterval;
            }
        }
Esempio n. 13
0
        private static void Tick(float deltaTime)
        {
            if (deltaTime > 1f)
            {
                return;
            }
            lock (staticMutationLock) {
                if (currentMenuState == MenuState.InGame)
                {
                    return;
                }
                if (cameraLight != null)
                {
                    cameraLight.Position = AssetLocator.MainCamera.Position;
                }
                if (isTransitioning)
                {
                    transitionTimeElapsed += deltaTime;
                    if (transitionTimeElapsed >= transitionTime)
                    {
                        EndTransition(deltaTime - (transitionTimeElapsed - transitionTime));
                    }
                    if (currentMenuState == MenuState.InGame)
                    {
                        return;
                    }
                }
                else
                {
                    if (downKeyState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - downKeyState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - downKeyState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                downKeyState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerDownLocal = triggerDown;
                                if (triggerDownLocal != null)
                                {
                                    triggerDownLocal();
                                }
                            }
                        }
                    }
                    if (upKeyState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - upKeyState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - upKeyState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                upKeyState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerUpLocal = triggerUp;
                                if (triggerUpLocal != null)
                                {
                                    triggerUpLocal();
                                }
                            }
                        }
                    }
                    if (leftKeyState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - leftKeyState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - leftKeyState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                leftKeyState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerLeftLocal = triggerLeft;
                                if (triggerLeftLocal != null)
                                {
                                    triggerLeftLocal();
                                }
                            }
                        }
                    }
                    if (rightKeyState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - rightKeyState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - rightKeyState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                rightKeyState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerRightLocal = triggerRight;
                                if (triggerRightLocal != null)
                                {
                                    triggerRightLocal();
                                }
                            }
                        }
                    }
                    if (downLSState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - downLSState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - downLSState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                downLSState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerDownLocal = triggerDown;
                                if (triggerDownLocal != null)
                                {
                                    triggerDownLocal();
                                }
                            }
                        }
                    }
                    if (upLSState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - upLSState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - upLSState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                upLSState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerUpLocal = triggerUp;
                                if (triggerUpLocal != null)
                                {
                                    triggerUpLocal();
                                }
                            }
                        }
                    }
                    if (leftLSState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - leftLSState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - leftLSState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                leftLSState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerLeftLocal = triggerLeft;
                                if (triggerLeftLocal != null)
                                {
                                    triggerLeftLocal();
                                }
                            }
                        }
                    }
                    if (rightLSState.IsDown)
                    {
                        float timeSinceDepression = EntityModule.ElapsedTime - rightLSState.LastDepress;
                        if (timeSinceDepression >= Config.InitialRepeatTimeDelay)
                        {
                            float timeSinceLastTrigger = EntityModule.ElapsedTime - rightLSState.LastTrigger;
                            if (timeSinceLastTrigger >= Config.SuccessiveRepeatTimeDelay)
                            {
                                rightLSState.LastTrigger = EntityModule.ElapsedTime;
                                var triggerRightLocal = triggerRight;
                                if (triggerRightLocal != null)
                                {
                                    triggerRightLocal();
                                }
                            }
                        }
                    }
                }

                if (!inDeferenceMode)
                {
                    AssetLocator.MainCamera.Rotate(BACKDROP_ROT_QUAT.Subrotation(deltaTime));

                    var deadBits = activeSillyBits.RemoveWhere(sb => sb.Transform.Translation.Y < AssetLocator.MainCamera.Position.Y - SILLY_BIT_DROP_HEIGHT);
                    foreach (var deadBit in deadBits)
                    {
                        deadBit.Dispose();
                    }

                    float timeSinceLastBitDrop = EntityModule.ElapsedTime - lastSillyBitDrop;
                    if (timeSinceLastBitDrop >= SILLY_BIT_DROP_INTERVAL / Config.PhysicsLevel + sillyBitSpawnRandomExtra)
                    {
                        int            sillyBitIndex = RandomProvider.Next(0f, 1f) <= SILLY_BIT_IS_EGG_CHANCE ? -1 : RandomProvider.Next(0, AssetLocator.SillyBitsHandles.Length);
                        SillyBitEntity newBit        = new SillyBitEntity(sillyBitIndex);
                        newBit.SetGravity(GameplayConstants.GRAVITY_ACCELERATION * RandomProvider.Next(0.025f, 0.175f) * Vector3.DOWN);
                        newBit.AngularVelocity = new Vector3(
                            RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
                            RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
                            RandomProvider.Next(-MathUtils.PI, MathUtils.PI)
                            );
                        Vector3 lateralOffset =
                            AssetLocator.MainCamera.Orientation
                            * SILLY_BIT_DROP_FORWARD_OFFSET
                            * Quaternion.FromAxialRotation(
                                Vector3.DOWN,
                                RandomProvider.Next(
                                    -SILLY_BIT_DROP_CONE * (1f - SILLY_BIT_CAM_ROT_CONE_BIAS),
                                    SILLY_BIT_DROP_CONE * SILLY_BIT_CAM_ROT_CONE_BIAS
                                    )
                                );
                        newBit.SetTranslation(AssetLocator.MainCamera.Position + Vector3.UP * SILLY_BIT_DROP_HEIGHT + lateralOffset);

                        activeSillyBits.Add(newBit);

                        HUDSound.PostPassEggPop.Play(0.2f, RandomProvider.Next(0.5f, 1.5f));
                        lastSillyBitDrop         = EntityModule.ElapsedTime;
                        sillyBitSpawnRandomExtra = RandomProvider.Next(0f, MAX_RANDOM_SPAWN_EXTRA_TIME);
                    }

                    float timeSinceLastBitExplosion = EntityModule.ElapsedTime - lastSillyBitExplosion;
                    if (timeSinceLastBitExplosion >= SILLY_BIT_EXPLOSION_INTERVAL / Config.PhysicsLevel + sillyBitExplosionRandomExtra && activeSillyBits.Any())
                    {
                        var nonEggBits = activeSillyBits.Except(bit => bit.BitIndex == -1);
                        if (nonEggBits.Any())
                        {
                            var targetBit = nonEggBits.ElementAt(RandomProvider.Next(0, nonEggBits.Count()));
                            for (int i = 0; i < SILLY_BIT_EXPLOSION_SIZE; ++i)
                            {
                                Vector3 targetDir = new Vector3(
                                    RandomProvider.Next(-1f, 1f),
                                    RandomProvider.Next(-1f, 1f),
                                    RandomProvider.Next(-1f, 1f)
                                    );
                                if (targetDir == Vector3.ZERO)
                                {
                                    targetDir = AssetLocator.MainCamera.Orientation;
                                }

                                SillyBitEntity newBit = new SillyBitEntity(targetBit.BitIndex);
                                newBit.AngularVelocity = new Vector3(
                                    RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
                                    RandomProvider.Next(-MathUtils.PI, MathUtils.PI),
                                    RandomProvider.Next(-MathUtils.PI, MathUtils.PI)
                                    );
                                newBit.SetTranslation(targetBit.Transform.Translation + targetDir.WithLength(PhysicsManager.ONE_METRE_SCALED * 0.1f));
                                newBit.Velocity = targetDir.WithLength(PhysicsManager.ONE_METRE_SCALED * 0.5f);
                                newBit.SetGravity(GameplayConstants.GRAVITY_ACCELERATION * RandomProvider.Next(0.025f, 0.175f) * Vector3.DOWN);

                                activeSillyBits.Add(newBit);
                            }
                            HUDSound.PostPassShowMenu.Play(RandomProvider.Next(0f, 0.5f), RandomProvider.Next(1.5f, 0.5f));
                        }


                        lastSillyBitExplosion        = EntityModule.ElapsedTime;
                        sillyBitExplosionRandomExtra = RandomProvider.Next(0f, MAX_RANDOM_EXPLOSION_EXTRA_TIME);
                    }

                    if (menuIdentTex.Color.W == 0f && worldIconTex.Color.W < WORLD_ICON_TARGET_ALPHA)
                    {
                        worldIconTex.AdjustAlpha(WORLD_ICON_ALPHA_PER_SEC * deltaTime);
                        if (worldIconTex.Color.W > WORLD_ICON_TARGET_ALPHA)
                        {
                            worldIconTex.SetAlpha(WORLD_ICON_TARGET_ALPHA);
                        }
                    }
                }

                if (versionString.Color.W < WORLD_ICON_TARGET_ALPHA)
                {
                    versionString.AdjustAlpha(WORLD_ICON_ALPHA_PER_SEC * deltaTime);
                    if (versionString.Color.W > WORLD_ICON_TARGET_ALPHA)
                    {
                        versionString.SetAlpha(WORLD_ICON_TARGET_ALPHA);
                    }
                }

                var transitionTickLocal = transitionTick;
                if (transitionTickLocal != null)
                {
                    transitionTickLocal(deltaTime, transitionTimeElapsed / transitionTime);
                }
                var tickLocal = tick;
                if (tickLocal != null)
                {
                    tickLocal(deltaTime);
                }
            }
        }
        private static void MainMenuCreateComponents()
        {
            MainMenuDisposeComponents();

            triggerUp      += MainMenuChangeOptionUp;
            triggerRight   += MainMenuChangeOptionUp;
            triggerDown    += MainMenuChangeOptionDown;
            triggerLeft    += MainMenuChangeOptionDown;
            triggerConfirm += MainMenuConfirmOption;
            triggerBackOut += MainMenuBackOut;
            tick           += MainMenuTick;

            mainMenuInExitConfirmationScreen = false;

            mainMenuELLogo = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopCentered,
                AnchorOffset             = new Vector2(0f, 0.01f),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 1f),
                Rotation = 0f,
                Scale    = new Vector2(0f, 0f),
                Texture  = AssetLocator.ELLogo,
                ZIndex   = 3
            };

            for (int i = 0; i < MAIN_MENU_EL_LOGO_LOW_CONFETTI_COUNT * Config.PhysicsLevel; ++i)
            {
                ITexture2D texture;
                switch (i % 4)
                {
                case 0: texture = AssetLocator.GoldStar; break;

                case 1: texture = AssetLocator.SilverStar; break;

                case 2: texture = AssetLocator.BronzeStar; break;

                default: texture = AssetLocator.CoinFrames[0]; break;
                }
                var confetto = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
                {
                    Anchoring                = ViewportAnchoring.TopLeft,
                    AnchorOffset             = new Vector2(0.5f, mainMenuELLogo.AnchorOffset.Y),
                    AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                    Color    = new Vector4(1f, 1f, 1f, 1f),
                    Rotation = 0f,
                    Scale    = new Vector2(0.1f, 0.1f),
                    Texture  = texture,
                    ZIndex   = mainMenuELLogo.ZIndex - 1
                };
                Vector2 initialVelo = new Vector2(
                    RandomProvider.Next(-0.5f, 0.5f),
                    RandomProvider.Next(-0.5f, 0.5f)
                    );
                float initialSpin = RandomProvider.Next(-MathUtils.PI, MathUtils.PI);
                mainMenuELLogoConfetti.Add(confetto, new Vector4(initialVelo, z: initialSpin, w: texture == AssetLocator.CoinFrames[0] ? 32f : 0f));
            }

            mainMenuPlayButtonL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopRight,
                AnchorOffset             = new Vector2(0.37f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 0),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuPlayButton,
                ZIndex   = 3
            };
            mainMenuPlayButtonR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopLeft,
                AnchorOffset             = new Vector2(0.37f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 0),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuPlayButton,
                ZIndex   = 3
            };

            mainMenuMedalsButtonL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopRight,
                AnchorOffset             = new Vector2(0.41f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 1),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuMedalsButton,
                ZIndex   = 3
            };
            mainMenuMedalsButtonR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopLeft,
                AnchorOffset             = new Vector2(0.41f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 1),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuMedalsButton,
                ZIndex   = 3
            };

            mainMenuOptionsButtonL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopRight,
                AnchorOffset             = new Vector2(0.42f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 2),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuOptionsButton,
                ZIndex   = 3
            };
            mainMenuOptionsButtonR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopLeft,
                AnchorOffset             = new Vector2(0.42f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 2),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuOptionsButton,
                ZIndex   = 3
            };

            mainMenuExitButtonL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopRight,
                AnchorOffset             = new Vector2(0.37f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 3),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuExitButton,
                ZIndex   = 3
            };
            mainMenuExitButtonR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = ViewportAnchoring.TopLeft,
                AnchorOffset             = new Vector2(0.37f + MAIN_MENU_BUTTON_TRANSITION_HORIZONTAL_OFFSET, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 3),
                AspectCorrectionStrategy = HUDTexture.AspectRatioCorrectionStrategy.UseBestUniformScaling,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuExitButton,
                ZIndex   = 3
            };



            mainMenuButtonFrontL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = mainMenuPlayButtonL.Anchoring,
                AnchorOffset             = mainMenuPlayButtonL.AnchorOffset,
                AspectCorrectionStrategy = mainMenuPlayButtonL.AspectCorrectionStrategy,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuPlayButtonFront,
                ZIndex   = 4
            };
            mainMenuButtonFrontR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = mainMenuPlayButtonR.Anchoring,
                AnchorOffset             = mainMenuPlayButtonR.AnchorOffset,
                AspectCorrectionStrategy = mainMenuPlayButtonR.AspectCorrectionStrategy,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuPlayButtonFront,
                ZIndex   = 4
            };

            mainMenuButtonRingL = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = mainMenuPlayButtonL.Anchoring,
                AnchorOffset             = mainMenuPlayButtonL.AnchorOffset,
                AspectCorrectionStrategy = mainMenuPlayButtonL.AspectCorrectionStrategy,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuButtonRing,
                ZIndex   = 2
            };
            mainMenuButtonRingR = new HUDTexture(AssetLocator.HUDFragmentShader, AssetLocator.HudLayer, AssetLocator.MainWindow)
            {
                Anchoring                = mainMenuPlayButtonR.Anchoring,
                AnchorOffset             = mainMenuPlayButtonR.AnchorOffset,
                AspectCorrectionStrategy = mainMenuPlayButtonR.AspectCorrectionStrategy,
                Color    = new Vector4(1f, 1f, 1f, 0f),
                Rotation = 0f,
                Scale    = MAIN_MENU_BUTTON_SCALE,
                Texture  = AssetLocator.MainMenuButtonRing,
                ZIndex   = 2
            };

            mainMenuButtonRingExciterL = new HUDItemExciterEntity(mainMenuButtonRingL)
            {
                OpacityMultiplier = 0.066f,
                Lifetime          = 0.8f,
                Speed             = 0.06f,
                CountPerSec       = 60
            };
            mainMenuButtonRingExciterR = new HUDItemExciterEntity(mainMenuButtonRingR)
            {
                OpacityMultiplier = mainMenuButtonRingExciterL.OpacityMultiplier,
                Lifetime          = mainMenuButtonRingExciterL.Lifetime,
                Speed             = mainMenuButtonRingExciterL.Speed,
                CountPerSec       = mainMenuButtonRingExciterL.CountPerSec
            };

            mainMenuPlayString = AssetLocator.TitleFontGlow.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopCentered,
                new Vector2(0.0f, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 0 + MAIN_MENU_TEXT_OFFSET_Y),
                MAIN_MENU_TEXT_SCALE
                );
            mainMenuPlayString.Color = new Vector4(MAIN_MENU_STRING_COLOR, w: 0f);
            mainMenuPlayString.Text  = "PLAY";

            mainMenuMedalsString = AssetLocator.TitleFontGlow.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopCentered,
                new Vector2(0.0f, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 1 + MAIN_MENU_TEXT_OFFSET_Y),
                MAIN_MENU_TEXT_SCALE
                );
            mainMenuMedalsString.Color = new Vector4(MAIN_MENU_STRING_COLOR, w: 0f);
            mainMenuMedalsString.Text  = "MEDALS";

            mainMenuOptionsString = AssetLocator.TitleFontGlow.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopCentered,
                new Vector2(0.0f, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 2 + MAIN_MENU_TEXT_OFFSET_Y),
                MAIN_MENU_TEXT_SCALE
                );
            mainMenuOptionsString.Color = new Vector4(MAIN_MENU_STRING_COLOR, w: 0f);
            mainMenuOptionsString.Text  = "OPTIONS";

            mainMenuExitString = AssetLocator.TitleFontGlow.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopCentered,
                new Vector2(0.0f, MAIN_MENU_BUTTONS_START_HEIGHT + MAIN_MENU_BUTTONS_ROW_HEIGHT * 3 + MAIN_MENU_TEXT_OFFSET_Y),
                MAIN_MENU_TEXT_SCALE
                );
            mainMenuExitString.Color = new Vector4(MAIN_MENU_STRING_COLOR, w: 0f);
            mainMenuExitString.Text  = "QUIT";

            mainMenuStringExciter = new HUDItemExciterEntity(null);

            mainMenuExitConfirmQuestionString = AssetLocator.TitleFont.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopCentered,
                new Vector2(0f, 0.475f),
                MAIN_MENU_EXIT_ANSWER_SCALE
                );
            mainMenuExitConfirmQuestionString.Color = new Vector4(MAIN_MENU_EXIT_QUESTION_COLOR, w: 0f);
            mainMenuExitConfirmQuestionString.Text  = "Exit Game?";

            mainMenuExitConfirmYesString = AssetLocator.TitleFont.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopRight,
                new Vector2(0.6f, 0.6f),
                MAIN_MENU_EXIT_SELECTED_ANSWER_SCALE
                );
            mainMenuExitConfirmYesString.Color = new Vector4(MAIN_MENU_EXIT_ANSWER_COLOR, w: 0f);
            mainMenuExitConfirmYesString.Text  = "YES";

            mainMenuExitConfirmNoString = AssetLocator.TitleFont.AddString(
                AssetLocator.HudLayer,
                AssetLocator.MainWindow,
                ViewportAnchoring.TopLeft,
                new Vector2(0.64f, 0.6f),
                MAIN_MENU_EXIT_ANSWER_SCALE
                );
            mainMenuExitConfirmNoString.Color = new Vector4(MAIN_MENU_EXIT_ANSWER_COLOR, w: 0f);
            mainMenuExitConfirmNoString.Text  = "NO";
        }