Exemple #1
0
        private static ObjectAction GetSatelliteShootAction(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            IMathExpression initialShootCooldownInMillis = MathExpression.RandomInteger(6000);
            IMathExpression shootCooldownInMillis        = MathExpression.Add(5000, MathExpression.RandomInteger(1000));

            string cooldownVariableName = guidGenerator.NextGuid();

            ObjectAction initialStartCooldownAction = ObjectAction.SetNumericVariable(cooldownVariableName, initialShootCooldownInMillis);
            ObjectAction startCooldownAction        = ObjectAction.SetNumericVariable(cooldownVariableName, shootCooldownInMillis);
            ObjectAction decrementCooldownAction    = ObjectAction.SetNumericVariable(cooldownVariableName, MathExpression.Subtract(MathExpression.Variable(cooldownVariableName), MathExpression.ElapsedMillisecondsPerIteration()));
            ObjectAction createBulletAction         = SpawnSatelliteBullet(
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            var createBulletWhenCooldownFinishedAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(cooldownVariableName), MathExpression.Constant(0)),
                action: ObjectAction.Union(startCooldownAction, createBulletAction));

            return(ObjectAction.ConditionalNextAction(
                       currentAction: initialStartCooldownAction,
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.Union(decrementCooldownAction, createBulletWhenCooldownFinishedAction)));
        }
Exemple #2
0
        private static ObjectAction GetBulletMovementAction(
            GuidGenerator guidGenerator)
        {
            long bulletSpeedInPixelsPerSecond = 250;

            ObjectAction moveAction = ObjectActionGenerator.MoveTowardsLocation(
                currentX: MathExpression.XMillis(),
                currentY: MathExpression.YMillis(),
                desiredX: MathExpression.PlayerXMillis(),
                desiredY: MathExpression.Min(MathExpression.PlayerYMillis(), 300 * 1000),
                movementSpeedInPixelsPerSecond: MathExpression.Constant(bulletSpeedInPixelsPerSecond),
                shouldSnapshot: true,
                guidGenerator: guidGenerator);

            long buffer = 100;

            BooleanExpression shouldDestroy = BooleanExpression.Or(
                BooleanExpression.GreaterThan(MathExpression.XMillis(), MathExpression.Constant((1000 + buffer) * 1000)),
                BooleanExpression.LessThan(MathExpression.XMillis(), MathExpression.Constant((0 - buffer) * 1000)),
                BooleanExpression.GreaterThan(MathExpression.YMillis(), MathExpression.Constant((700 + buffer) * 1000)),
                BooleanExpression.LessThan(MathExpression.YMillis(), MathExpression.Constant((0 - buffer) * 1000)));

            ObjectAction destroyAction = ObjectAction.Condition(
                condition: shouldDestroy,
                action: ObjectAction.Destroy());

            return(ObjectAction.Union(moveAction, destroyAction));
        }
Exemple #3
0
        public static ObjectAction SpawnBarrageEnemy(
            IMathExpression xMillis,
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            // Should be called first so it sets the "can shoot" variable that the shootBullet action will need
            ObjectAction moveAction = GetMoveAndSetCanShootVariableAction(
                xMillis: xMillis,
                guidGenerator: guidGenerator);

            ObjectAction shootAction = GetShootBulletAction(
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            ObjectAction destroyAction = ObjectActionGenerator.DestroyWhenHpIsZeroAndMaybeDropPowerUp(
                chanceToDropPowerUpInMilliPercent: 15 * 1000,
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                soundNameToSoundDictionary: soundNameToSoundDictionary,
                guidGenerator: guidGenerator);

            string spriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(spriteName, DTDanmakuImage.BarrageEnemyShip);

            List <ObjectBox> damageBoxes = new List <ObjectBox>();

            damageBoxes.Add(new ObjectBox(lowerXMillis: -46500, upperXMillis: 46500, lowerYMillis: 0, upperYMillis: 40000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -31500, upperXMillis: 31500, lowerYMillis: -35000, upperYMillis: 30000));

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -10000, upperXMillis: 10000, lowerYMillis: -25000, upperYMillis: 25000));
            collisionBoxes.Add(new ObjectBox(lowerXMillis: -25000, upperXMillis: 25000, lowerYMillis: -10000, upperYMillis: 10000));

            EnemyObjectTemplate enemyObjectTemplate = EnemyObjectTemplate.Enemy(
                action: ObjectAction.Union(moveAction, shootAction, destroyAction),
                initialMilliHP: MathExpression.Add(MathExpression.Constant(38000), MathExpression.RandomInteger(MathExpression.Constant(10000))),
                damageBoxes: damageBoxes,
                collisionBoxes: collisionBoxes,
                spriteName: spriteName);

            string templateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(templateName, enemyObjectTemplate);

            return(ObjectAction.SpawnChild(
                       childXMillis: MathExpression.Constant(-1000 * 1000),
                       childYMillis: MathExpression.Constant(-1000 * 1000),
                       childObjectTemplateName: templateName,
                       childInitialNumericVariables: null,
                       childInitialBooleanVariables: null));
        }
Exemple #4
0
        public static ObjectAction DestroyWhenHpIsZeroAndMaybeDropPowerUp(
            long chanceToDropPowerUpInMilliPercent,             // ranges from 0 (meaning 0%) to 100,000 (meaning 100%)
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            string soundEffectName = guidGenerator.NextGuid();

            BooleanExpression isHpZero = BooleanExpression.LessThanOrEqualTo(
                MathExpression.MilliHP(),
                MathExpression.Constant(0));

            ObjectAction playEnemyDeathSoundEffectAction = ObjectAction.PlaySoundEffect(soundEffectName: soundEffectName);

            soundNameToSoundDictionary.Add(soundEffectName, DTDanmakuSound.EnemyDeath);

            DestructionAnimationGenerator.GenerateDestructionAnimationResult generateDestructionAnimationResult = DestructionAnimationGenerator.GenerateDestructionAnimation(
                orderedSprites: new List <DTDanmakuImage>
            {
                DTDanmakuImage.Explosion1,
                DTDanmakuImage.Explosion2,
                DTDanmakuImage.Explosion3,
                DTDanmakuImage.Explosion4,
                DTDanmakuImage.Explosion5,
                DTDanmakuImage.Explosion6,
                DTDanmakuImage.Explosion7,
                DTDanmakuImage.Explosion8,
                DTDanmakuImage.Explosion9
            },
                millisecondsPerSprite: 20,
                guidGenerator: guidGenerator);

            foreach (var entry in generateDestructionAnimationResult.spriteNameToImageDictionary)
            {
                spriteNameToImageDictionary.Add(entry.Key, entry.Value);
            }
            foreach (var entry in generateDestructionAnimationResult.enemyObjectTemplates)
            {
                enemyObjectTemplates.Add(entry.Key, entry.Value);
            }

            ObjectAction possiblySpawnPowerUpAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThan(
                    MathExpression.RandomInteger(MathExpression.Constant(100 * 1000)),
                    MathExpression.Constant(chanceToDropPowerUpInMilliPercent)),
                action: ObjectAction.SpawnPowerUp());

            return(ObjectAction.Condition(
                       condition: isHpZero,
                       action: ObjectAction.Union(
                           playEnemyDeathSoundEffectAction,
                           generateDestructionAnimationResult.objectAction,
                           possiblySpawnPowerUpAction,
                           ObjectAction.Destroy())));
        }
Exemple #5
0
 public static MathExpressionOffset GetOffset(
     IMathExpression millipixels,
     IMathExpression movementDirectionInMillidegrees)
 {
     return(new MathExpressionOffset
     {
         DeltaXInMillipixels = MathExpression.Divide(MathExpression.Multiply(millipixels, MathExpression.SineScaled(movementDirectionInMillidegrees)), MathExpression.Constant(1000L)),
         DeltaYInMillipixels = MathExpression.Divide(MathExpression.Multiply(millipixels, MathExpression.CosineScaled(movementDirectionInMillidegrees)), MathExpression.Constant(1000L))
     });
 }
Exemple #6
0
        private static ObjectAction GetSatelliteMoveAndDestroyAction(
            long initialAngleInMillidegrees,
            GuidGenerator guidGenerator)
        {
            string angleVariableName = guidGenerator.NextGuid();

            ObjectAction initializeAngleVariableAction = ObjectActionGenerator.DoOnce(
                ObjectAction.SetNumericVariable(angleVariableName, MathExpression.Constant(initialAngleInMillidegrees)));

            ObjectAction updateAngleVariableAction = ObjectAction.Union(
                ObjectAction.SetNumericVariable(
                    angleVariableName,
                    MathExpression.Add(MathExpression.Variable(angleVariableName), MathExpression.Multiply(MathExpression.Constant(50), MathExpression.ElapsedMillisecondsPerIteration()))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(angleVariableName), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(angleVariableName, MathExpression.Subtract(MathExpression.Variable(angleVariableName), MathExpression.Constant(360 * 1000)))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(angleVariableName), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(angleVariableName, MathExpression.Constant(0))));

            long radius = 110;

            ObjectAction setPositionAction = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(MathExpression.ParentXMillis(), MathExpression.Multiply(MathExpression.Constant(radius), MathExpression.CosineScaled(MathExpression.Multiply(MathExpression.Variable(angleVariableName), MathExpression.Constant(-1))))),
                yMillis: MathExpression.Add(MathExpression.ParentYMillis(), MathExpression.Multiply(MathExpression.Constant(radius), MathExpression.SineScaled(MathExpression.Multiply(MathExpression.Variable(angleVariableName), MathExpression.Constant(-1))))));

            string facingAngleVariableName = guidGenerator.NextGuid();

            ObjectAction initializeFacingAngleVariableAction = ObjectActionGenerator.DoOnce(
                ObjectAction.SetNumericVariable(facingAngleVariableName, MathExpression.RandomInteger(360 * 1000)));
            ObjectAction updateFacingAngleVariableAction = ObjectAction.Union(
                ObjectAction.SetNumericVariable(
                    facingAngleVariableName,
                    MathExpression.Add(MathExpression.Variable(facingAngleVariableName), MathExpression.Multiply(MathExpression.Constant(500), MathExpression.ElapsedMillisecondsPerIteration()))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(facingAngleVariableName), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(facingAngleVariableName, MathExpression.Subtract(MathExpression.Variable(facingAngleVariableName), MathExpression.Constant(360 * 1000)))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(facingAngleVariableName), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(facingAngleVariableName, MathExpression.Constant(0))));
            ObjectAction setFacingDirectionAction = ObjectAction.SetFacingDirection(MathExpression.Multiply(MathExpression.Variable(facingAngleVariableName), MathExpression.Constant(-1)));

            ObjectAction destroyAction = ObjectAction.Condition(
                condition: BooleanExpression.IsParentDestroyed(),
                action: ObjectAction.Destroy());

            return(ObjectAction.Union(
                       initializeAngleVariableAction,
                       updateAngleVariableAction,
                       setPositionAction,
                       initializeFacingAngleVariableAction,
                       updateFacingAngleVariableAction,
                       setFacingDirectionAction,
                       destroyAction));
        }
Exemple #7
0
        private static ObjectAction GetShootBulletAction(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            IMathExpression initialShootCooldownInMillis = MathExpression.RandomInteger(2750);
            IMathExpression shootCooldownInMillis        = MathExpression.Add(1750, MathExpression.RandomInteger(1000));

            string cooldownVariableName    = guidGenerator.NextGuid();
            string childObjectTemplateName = guidGenerator.NextGuid();
            string enemyBulletSpriteName   = guidGenerator.NextGuid();

            IMathExpression facingAngleInMillidegrees = DTDanmakuMath.GetMovementDirectionInMillidegrees(
                currentX: MathExpression.XMillis(),
                currentY: MathExpression.YMillis(),
                desiredX: MathExpression.PlayerXMillis(),
                desiredY: MathExpression.Min(MathExpression.PlayerYMillis(), 300 * 1000));

            DTDanmakuMath.MathExpressionOffset deltaXAndY = DTDanmakuMath.GetOffset(
                millipixels: MathExpression.Constant(40000),
                movementDirectionInMillidegrees: facingAngleInMillidegrees);

            ObjectAction initialStartCooldownAction = ObjectAction.SetNumericVariable(cooldownVariableName, initialShootCooldownInMillis);
            ObjectAction startCooldownAction        = ObjectAction.SetNumericVariable(cooldownVariableName, shootCooldownInMillis);
            ObjectAction decrementCooldownAction    = ObjectAction.SetNumericVariable(cooldownVariableName, MathExpression.Subtract(MathExpression.Variable(cooldownVariableName), MathExpression.ElapsedMillisecondsPerIteration()));
            ObjectAction createBulletAction         = ObjectAction.SpawnChild(
                childXMillis: MathExpression.Add(MathExpression.XMillis(), deltaXAndY.DeltaXInMillipixels),
                childYMillis: MathExpression.Add(MathExpression.YMillis(), deltaXAndY.DeltaYInMillipixels),
                childObjectTemplateName: childObjectTemplateName,
                childInitialNumericVariables: null,
                childInitialBooleanVariables: null);

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -4000, upperXMillis: 4000, lowerYMillis: -4000, upperYMillis: 4000));

            enemyObjectTemplates.Add(childObjectTemplateName,
                                     EnemyObjectTemplate.EnemyBullet(
                                         action: ObjectAction.Union(GetBulletMovementAction(guidGenerator: guidGenerator), GetBulletAnimationAction(guidGenerator: guidGenerator)),
                                         initialMilliHP: null,
                                         damageBoxes: null,
                                         collisionBoxes: collisionBoxes,
                                         spriteName: enemyBulletSpriteName));

            spriteNameToImageDictionary.Add(enemyBulletSpriteName, DTDanmakuImage.EliteSniperEnemyBullet);

            var createBulletWhenCooldownFinishedAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(cooldownVariableName), MathExpression.Constant(0)),
                action: ObjectAction.Union(startCooldownAction, createBulletAction));

            return(ObjectAction.ConditionalNextAction(
                       currentAction: initialStartCooldownAction,
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.Union(decrementCooldownAction, createBulletWhenCooldownFinishedAction)));
        }
Exemple #8
0
        public static ObjectAction SpawnEliteOrbiterEnemy(
            IMathExpression xMillis,
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            ObjectAction moveAction = GetMoveAction(
                xMillis: xMillis);

            ObjectAction destroyAction = ObjectActionGenerator.DestroyWhenHpIsZeroAndMaybeDropPowerUp(
                chanceToDropPowerUpInMilliPercent: 15 * 1000,
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                soundNameToSoundDictionary: soundNameToSoundDictionary,
                guidGenerator: guidGenerator);

            string spriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(spriteName, DTDanmakuImage.EliteOrbiterEnemyShip);

            List <ObjectBox> damageBoxes = new List <ObjectBox>();

            damageBoxes.Add(new ObjectBox(lowerXMillis: -68000, upperXMillis: 68000, lowerYMillis: -30000, upperYMillis: 50000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -46000, upperXMillis: 46000, lowerYMillis: -48000, upperYMillis: 68000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -26000, upperXMillis: 26000, lowerYMillis: -68000, upperYMillis: 74000));

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -58000, upperXMillis: 58000, lowerYMillis: -35000, upperYMillis: 50000));

            ObjectAction spawnOrbiterSatellitesAction = GetSpawnOrbiterSatellitesAction(
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            EnemyObjectTemplate enemyObjectTemplate = EnemyObjectTemplate.Enemy(
                action: ObjectAction.Union(moveAction, spawnOrbiterSatellitesAction, destroyAction),
                initialMilliHP: MathExpression.Add(MathExpression.Constant(45000), MathExpression.RandomInteger(MathExpression.Constant(15000))),
                damageBoxes: damageBoxes,
                collisionBoxes: collisionBoxes,
                spriteName: spriteName);

            string templateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(templateName, enemyObjectTemplate);

            return(ObjectAction.SpawnChild(
                       childXMillis: MathExpression.Constant(-1000 * 1000),
                       childYMillis: MathExpression.Constant(-1000 * 1000),
                       childObjectTemplateName: templateName,
                       childInitialNumericVariables: null,
                       childInitialBooleanVariables: null));
        }
Exemple #9
0
        public static ObjectAction MoveToSpecifiedLocations(
            // enemy will teleport to this initial location
            long initialXMillis,
            long initialYMillis,
            List <Tuple <long, long> > movementPath,
            long speedInPixelsPerSecond,
            bool shouldStrafe,
            bool shouldDestroyAtEndOfMovementPath,
            GuidGenerator guidGenerator)
        {
            ObjectAction currentAction = shouldDestroyAtEndOfMovementPath
                                ? ObjectAction.Destroy()
                                : ObjectActionGenerator.Noop();

            for (int i = movementPath.Count - 1; i >= 0; i--)
            {
                long endingX   = movementPath[i].Item1;
                long endingY   = movementPath[i].Item2;
                long startingX = i == 0
                                        ? initialXMillis
                                        : movementPath[i - 1].Item1;
                long startingY = i == 0
                                        ? initialYMillis
                                        : movementPath[i - 1].Item2;

                Tuple <ObjectAction, BooleanExpression> helper = MoveToSpecifiedLocations_Helper(
                    startingXMillis: startingX,
                    startingYMillis: startingY,
                    endingXMillis: endingX,
                    endingYMillis: endingY,
                    speedInPixelsPerSecond: speedInPixelsPerSecond,
                    shouldStrafe: shouldStrafe,
                    guidGenerator: guidGenerator);

                currentAction = ObjectAction.ConditionalNextAction(
                    currentAction: helper.Item1,
                    condition: helper.Item2,
                    nextAction: currentAction);
            }

            ObjectAction teleportToInitialLocation = ObjectAction.SetPosition(
                xMillis: MathExpression.Constant(initialXMillis),
                yMillis: MathExpression.Constant(initialYMillis));

            return(ObjectAction.ConditionalNextAction(
                       currentAction: teleportToInitialLocation,
                       condition: BooleanExpression.True(),
                       nextAction: currentAction));
        }
Exemple #10
0
        private static ObjectAction GetPhase2Action(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            string milliHpVariable = guidGenerator.NextGuid();
            string amountOfDamageTakenVariableName = guidGenerator.NextGuid();

            ObjectAction setInitialDamageTakenAction = ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(amountOfDamageTakenVariableName, MathExpression.Constant(0)));

            ObjectAction setInitialMilliHpVariable = ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(milliHpVariable, MathExpression.MilliHP()));

            ObjectAction setDamageTakenVariableAction = ObjectAction.SetNumericVariable(
                amountOfDamageTakenVariableName,
                MathExpression.Add(
                    MathExpression.Variable(amountOfDamageTakenVariableName),
                    MathExpression.Subtract(MathExpression.Variable(milliHpVariable), MathExpression.MilliHP())));

            ObjectAction setMilliHpVariable = ObjectAction.SetNumericVariable(milliHpVariable, MathExpression.MilliHP());

            long phase2InitialMilliHp = 200 * 1000;

            IMathExpression currentMilliHp = MathExpression.Max(
                MathExpression.Subtract(MathExpression.Constant(phase2InitialMilliHp), MathExpression.Variable(amountOfDamageTakenVariableName)),
                MathExpression.Constant(0));

            ObjectAction displayHpBarAction = ObjectAction.DisplayBossHealthBar(
                healthBarMeterNumber: MathExpression.Constant(2),
                healthBarMilliPercentage: MathExpression.Divide(MathExpression.Multiply(currentMilliHp, MathExpression.Constant(100 * 1000)), MathExpression.Constant(phase2InitialMilliHp)));

            ObjectAction goToPhase3Action = ObjectAction.Condition(
                condition: BooleanExpression.Equal(currentMilliHp, MathExpression.Constant(0)),
                action: ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(CurrentPhaseVariableName, MathExpression.Constant(3))));

            ObjectAction shootBulletAction = Phase2ShootAction(
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            return(ObjectAction.Union(
                       setInitialDamageTakenAction,
                       setInitialMilliHpVariable,
                       setDamageTakenVariableAction,
                       setMilliHpVariable,
                       displayHpBarAction,
                       GetMoveAction(guidGenerator: guidGenerator),
                       goToPhase3Action,
                       shootBulletAction));
        }
Exemple #11
0
        public static ObjectAction Delay(
            ObjectAction action,
            long milliseconds,
            GuidGenerator guidGenerator)
        {
            string guid = guidGenerator.NextGuid();

            return(ObjectAction.ConditionalNextAction(
                       currentAction: ObjectAction.SetNumericVariable(guid, MathExpression.Constant(0)),
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.ConditionalNextAction(
                           currentAction: ObjectAction.SetNumericVariable(guid, MathExpression.Add(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Variable(guid))),
                           condition: BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(guid), MathExpression.Constant(milliseconds)),
                           nextAction: action)));
        }
Exemple #12
0
        public static ObjectAction ShootBulletStraightDownAction(
            IMathExpression initialShootCooldownInMillis,
            IMathExpression shootCooldownInMillis,
            // Where the bullet should spawn (relative to the enemy shooting the bullet)
            long xOffset,
            long yOffset,
            long bulletSpeedInPixelsPerSecond,
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            string cooldownVariableName    = guidGenerator.NextGuid();
            string childObjectTemplateName = guidGenerator.NextGuid();
            string enemyBulletSpriteName   = guidGenerator.NextGuid();

            ObjectAction initialStartCooldownAction = ObjectAction.SetNumericVariable(cooldownVariableName, initialShootCooldownInMillis);
            ObjectAction startCooldownAction        = ObjectAction.SetNumericVariable(cooldownVariableName, shootCooldownInMillis);
            ObjectAction decrementCooldownAction    = ObjectAction.SetNumericVariable(cooldownVariableName, MathExpression.Subtract(MathExpression.Variable(cooldownVariableName), MathExpression.ElapsedMillisecondsPerIteration()));
            ObjectAction createBulletAction         = ObjectAction.SpawnChild(
                childXMillis: MathExpression.Add(MathExpression.XMillis(), MathExpression.Constant(xOffset)),
                childYMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Constant(yOffset)),
                childObjectTemplateName: childObjectTemplateName,
                childInitialNumericVariables: null,
                childInitialBooleanVariables: null);

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -3000, upperXMillis: 3000, lowerYMillis: -23000, upperYMillis: 23000));

            enemyObjectTemplates.Add(childObjectTemplateName,
                                     EnemyObjectTemplate.EnemyBullet(
                                         action: BulletStraightDownAction(bulletSpeedInPixelsPerSecond: bulletSpeedInPixelsPerSecond),
                                         initialMilliHP: null,
                                         damageBoxes: null,
                                         collisionBoxes: collisionBoxes,
                                         spriteName: enemyBulletSpriteName));

            spriteNameToImageDictionary.Add(enemyBulletSpriteName, DTDanmakuImage.EnemyBullet);

            var createBulletWhenCooldownFinishedAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(cooldownVariableName), MathExpression.Constant(0)),
                action: ObjectAction.Union(startCooldownAction, createBulletAction));

            return(ObjectAction.ConditionalNextAction(
                       currentAction: initialStartCooldownAction,
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.Union(decrementCooldownAction, createBulletWhenCooldownFinishedAction)));
        }
Exemple #13
0
        private static ObjectAction GetBulletAnimationAction(
            GuidGenerator guidGenerator)
        {
            string variableName = guidGenerator.NextGuid();

            return(ObjectAction.Union(
                       ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(variableName, MathExpression.RandomInteger(360 * 1000))),
                       ObjectAction.SetNumericVariable(variableName, MathExpression.Add(MathExpression.Variable(variableName), MathExpression.Multiply(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Constant(315)))),
                       ObjectAction.Condition(
                           condition: BooleanExpression.GreaterThan(MathExpression.Variable(variableName), MathExpression.Constant(360 * 1000)),
                           action: ObjectAction.SetNumericVariable(variableName, MathExpression.Subtract(MathExpression.Variable(variableName), MathExpression.Constant(360 * 1000)))),
                       ObjectAction.Condition(
                           condition: BooleanExpression.GreaterThan(MathExpression.Variable(variableName), MathExpression.Constant(360 * 1000)),
                           action: ObjectAction.SetNumericVariable(variableName, MathExpression.Constant(0))),
                       ObjectAction.SetFacingDirection(MathExpression.Multiply(MathExpression.Variable(variableName), MathExpression.Constant(-1)))));
        }
Exemple #14
0
        /*
         *      When (currentX, currentY) == (desiredX, desiredY), the resulting math expression is arbitrary
         *      but is guaranteed not to error.
         */
        public static IMathExpression GetMovementDirectionInMillidegrees(
            IMathExpression currentX,
            IMathExpression currentY,
            IMathExpression desiredX,
            IMathExpression desiredY)
        {
            IMathExpression deltaX = MathExpression.Subtract(desiredX, currentX);
            IMathExpression deltaY = MathExpression.Subtract(desiredY, currentY);

            IMathExpression angleInMillidegrees = MathExpression.ArcTangentScaled(x: deltaX, y: deltaY, changeUndefinedOutputToZero: true);
            IMathExpression angle2 = MathExpression.Add(
                MathExpression.Multiply(angleInMillidegrees, MathExpression.Constant(-1)),
                MathExpression.Constant(90 * 1000));

            return(angle2);
        }
Exemple #15
0
        private static ObjectAction Phase3ShootAction(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            string angleVariable         = guidGenerator.NextGuid();
            string shootCooldownVariable = guidGenerator.NextGuid();

            ObjectAction initializeAngleVariable = ObjectActionGenerator.DoOnce(
                ObjectAction.SetNumericVariable(angleVariable, MathExpression.Constant(0)));

            ObjectAction updateAngleVariableAction = ObjectAction.Union(
                ObjectAction.SetNumericVariable(
                    angleVariable,
                    MathExpression.Add(MathExpression.Variable(angleVariable), MathExpression.Multiply(MathExpression.Constant(431), MathExpression.ElapsedMillisecondsPerIteration()))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(angleVariable, MathExpression.Subtract(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)))),
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThan(MathExpression.Variable(angleVariable), MathExpression.Constant(360 * 1000)),
                    action: ObjectAction.SetNumericVariable(angleVariable, MathExpression.Constant(0))));

            ObjectAction createBulletAction1 = SpawnPhase3Bullet(
                bulletDirectionInMillidegrees: MathExpression.Multiply(MathExpression.ParentVariable(angleVariable), MathExpression.Constant(1)),
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);
            ObjectAction createBulletAction2 = SpawnPhase3Bullet(
                bulletDirectionInMillidegrees: MathExpression.Multiply(MathExpression.ParentVariable(angleVariable), MathExpression.Constant(-1)),
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            IMathExpression shootCooldownInMillis   = MathExpression.Constant(20);
            ObjectAction    startCooldownAction     = ObjectAction.SetNumericVariable(shootCooldownVariable, shootCooldownInMillis);
            ObjectAction    decrementCooldownAction = ObjectAction.SetNumericVariable(shootCooldownVariable, MathExpression.Subtract(MathExpression.Variable(shootCooldownVariable), MathExpression.ElapsedMillisecondsPerIteration()));
            ObjectAction    createBulletWhenCooldownFinishedAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.Variable(shootCooldownVariable), MathExpression.Constant(0)),
                action: ObjectAction.Union(startCooldownAction, createBulletAction1, createBulletAction2));

            return(ObjectAction.Union(
                       initializeAngleVariable,
                       updateAngleVariableAction,
                       ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(shootCooldownVariable, MathExpression.Constant(1000))),
                       decrementCooldownAction,
                       createBulletWhenCooldownFinishedAction));
        }
Exemple #16
0
        public static ObjectAction BulletStraightDownAction(
            long bulletSpeedInPixelsPerSecond)
        {
            var enemyBulletMovementAction = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Add(
                    MathExpression.YMillis(),
                    MathExpression.Multiply(
                        MathExpression.Constant(-bulletSpeedInPixelsPerSecond),
                        MathExpression.ElapsedMillisecondsPerIteration())));

            var enemyBulletDestroyAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.YMillis(), MathExpression.Constant(-700 * 1000)),
                action: ObjectAction.Destroy());

            return(ObjectAction.Union(enemyBulletMovementAction, enemyBulletDestroyAction));
        }
Exemple #17
0
        public static ObjectAction SpawnBossEnemy(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            string spriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(spriteName, DTDanmakuImage.Boss);

            List <ObjectBox> damageBoxes = new List <ObjectBox>();

            damageBoxes.Add(new ObjectBox(lowerXMillis: -96500, upperXMillis: 96500, lowerYMillis: -10000, upperYMillis: 30000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -71500, upperXMillis: 71500, lowerYMillis: -35000, upperYMillis: 30000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -50000, upperXMillis: 50000, lowerYMillis: -81000, upperYMillis: 48000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -35000, upperXMillis: 35000, lowerYMillis: 0, upperYMillis: 68000));

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -20000, upperXMillis: 20000, lowerYMillis: -50000, upperYMillis: 50000));
            collisionBoxes.Add(new ObjectBox(lowerXMillis: -50000, upperXMillis: 50000, lowerYMillis: -20000, upperYMillis: 20000));

            EnemyObjectTemplate enemyObjectTemplate = EnemyObjectTemplate.Enemy(
                action: GetBossAction(
                    spriteNameToImageDictionary: spriteNameToImageDictionary,
                    enemyObjectTemplates: enemyObjectTemplates,
                    soundNameToSoundDictionary: soundNameToSoundDictionary,
                    guidGenerator: guidGenerator),
                initialMilliHP: MathExpression.Constant(50L * 1000L * 1000L * 1000L * 1000L),
                damageBoxes: damageBoxes,
                collisionBoxes: collisionBoxes,
                spriteName: spriteName);

            string templateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(templateName, enemyObjectTemplate);

            return(ObjectAction.SpawnChild(
                       childXMillis: MathExpression.Constant(-1000 * 1000),
                       childYMillis: MathExpression.Constant(-1000 * 1000),
                       childObjectTemplateName: templateName,
                       childInitialNumericVariables: null,
                       childInitialBooleanVariables: null));
        }
Exemple #18
0
        private static ObjectAction GetMoveAction(IMathExpression xMillis)
        {
            ObjectAction teleportToInitialLocation = ObjectAction.SetPosition(
                xMillis: xMillis,
                yMillis: MathExpression.Constant(900 * 1000));

            ObjectAction moveDown = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Subtract(MathExpression.YMillis(), MathExpression.Multiply(MathExpression.Constant(35), MathExpression.ElapsedMillisecondsPerIteration())));

            ObjectAction destroyAction = ObjectAction.Condition(
                condition: BooleanExpression.LessThanOrEqualTo(MathExpression.YMillis(), -200 * 1000),
                action: ObjectAction.Destroy());

            return(ObjectAction.Union(
                       ObjectActionGenerator.DoOnce(teleportToInitialLocation),
                       moveDown,
                       destroyAction));
        }
Exemple #19
0
        private static ObjectAction GetSpawnOrbiterSatellitesAction(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            string spriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(spriteName, DTDanmakuImage.EliteOrbiterSatellite);

            List <ObjectAction> objectActions = new List <ObjectAction>();

            for (long i = 0; i < 5; i++)
            {
                EnemyObjectTemplate orbiterSatelliteTemplate = EnemyObjectTemplate.EnemyBullet(
                    action: ObjectAction.Union(
                        GetSatelliteMoveAndDestroyAction(
                            initialAngleInMillidegrees: 72L * 1000L * i,
                            guidGenerator: guidGenerator),
                        GetSatelliteShootAction(
                            spriteNameToImageDictionary: spriteNameToImageDictionary,
                            enemyObjectTemplates: enemyObjectTemplates,
                            guidGenerator: guidGenerator)),
                    initialMilliHP: null,
                    damageBoxes: null,
                    collisionBoxes: null,
                    spriteName: spriteName);

                string templateName = guidGenerator.NextGuid();
                enemyObjectTemplates.Add(templateName, orbiterSatelliteTemplate);

                ObjectAction spawnSatelliteAction = ObjectAction.SpawnChild(
                    childXMillis: MathExpression.Constant(-1000 * 1000),
                    childYMillis: MathExpression.Constant(-1000 * 1000),
                    childObjectTemplateName: templateName,
                    childInitialNumericVariables: null,
                    childInitialBooleanVariables: null);

                objectActions.Add(spawnSatelliteAction);
            }

            return(ObjectActionGenerator.DoOnce(ObjectAction.Union(objectActions)));
        }
Exemple #20
0
        private static Tuple <ObjectAction, EnemyObjectTemplate> SpawnOneDestructionSpriteImage(
            long startMilliseconds,
            long endMilliseconds,
            string childObjectTemplateName,
            string spriteName,
            bool isLast)
        {
            List <ObjectAction> destroyActions = new List <ObjectAction>();

            destroyActions.Add(ObjectAction.Destroy());
            destroyActions.Add(ObjectAction.DestroyParent());

            ObjectAction destroySelfAction = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    leftSide: MathExpression.ParentVariable(elapsedTimeInMillisVariableName),
                    rightSide: MathExpression.Constant(endMilliseconds)),
                action: isLast ? ObjectAction.Union(destroyActions) : ObjectAction.Destroy());

            ObjectAction spawnChildAction = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: childObjectTemplateName,
                childInitialNumericVariables: null,
                childInitialBooleanVariables: null);

            ObjectAction delayedSpawnChildAction =
                ObjectAction.Condition(
                    condition: BooleanExpression.GreaterThanOrEqualTo(
                        leftSide: MathExpression.Variable(elapsedTimeInMillisVariableName),
                        rightSide: MathExpression.Constant(startMilliseconds)),
                    action: ObjectActionGenerator.DoOnce(spawnChildAction));

            EnemyObjectTemplate template = EnemyObjectTemplate.Enemy(
                action: destroySelfAction,
                initialMilliHP: null,
                damageBoxes: null,
                collisionBoxes: null,
                spriteName: spriteName);

            return(new Tuple <ObjectAction, EnemyObjectTemplate>(delayedSpawnChildAction, template));
        }
Exemple #21
0
        private static ObjectAction GetBossAction(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            ObjectAction setPhaseVariableAction = ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(CurrentPhaseVariableName, MathExpression.Constant(0)));

            ObjectAction phase0Action = ObjectAction.Condition(
                condition: BooleanExpression.Equal(MathExpression.Variable(CurrentPhaseVariableName), MathExpression.Constant(0)),
                action: GetMoveAction_Phase0());

            ObjectAction phase1Action = ObjectAction.Condition(
                condition: BooleanExpression.Equal(MathExpression.Variable(CurrentPhaseVariableName), MathExpression.Constant(1)),
                action: GetPhase1Action(
                    spriteNameToImageDictionary: spriteNameToImageDictionary,
                    enemyObjectTemplates: enemyObjectTemplates,
                    guidGenerator: guidGenerator));

            ObjectAction phase2Action = ObjectAction.Condition(
                condition: BooleanExpression.Equal(MathExpression.Variable(CurrentPhaseVariableName), MathExpression.Constant(2)),
                action: GetPhase2Action(
                    spriteNameToImageDictionary: spriteNameToImageDictionary,
                    enemyObjectTemplates: enemyObjectTemplates,
                    guidGenerator: guidGenerator));

            ObjectAction phase3Action = ObjectAction.Condition(
                condition: BooleanExpression.Equal(MathExpression.Variable(CurrentPhaseVariableName), MathExpression.Constant(3)),
                action: GetPhase3Action(
                    spriteNameToImageDictionary: spriteNameToImageDictionary,
                    enemyObjectTemplates: enemyObjectTemplates,
                    soundNameToSoundDictionary: soundNameToSoundDictionary,
                    guidGenerator: guidGenerator));

            return(ObjectAction.Union(
                       setPhaseVariableAction,
                       phase0Action,
                       phase1Action,
                       phase2Action,
                       phase3Action));
        }
Exemple #22
0
        private static ObjectAction SpawnBasicEnemy(
            long initialXMillis,
            long initialYMillis,
            List <Tuple <long, long> > movementPath,
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            List <ObjectBox> damageBoxes = new List <ObjectBox>();

            damageBoxes.Add(new ObjectBox(lowerXMillis: -46500, upperXMillis: 46500, lowerYMillis: 0, upperYMillis: 40000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -31500, upperXMillis: 31500, lowerYMillis: -25000, upperYMillis: 40000));
            damageBoxes.Add(new ObjectBox(lowerXMillis: -21500, upperXMillis: 21500, lowerYMillis: -35000, upperYMillis: 40000));

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -10000, upperXMillis: 10000, lowerYMillis: -25000, upperYMillis: 25000));
            collisionBoxes.Add(new ObjectBox(lowerXMillis: -25000, upperXMillis: 25000, lowerYMillis: -10000, upperYMillis: 10000));

            return(ObjectActionGenerator.SpawnEnemyThatMovesToSpecificLocation(
                       initialXMillis: initialXMillis,
                       initialYMillis: initialYMillis,
                       movementPath: movementPath,
                       movementSpeedInPixelsPerSecond: 100,
                       shouldStrafe: true,
                       bulletXOffset: 0,
                       bulletYOffset: -52000,
                       initialShootCooldownInMillis: MathExpression.RandomInteger(5000),
                       shootCooldownInMillis: MathExpression.Add(3000, MathExpression.RandomInteger(2000)),
                       bulletSpeedInPixelsPerSecond: 250,
                       initialMilliHP: MathExpression.Add(MathExpression.Constant(6000), MathExpression.RandomInteger(MathExpression.Constant(5000))),
                       chanceToDropPowerUpInMilliPercent: 15 * 1000,
                       damageBoxes: damageBoxes,
                       collisionBoxes: collisionBoxes,
                       sprite: DTDanmakuImage.BasicEnemyShip,
                       spriteNameToImageDictionary: spriteNameToImageDictionary,
                       enemyObjectTemplates: enemyObjectTemplates,
                       soundNameToSoundDictionary: soundNameToSoundDictionary,
                       guidGenerator: guidGenerator));
        }
Exemple #23
0
        private static ObjectAction GetMoveAction_Phase0()
        {
            ObjectAction teleportToInitialLocation = ObjectActionGenerator.DoOnce(
                ObjectAction.SetPosition(
                    xMillis: MathExpression.Constant(500 * 1000),
                    yMillis: MathExpression.Constant(850 * 1000)));

            ObjectAction moveAction = ObjectAction.Union(
                ObjectAction.StrafeMove(moveToXMillis: MathExpression.XMillis(), moveToYMillis: MathExpression.Constant(0)),
                ObjectAction.SetSpeed(MathExpression.Constant(20)));

            BooleanExpression shouldStopMoving = BooleanExpression.LessThanOrEqualTo(
                MathExpression.YMillis(),
                MathExpression.Constant(500 * 1000));

            ObjectAction stopMovingAction = ObjectAction.SetSpeed(MathExpression.Constant(0));
            ObjectAction setPhaseAction   = ObjectAction.SetNumericVariable(CurrentPhaseVariableName, MathExpression.Constant(1));

            return(ObjectAction.ConditionalNextAction(
                       currentAction: ObjectAction.Union(teleportToInitialLocation, moveAction),
                       condition: shouldStopMoving,
                       nextAction: ObjectActionGenerator.DoOnce(ObjectAction.Union(stopMovingAction, setPhaseAction))));
        }
Exemple #24
0
        private static ObjectAction GetMoveAction(
            GuidGenerator guidGenerator)
        {
            string variableName = guidGenerator.NextGuid();

            ObjectAction initializeVariable = ObjectAction.SetNumericVariable(
                variableName: variableName,
                variableValue: MathExpression.Constant(0));

            ObjectAction incrementVariable = ObjectAction.SetNumericVariable(
                variableName: variableName,
                variableValue: MathExpression.Add(MathExpression.Variable(variableName), MathExpression.ElapsedMillisecondsPerIteration()));

            ObjectAction initializeAndIncrementVariable = ObjectAction.ConditionalNextAction(
                currentAction: initializeVariable,
                condition: BooleanExpression.True(),
                nextAction: incrementVariable);

            ObjectAction teleportToInitialLocation = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(50 * 1000, MathExpression.RandomInteger(900 * 1000)),
                yMillis: MathExpression.Constant(800 * 1000));

            ObjectAction faceTowardsPlayer = ObjectAction.Move(
                moveToXMillis: MathExpression.PlayerXMillis(),
                moveToYMillis: MathExpression.Min(MathExpression.PlayerYMillis(), 300 * 1000));

            ObjectAction setInitialSpeed = ObjectActionGenerator.DoOnce(
                ObjectAction.SetSpeed(
                    speedInMillipixelsPerMillisecond: MathExpression.Constant(60)));

            ObjectAction slowDownSpeed1 = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    1 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(40))));

            ObjectAction slowDownSpeed2 = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    2 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(20))));

            ObjectAction stopMovement = ObjectAction.Condition(
                condition: BooleanExpression.GreaterThanOrEqualTo(
                    MathExpression.Variable(variableName),
                    3 * 1000),
                action: ObjectActionGenerator.DoOnce(
                    ObjectAction.SetSpeed(
                        speedInMillipixelsPerMillisecond: MathExpression.Constant(0))));

            BooleanExpression ShouldLeave1 = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.Variable(variableName),
                10 * 1000);

            ObjectAction leave1 = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Multiply(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Constant(25))));

            ObjectAction leave1ConditionalAction = ObjectAction.Condition(
                condition: ShouldLeave1,
                action: leave1);

            BooleanExpression shouldLeave2 = BooleanExpression.GreaterThanOrEqualTo(
                MathExpression.Variable(variableName),
                11 * 1000);

            ObjectAction leave2 = ObjectAction.SetPosition(
                xMillis: MathExpression.XMillis(),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Multiply(MathExpression.ElapsedMillisecondsPerIteration(), MathExpression.Constant(50))));

            ObjectAction leave2ConditionalAction = ObjectAction.ConditionalNextAction(
                currentAction: leave1ConditionalAction,
                condition: shouldLeave2,
                nextAction: leave2);

            ObjectAction shouldDestroy = ObjectAction.Condition(
                condition: BooleanExpression.And(shouldLeave2, BooleanExpression.GreaterThanOrEqualTo(MathExpression.YMillis(), 800 * 1000)),
                action: ObjectAction.Destroy());

            return(ObjectAction.ConditionalNextAction(
                       currentAction: teleportToInitialLocation,
                       condition: BooleanExpression.True(),
                       nextAction: ObjectAction.Union(faceTowardsPlayer, initializeAndIncrementVariable, setInitialSpeed, slowDownSpeed1, slowDownSpeed2, stopMovement, leave2ConditionalAction, shouldDestroy)));
        }
Exemple #25
0
        private static ObjectAction GetPhase3Action(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            string milliHpVariable = guidGenerator.NextGuid();
            string amountOfDamageTakenVariableName = guidGenerator.NextGuid();

            ObjectAction setInitialDamageTakenAction = ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(amountOfDamageTakenVariableName, MathExpression.Constant(0)));

            ObjectAction setInitialMilliHpVariable = ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(milliHpVariable, MathExpression.MilliHP()));

            ObjectAction setDamageTakenVariableAction = ObjectAction.SetNumericVariable(
                amountOfDamageTakenVariableName,
                MathExpression.Add(
                    MathExpression.Variable(amountOfDamageTakenVariableName),
                    MathExpression.Subtract(MathExpression.Variable(milliHpVariable), MathExpression.MilliHP())));

            ObjectAction setMilliHpVariable = ObjectAction.SetNumericVariable(milliHpVariable, MathExpression.MilliHP());

            long phase3InitialMilliHp = 200 * 1000;

            IMathExpression currentMilliHp = MathExpression.Max(
                MathExpression.Subtract(MathExpression.Constant(phase3InitialMilliHp), MathExpression.Variable(amountOfDamageTakenVariableName)),
                MathExpression.Constant(0));

            ObjectAction displayHpBarAction = ObjectAction.DisplayBossHealthBar(
                healthBarMeterNumber: MathExpression.Constant(1),
                healthBarMilliPercentage: MathExpression.Divide(MathExpression.Multiply(currentMilliHp, MathExpression.Constant(100 * 1000)), MathExpression.Constant(phase3InitialMilliHp)));

            string       soundEffectName = guidGenerator.NextGuid();
            ObjectAction playEnemyDeathSoundEffectAction = ObjectAction.PlaySoundEffect(soundEffectName: soundEffectName);

            soundNameToSoundDictionary.Add(soundEffectName, DTDanmakuSound.EnemyDeath);

            DestructionAnimationGenerator.GenerateDestructionAnimationResult generateDestructionAnimationResult = DestructionAnimationGenerator.GenerateDestructionAnimation(
                orderedSprites: new List <DTDanmakuImage>
            {
                DTDanmakuImage.Explosion1,
                DTDanmakuImage.Explosion2,
                DTDanmakuImage.Explosion3,
                DTDanmakuImage.Explosion4,
                DTDanmakuImage.Explosion5,
                DTDanmakuImage.Explosion6,
                DTDanmakuImage.Explosion7,
                DTDanmakuImage.Explosion8,
                DTDanmakuImage.Explosion9
            },
                millisecondsPerSprite: 20,
                guidGenerator: guidGenerator);

            foreach (var entry in generateDestructionAnimationResult.spriteNameToImageDictionary)
            {
                spriteNameToImageDictionary.Add(entry.Key, entry.Value);
            }
            foreach (var entry in generateDestructionAnimationResult.enemyObjectTemplates)
            {
                enemyObjectTemplates.Add(entry.Key, entry.Value);
            }

            ObjectAction destroyBoss = ObjectAction.Union(
                playEnemyDeathSoundEffectAction,
                generateDestructionAnimationResult.objectAction,
                ObjectAction.Destroy());

            ObjectAction destroyAndEndLevelAction = ObjectAction.Condition(
                condition: BooleanExpression.Equal(currentMilliHp, MathExpression.Constant(0)),
                action: ObjectAction.Union(
                    ObjectAction.EndLevel(),
                    destroyBoss));

            ObjectAction shootBulletAction = Phase3ShootAction(
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            return(ObjectAction.Union(
                       setInitialDamageTakenAction,
                       setInitialMilliHpVariable,
                       setDamageTakenVariableAction,
                       setMilliHpVariable,
                       displayHpBarAction,
                       GetMoveAction(guidGenerator: guidGenerator),
                       destroyAndEndLevelAction,
                       shootBulletAction));
        }
Exemple #26
0
 public static ObjectAction Noop()
 {
     return(ObjectAction.IncreaseSpeed(
                speedInMillipixelsPerMillisecond: MathExpression.Constant(0)));
 }
Exemple #27
0
        // Spawns 12 bullets (30 degrees apart)
        private static ObjectAction SpawnSatelliteBullet(
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            GuidGenerator guidGenerator)
        {
            string singleBulletSpriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(singleBulletSpriteName, DTDanmakuImage.EliteOrbiterEnemyBullet);

            long buffer = 100;

            BooleanExpression shouldDestroySingleBullet = BooleanExpression.Or(
                BooleanExpression.GreaterThan(MathExpression.XMillis(), MathExpression.Constant((1000 + buffer) * 1000)),
                BooleanExpression.LessThan(MathExpression.XMillis(), MathExpression.Constant((0 - buffer) * 1000)),
                BooleanExpression.GreaterThan(MathExpression.YMillis(), MathExpression.Constant((700 + buffer) * 1000)),
                BooleanExpression.LessThan(MathExpression.YMillis(), MathExpression.Constant((0 - buffer) * 1000)));

            ObjectAction destroySingleBulletAction = ObjectAction.Condition(
                condition: shouldDestroySingleBullet,
                action: ObjectAction.Destroy());

            DTDanmakuMath.MathExpressionOffset singleBulletOffset = DTDanmakuMath.GetOffset(
                millipixels: MathExpression.Multiply(MathExpression.Constant(100), MathExpression.ElapsedMillisecondsPerIteration()),
                movementDirectionInMillidegrees: MathExpression.Variable("direction"));

            List <ObjectBox> collisionBoxes = new List <ObjectBox>();

            collisionBoxes.Add(new ObjectBox(lowerXMillis: -3000, upperXMillis: 3000, lowerYMillis: -5000, upperYMillis: 5000));
            collisionBoxes.Add(new ObjectBox(lowerXMillis: -5000, upperXMillis: 5000, lowerYMillis: -3000, upperYMillis: 3000));

            EnemyObjectTemplate singleBulletTemplate = EnemyObjectTemplate.EnemyBullet(
                action: ObjectAction.Union(
                    ObjectAction.SetFacingDirection(MathExpression.Variable("direction")),
                    ObjectAction.SetPosition(
                        xMillis: MathExpression.Add(MathExpression.XMillis(), singleBulletOffset.DeltaXInMillipixels),
                        yMillis: MathExpression.Add(MathExpression.YMillis(), singleBulletOffset.DeltaYInMillipixels)),
                    destroySingleBulletAction),
                initialMilliHP: null,
                damageBoxes: null,
                collisionBoxes: collisionBoxes,
                spriteName: singleBulletSpriteName);

            string singleBulletTemplateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(singleBulletTemplateName, singleBulletTemplate);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables1 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables1.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(0))));

            ObjectAction spawnSingleBulletAction1 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables1,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables2 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables2.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(30 * 1000))));

            ObjectAction spawnSingleBulletAction2 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables2,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables3 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables3.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(60 * 1000))));

            ObjectAction spawnSingleBulletAction3 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables3,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables4 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables4.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(90 * 1000))));

            ObjectAction spawnSingleBulletAction4 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables4,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables5 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables5.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(120 * 1000))));

            ObjectAction spawnSingleBulletAction5 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables5,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables6 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables6.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(150 * 1000))));

            ObjectAction spawnSingleBulletAction6 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables6,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables7 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables7.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(180 * 1000))));

            ObjectAction spawnSingleBulletAction7 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables7,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables8 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables8.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(210 * 1000))));

            ObjectAction spawnSingleBulletAction8 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables8,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables9 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables9.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(240 * 1000))));

            ObjectAction spawnSingleBulletAction9 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables9,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables10 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables10.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(270 * 1000))));

            ObjectAction spawnSingleBulletAction10 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables10,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables11 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables11.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(300 * 1000))));

            ObjectAction spawnSingleBulletAction11 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables11,
                childInitialBooleanVariables: null);

            List <ObjectAction.InitialChildNumericVariableInfo> initialNumericVariables12 = new List <ObjectAction.InitialChildNumericVariableInfo>();

            initialNumericVariables12.Add(new ObjectAction.InitialChildNumericVariableInfo(name: "direction", value: MathExpression.Add(MathExpression.Variable("random offset"), MathExpression.Constant(330 * 1000))));

            ObjectAction spawnSingleBulletAction12 = ObjectAction.SpawnChild(
                childXMillis: MathExpression.XMillis(),
                childYMillis: MathExpression.YMillis(),
                childObjectTemplateName: singleBulletTemplateName,
                childInitialNumericVariables: initialNumericVariables12,
                childInitialBooleanVariables: null);

            List <ObjectAction> actionList = new List <ObjectAction>();

            actionList.Add(ObjectAction.SetNumericVariable("random offset", MathExpression.RandomInteger(MathExpression.Constant(360 * 1000))));
            actionList.Add(spawnSingleBulletAction1);
            actionList.Add(spawnSingleBulletAction2);
            actionList.Add(spawnSingleBulletAction3);
            actionList.Add(spawnSingleBulletAction4);
            actionList.Add(spawnSingleBulletAction5);
            actionList.Add(spawnSingleBulletAction6);
            actionList.Add(spawnSingleBulletAction7);
            actionList.Add(spawnSingleBulletAction8);
            actionList.Add(spawnSingleBulletAction9);
            actionList.Add(spawnSingleBulletAction10);
            actionList.Add(spawnSingleBulletAction11);
            actionList.Add(spawnSingleBulletAction12);
            actionList.Add(ObjectAction.Destroy());

            EnemyObjectTemplate placeholderTemplate = EnemyObjectTemplate.Placeholder(
                action: ObjectAction.Union(actionList));

            string placeholderTemplateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(placeholderTemplateName, placeholderTemplate);

            return(ObjectAction.SpawnChild(
                       childXMillis: MathExpression.XMillis(),
                       childYMillis: MathExpression.YMillis(),
                       childObjectTemplateName: placeholderTemplateName,
                       childInitialNumericVariables: null,
                       childInitialBooleanVariables: null));
        }
Exemple #28
0
        /*
         *      If (currentX, currentY) == (desiredX, desiredY), then
         *      the resulting movement direction is arbitrary.
         */
        public static ObjectAction MoveTowardsLocation(
            IMathExpression currentX,
            IMathExpression currentY,
            IMathExpression desiredX,
            IMathExpression desiredY,

            /*
             *      Note that movement speed is not affected by shouldSnapshot
             */
            IMathExpression movementSpeedInPixelsPerSecond,

            /*
             *      When true, will decide movement direction on the first frame, and keep that direction.
             *      When false, will continuously move towards (desiredX, desiredY)
             */
            bool shouldSnapshot,
            GuidGenerator guidGenerator)
        {
            string deltaXVariable = guidGenerator.NextGuid();
            string deltaYVariable = guidGenerator.NextGuid();

            ObjectAction setDeltaX = ObjectAction.SetNumericVariable(deltaXVariable, MathExpression.Subtract(desiredX, currentX));
            ObjectAction setDeltaY = ObjectAction.SetNumericVariable(deltaYVariable, MathExpression.Subtract(desiredY, currentY));

            BooleanExpression areDeltasBothZero = BooleanExpression.And(
                BooleanExpression.Equal(MathExpression.Variable(deltaXVariable), MathExpression.Constant(0)),
                BooleanExpression.Equal(MathExpression.Variable(deltaYVariable), MathExpression.Constant(0)));

            string angleInMillidegreesVariable = guidGenerator.NextGuid();

            ObjectAction setAngle = ObjectAction.Union(
                shouldSnapshot ? ObjectActionGenerator.DoOnce(setDeltaX) : setDeltaX,
                shouldSnapshot ? ObjectActionGenerator.DoOnce(setDeltaY) : setDeltaY,
                ObjectAction.Condition(
                    condition: areDeltasBothZero,
                    action: ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Constant(0))),
                ObjectAction.Condition(
                    condition: BooleanExpression.Not(areDeltasBothZero),
                    action: ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.ArcTangentScaled(MathExpression.Variable(deltaXVariable), MathExpression.Variable(deltaYVariable), false))),
                ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Multiply(MathExpression.Variable(angleInMillidegreesVariable), MathExpression.Constant(-1))),
                ObjectAction.SetNumericVariable(angleInMillidegreesVariable, MathExpression.Add(MathExpression.Variable(angleInMillidegreesVariable), 90 * 1000)));

            IMathExpression xMillis =
                MathExpression.Divide(
                    MathExpression.Multiply(
                        movementSpeedInPixelsPerSecond,
                        MathExpression.ElapsedMillisecondsPerIteration(),
                        MathExpression.SineScaled(MathExpression.Variable(angleInMillidegreesVariable))),
                    MathExpression.Constant(1000));
            IMathExpression yMillis =
                MathExpression.Divide(
                    MathExpression.Multiply(
                        movementSpeedInPixelsPerSecond,
                        MathExpression.ElapsedMillisecondsPerIteration(),
                        MathExpression.CosineScaled(MathExpression.Variable(angleInMillidegreesVariable))),
                    MathExpression.Constant(1000));

            string       xMillisVariable    = guidGenerator.NextGuid();
            string       yMillisVariable    = guidGenerator.NextGuid();
            ObjectAction setXMillisVariable = shouldSnapshot
                                ? ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(xMillisVariable, xMillis))
                                : ObjectAction.SetNumericVariable(xMillisVariable, xMillis);
            ObjectAction setYMillisVariable = shouldSnapshot
                                ? ObjectActionGenerator.DoOnce(ObjectAction.SetNumericVariable(yMillisVariable, yMillis))
                                : ObjectAction.SetNumericVariable(yMillisVariable, yMillis);

            return(ObjectAction.Union(
                       setAngle,
                       setXMillisVariable,
                       setYMillisVariable,
                       ObjectAction.SetPosition(
                           xMillis: MathExpression.Add(MathExpression.XMillis(), MathExpression.Variable(xMillisVariable)),
                           yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Variable(yMillisVariable)))));
        }
Exemple #29
0
        public static ObjectAction SpawnEnemyThatMovesToSpecificLocation(
            long initialXMillis,
            long initialYMillis,
            List <Tuple <long, long> > movementPath,
            long movementSpeedInPixelsPerSecond,
            bool shouldStrafe,
            long bulletXOffset,
            long bulletYOffset,
            IMathExpression initialShootCooldownInMillis,
            IMathExpression shootCooldownInMillis,
            long bulletSpeedInPixelsPerSecond,
            IMathExpression initialMilliHP,
            long chanceToDropPowerUpInMilliPercent,  // ranges from 0 (meaning 0%) to 100,000 (meaning 100%)
            List <ObjectBox> damageBoxes,            // nullable
            List <ObjectBox> collisionBoxes,         // nullable
            DTDanmakuImage sprite,
            Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary,
            Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates,
            Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary,
            GuidGenerator guidGenerator)
        {
            ObjectAction moveAction = MoveToSpecifiedLocations(
                initialXMillis: initialXMillis,
                initialYMillis: initialYMillis,
                movementPath: movementPath,
                speedInPixelsPerSecond: movementSpeedInPixelsPerSecond,
                shouldStrafe: shouldStrafe,
                shouldDestroyAtEndOfMovementPath: true,
                guidGenerator: guidGenerator);

            ObjectAction shootAction = ShootBulletStraightDownAction(
                initialShootCooldownInMillis: initialShootCooldownInMillis,
                shootCooldownInMillis: shootCooldownInMillis,
                xOffset: bulletXOffset,
                yOffset: bulletYOffset,
                bulletSpeedInPixelsPerSecond: bulletSpeedInPixelsPerSecond,
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                guidGenerator: guidGenerator);

            ObjectAction destroyAction = DestroyWhenHpIsZeroAndMaybeDropPowerUp(
                chanceToDropPowerUpInMilliPercent: chanceToDropPowerUpInMilliPercent,
                spriteNameToImageDictionary: spriteNameToImageDictionary,
                enemyObjectTemplates: enemyObjectTemplates,
                soundNameToSoundDictionary: soundNameToSoundDictionary,
                guidGenerator: guidGenerator);

            string spriteName = guidGenerator.NextGuid();

            spriteNameToImageDictionary.Add(spriteName, sprite);

            EnemyObjectTemplate enemyObjectTemplate = EnemyObjectTemplate.Enemy(
                action: ObjectAction.Union(moveAction, shootAction, destroyAction),
                initialMilliHP: initialMilliHP,
                damageBoxes: damageBoxes,
                collisionBoxes: collisionBoxes,
                spriteName: spriteName);

            string templateName = guidGenerator.NextGuid();

            enemyObjectTemplates.Add(templateName, enemyObjectTemplate);

            return(ObjectAction.SpawnChild(
                       childXMillis: MathExpression.Constant(initialXMillis),
                       childYMillis: MathExpression.Constant(initialYMillis),
                       childObjectTemplateName: templateName,
                       childInitialNumericVariables: null,
                       childInitialBooleanVariables: null));
        }
Exemple #30
0
        private static Tuple <ObjectAction, BooleanExpression> MoveToSpecifiedLocations_Helper(
            long startingXMillis,
            long startingYMillis,
            long endingXMillis,
            long endingYMillis,
            long speedInPixelsPerSecond,
            bool shouldStrafe,
            GuidGenerator guidGenerator)
        {
            string variableName  = guidGenerator.NextGuid();
            string variableName2 = guidGenerator.NextGuid();

            long?direction = DTDanmakuMath.GetMovementDirectionInMillidegrees(
                currentX: startingXMillis,
                currentY: startingYMillis,
                desiredX: endingXMillis,
                desiredY: endingYMillis);

            if (direction == null)
            {
                throw new Exception();
            }

            DTDanmakuMath.Offset offset = DTDanmakuMath.GetOffset(
                speedInMillipixelsPerMillisecond: speedInPixelsPerSecond, // millipixels/millisecond is equivalent to pixels/second
                movementDirectionInMillidegrees: direction.Value,
                elapsedMillisecondsPerIteration: 1000);                   // Use the 1000 to help prevent rounding issues

            ObjectAction moveAction = ObjectAction.SetPosition(
                xMillis: MathExpression.Add(MathExpression.XMillis(), MathExpression.Divide(MathExpression.Multiply(MathExpression.Constant(offset.DeltaXInMillipixels), MathExpression.ElapsedMillisecondsPerIteration()), MathExpression.Constant(1000))),
                yMillis: MathExpression.Add(MathExpression.YMillis(), MathExpression.Divide(MathExpression.Multiply(MathExpression.Constant(offset.DeltaYInMillipixels), MathExpression.ElapsedMillisecondsPerIteration()), MathExpression.Constant(1000))));

            ObjectAction setDirectionAction = shouldStrafe
                                ? ObjectAction.SetFacingDirection(facingDirectionInMillidegrees: MathExpression.Constant(180 * 1000))
                                : ObjectAction.SetFacingDirection(facingDirectionInMillidegrees: MathExpression.Constant(direction.Value));

            IMathExpression deltaX             = MathExpression.AbsoluteValue(MathExpression.Subtract(MathExpression.XMillis(), MathExpression.Constant(endingXMillis)));
            IMathExpression deltaY             = MathExpression.AbsoluteValue(MathExpression.Subtract(MathExpression.YMillis(), MathExpression.Constant(endingYMillis)));
            IMathExpression totalDelta         = MathExpression.Add(deltaX, deltaY);
            ObjectAction    setDeltaToVariable = ObjectAction.Union(
                ObjectAction.SetNumericVariable(variableName: variableName2, variableValue: MathExpression.Variable(variableName)),
                ObjectAction.SetNumericVariable(variableName: variableName, variableValue: totalDelta));
            BooleanExpression reachedDestination = BooleanExpression.And(
                BooleanExpression.LessThanOrEqualTo(
                    MathExpression.Variable(variableName2),
                    MathExpression.Variable(variableName)),
                BooleanExpression.And(
                    BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(variableName), MathExpression.Constant(0)),
                    BooleanExpression.GreaterThanOrEqualTo(MathExpression.Variable(variableName2), MathExpression.Constant(0))
                    ));

            ObjectAction initializeVariables = ObjectAction.Union(
                ObjectAction.SetNumericVariable(variableName: variableName, variableValue: MathExpression.Constant(-1)),
                ObjectAction.SetNumericVariable(variableName: variableName2, variableValue: MathExpression.Constant(-1)));

            return(new Tuple <ObjectAction, BooleanExpression>(
                       ObjectAction.Union(
                           moveAction,
                           setDirectionAction,
                           ObjectAction.ConditionalNextAction(
                               currentAction: initializeVariables,
                               condition: BooleanExpression.True(),
                               nextAction: setDeltaToVariable)),
                       reachedDestination));
        }