/// <summary> /// This Factory Method produces the next state for every enemy calling it. /// </summary> /// <param name="e"> Used to determine what states are available to the enemy </param> /// <returns> A new EnemyState Child </returns> public static EnemyState GetNextState(Enemy e) { Random rand = new Random(DateTime.Now.Millisecond); for (int i = 0; i < 999990; i++) { } // Use up time so each Enemy's random updates differently int chance = rand.Next(100); if (e is Buzzard) { /*** Buzzard States ***/ Buzzard b = e as Buzzard; // *** Check if lost in a joust against the player *** if (b.coords.y > 450 && b.coords.y < 525 && b.coords.x > 650 && b.coords.x < 800) { return new BuzzardFleeingState() { StateEnemy = b } } ; // *** Check if Buzzard is near the ground of a platform and return new EnemyRunningState like below *** if (b.state is EnemyStandingState) { if (chance % 2 == 0) { if (chance % 10 < 5) { return new EnemyRunningState() { Angle = 0, StateEnemy = b } } ; // Running right state else { return new EnemyRunningState() { Angle = 180, StateEnemy = b } }; // Running left state } else { return(new EnemyFlappingState() { Angle = 90, StateEnemy = b }); // Flapping up state } } else if (b.state is EnemyRunningState) { if (chance < 2) { return new EnemyStandingState() { Angle = b.state.Angle, StateEnemy = b } } ; // Standing state else if (chance < 99) { return new EnemyRunningState() { Angle = b.state.Angle, StateEnemy = b } } ; // Running in same direction state b.state.Angle += 180; if (b.state.Angle > 360) { b.state.Angle -= 360; } return(new EnemyRunningState() { Angle = b.state.Angle, StateEnemy = b }); // Running in opposite direction state } else if (b.state is EnemyFlappingState) { switch (b.state.Angle) { case 90: if (chance / 10 < 2 && chance % 10 < 4 || b.coords.y < 10) { return new EnemyFallingState() { Angle = 270, StateEnemy = b } } ; // Falling down state else if (chance % 2 == 0) { return new EnemyFlappingState() { Angle = 45, StateEnemy = b } } ; // Flapping right state else { return new EnemyFlappingState() { Angle = 135, StateEnemy = b } }; // Flapping left state default: if (chance < 2 || b.coords.y < 10) { return new EnemyFlappingState() { Angle = 90, StateEnemy = b } } ; // Flapping up state else { return new EnemyFlappingState() { Angle = b.state.Angle, StateEnemy = b } }; } } else if (b.state is EnemyFallingState) { switch (b.state.Angle) { case 270: if (chance % 10 < 3 || b.coords.y > 800) { return new EnemyFlappingState() { Angle = 90, StateEnemy = b } } ; // Flapping up state else if (chance % 2 == 0) { return new EnemyFallingState() { Angle = 315, StateEnemy = b } } ; // Falling right state else { return new EnemyFallingState() { Angle = 225, StateEnemy = b } }; // Falling left state default: if (chance < 3) { return new EnemyFallingState() { Angle = 270, StateEnemy = b } } ; // Falling down state else { return new EnemyFallingState() { Angle = b.state.Angle, StateEnemy = b } }; } } else if (b.state is BuzzardPickupState) { BuzzardPickupState set_state = b.state as BuzzardPickupState; // Determine if the Buzzard is close enough to the Mik being picked up if ((set_state.TargetEgg.coords.x - b.coords.x) > -5 && (set_state.TargetEgg.coords.x - b.coords.x) < 5 && ((set_state.TargetEgg.coords.y - 50) - b.coords.y) < 5 && ((set_state.TargetEgg.coords.y - 50) - b.coords.y) > -5) { // Picked up Mik set_state.TargetEgg.mounted = true; b.droppedEgg = false; return(new EnemyStandingState() { StateEnemy = b, Angle = 0 }); } else { return(new BuzzardPickupState() { StateEnemy = b, Angle = b.state.Angle, TargetEgg = set_state.TargetEgg }); } } else { // If non of the previous states, set state to Fleeing return(new BuzzardFleeingState() { StateEnemy = b }); } } else if (e is Egg) { /*** Egg States ***/ Egg egg = e as Egg; if (egg.state is EnemyFallingState) { // *** Implement when the egg lands on a platform *** if (egg.coords.y > 800) { return new EnemyStandingState() { Angle = egg.state.Angle, StateEnemy = egg } } ; // Standing state else { return new EnemyFallingState() { Angle = egg.state.Angle, StateEnemy = egg } }; // Falling state } else { if (egg.seconds > 800) { return(new EggHatchedState() { StateEnemy = egg }); // Egg has hatched state } else if (egg.seconds > 600) { egg.seconds++; return(new EggHatchingState() { StateEnemy = egg }); // Egg is hatching state } else { egg.seconds++; return(new EnemyStandingState() { Angle = 0, StateEnemy = egg }); // Standing state } } } else if (e is Pterodactyl) { /*** Pterodactyl States ***/ Pterodactyl p = e as Pterodactyl; // *** Add charging state to attack nearby player *** if (p.coords.y > 300 && p.coords.y < 500 && p.coords.x > 600 && p.coords.x < 800) { return new PterodactylChargeState() { StateEnemy = p } } ; // *** Add hitbox check to destroy pterodactyl *** if (p.coords.y > 450 && p.coords.y < 525 && p.coords.x > 650 && p.coords.x < 800) { return new PterodactylDestroyedState() { StateEnemy = p } } ; if (p.state is EnemyFallingState) { switch (p.state.Angle) { case 270: if (chance % 10 < 3 || p.coords.y > 800) { return new EnemyFlappingState() { Angle = 90, StateEnemy = p } } ; // Flapping up state else if (chance % 2 == 0) { return new EnemyFallingState() { Angle = 315, StateEnemy = p } } ; // Falling right state else { return new EnemyFallingState() { Angle = 225, StateEnemy = p } }; // Falling left state default: if (chance < 3) { return new EnemyFallingState() { Angle = 270, StateEnemy = p } } ; // Falling down state else { return new EnemyFallingState() { Angle = p.state.Angle, StateEnemy = p } }; } } else if (p.state is EnemyFlappingState) { switch (p.state.Angle) { case 90: if (chance / 10 < 2 && chance % 10 < 4 || p.coords.y < 10) { return new EnemyFallingState() { Angle = 270, StateEnemy = p } } ; // Falling down state else if (chance % 2 == 0) { return new EnemyFlappingState() { Angle = 45, StateEnemy = p } } ; // Flapping right state else { return new EnemyFlappingState() { Angle = 135, StateEnemy = p } }; // Flapping left state default: if (chance < 2 || p.coords.y < 10) { return new EnemyFlappingState() { Angle = 90, StateEnemy = p } } ; // Flapping up state else { return new EnemyFlappingState() { Angle = p.state.Angle, StateEnemy = p } }; } } else { // Default is Falling state return(new EnemyFallingState() { Angle = p.state.Angle, StateEnemy = p }); } } else { /*** No Know Enemy Default State ***/ return(new EnemyStandingState() { Angle = 0 }); } }
/// <summary> /// This Factory Method produces the next state for every enemy calling it. /// </summary> /// <param name="e"> Used to determine what states are available to the enemy </param> /// <returns> A new EnemyState Child </returns> public static void GetNextState(Enemy e) { // Use Random number to choose next state Random rand = new Random(DateTime.Now.Millisecond); for (int i = 0; i < 999990; i++) { } int chance = rand.Next(100); if (e is Buzzard) { /*** Buzzard States ***/ Buzzard b = e as Buzzard; if (b.stateMachine.currentState is EnemyStandingState) { if (chance % 2 == 0) { if (chance % 10 < 5) { b.stateMachine.Change("run_right"); } else { b.stateMachine.Change("run_right"); } } else { b.stateMachine.Change("flap"); } } else if (b.stateMachine.currentState is EnemyRunningState) { if (chance < 2) { b.stateMachine.Change("stand"); } else if (chance == 99) { EnemyState enemySt = b.stateMachine.currentState as EnemyState; if (enemySt.Angle == 0) { b.stateMachine.Change("run_left"); } else { b.stateMachine.Change("run_right"); } } } else if (b.stateMachine.currentState is EnemyFlappingState) { EnemyState enemySt = b.stateMachine.currentState as EnemyState; switch (enemySt.Angle) { case 90: if (chance / 10 < 2 && chance % 10 < 4 || b.coords.y < 10) { b.stateMachine.Change("fall"); } else if (chance % 2 == 0) { b.stateMachine.Change("flap_right"); } else { b.stateMachine.Change("flap_left"); } break; default: if (chance < 2 || b.coords.y < 10) { b.stateMachine.Change("flap"); } break; } } else if (b.stateMachine.currentState is EnemyFallingState) { EnemyState enemySt = b.stateMachine.currentState as EnemyState; switch (enemySt.Angle) { case 270: if (chance % 10 < 3 || b.coords.y > 730) { b.stateMachine.Change("flap"); } else if (chance % 2 == 0) { b.stateMachine.Change("fall_right"); } else { b.stateMachine.Change("fall_left"); } break; default: if (chance < 3 || b.coords.y > 730) { b.stateMachine.Change("fall"); } break; } } else if (b.stateMachine.currentState is BuzzardPickupState) { BuzzardPickupState set_state = b.stateMachine.currentState as BuzzardPickupState; // Determine if the Buzzard is close enough to the Mik (Hatched Egg) being picked up if ((set_state.TargetEgg.coords.x - b.coords.x) > -5 && (set_state.TargetEgg.coords.x - b.coords.x) < 5 && ((set_state.TargetEgg.coords.y - 50) - b.coords.y) < 5 && ((set_state.TargetEgg.coords.y - 50) - b.coords.y) > -5) { // Picked up Mik (Hatched Egg) set_state.TargetEgg.mounted = true; b.droppedEgg = false; b.stateMachine.Change("stand"); } } else if (b.stateMachine.currentState is BuzzardFleeingState) { // If none of the previous states, set state to Fleeing b.stateMachine.Change("flee"); } else { b.stateMachine.Change("flap"); } } else if (e is Egg) { /*** Egg States ***/ Egg egg = e as Egg; if (egg.stateMachine.currentState is EnemyFallingState) { if (egg.coords.y > 750) { egg.stateMachine.Change("stand"); } } else { if (egg.seconds > 800) { egg.stateMachine.Change("hatched"); } else if (egg.seconds > 600) { egg.seconds++; egg.stateMachine.Change("hatching"); } else { egg.seconds++; egg.stateMachine.Change("stand"); } } } else if (e is Pterodactyl) { /*** Pterodactyl States ***/ Pterodactyl p = e as Pterodactyl; // *** Add charging state to attack nearby player *** if (p.coords.y > 300 && p.coords.y < 450 && p.coords.x > 600 && p.coords.x < 700) { p.stateMachine.Change("charge"); } if (p.stateMachine.currentState is EnemyFallingState) { EnemyState enemySt = p.stateMachine.currentState as EnemyState; switch (enemySt.Angle) { case 270: if (chance % 10 < 3 || p.coords.y > 700) { p.stateMachine.Change("flap"); } else if (chance % 2 == 0) { p.stateMachine.Change("fall_right"); } else { p.stateMachine.Change("fall_left"); } break; default: if (chance < 3 || p.coords.y > 700) { p.stateMachine.Change("fall"); } break; } } else if (p.stateMachine.currentState is EnemyFlappingState) { EnemyState enemySt = p.stateMachine.currentState as EnemyState; switch (enemySt.Angle) { case 90: if (chance / 10 < 2 && chance % 10 < 4 || p.coords.y < 10) { p.stateMachine.Change("fall"); } else if (chance % 2 == 0) { p.stateMachine.Change("flap_right"); } else { p.stateMachine.Change("flap_left"); } break; default: if (chance < 2 || p.coords.y < 10) { p.stateMachine.Change("flap"); } break; } } else if (p.stateMachine.currentState is PterodactylChargeState) { if (p.coords.y <= 300 || p.coords.y >= 450 || p.coords.x <= 600 || p.coords.x >= 700) { p.stateMachine.Change("flap"); } } } }
/// <summary> /// Determines the objects next state and fires the appropriate event /// handler to notify the view of the state change. /// </summary> public override void Update() { //Console.WriteLine("Buzzard state = " + stateMachine.currentState.ToString()); if (!isSpawning) { if (!droppedEgg) { CheckEnemyCollision(); } // Determine the next state EnemyState.GetNextState(this); stateMachine.currentState.Update(); } if (stateMachine.currentState is EnemyFlappingState) { // "Gravity" purposes if (speed > TERMINAL_VELOCITY) { if (prevAngle == 225 || prevAngle == 270 || prevAngle == 315) { speed = 0.05; } else { speed = TERMINAL_VELOCITY; } } } else if (stateMachine.currentState is EnemyFallingState) { // "Gravity" purposes if (speed > TERMINAL_VELOCITY) { if (prevAngle == 45 || prevAngle == 90 || prevAngle == 135) { speed = 0.05; } else { speed = TERMINAL_VELOCITY; } } } else if (stateMachine.currentState is EnemyRunningState) { speed = SPEED; } else if (stateMachine.currentState is BuzzardFleeingState) { // When the Buzzard has been hit, it drops an egg and // flies to the left side. Destroy the Buzzard when // close enough to the edge of the screen. if (!droppedEgg) { if (BuzzardDropEgg != null) { BuzzardDropEgg(this, null); } droppedEgg = true; } if (coords.x < 3) { if (BuzzardDestroyed != null) { BuzzardDestroyed(this, null); } Die(); } } else if (stateMachine.currentState is EnemySpawningState) { respawning++; isSpawning = true; prevAngle = 90; angle = 90; speed = 0.5; imagePath = "Images/Enemy/mik_respawn.png"; if (respawning > 100) { if (droppedEgg) { stateMachine.Change("pickup"); BuzzardPickupState pState = stateMachine.currentState as BuzzardPickupState; pState.TargetEgg = pickupEgg; stateMachine.currentState.Update(); } else { stateMachine.Change("spawn"); } respawning = 0; isSpawning = false; } } // "Gravity" purposes prevAngle = angle; // Slow the rate of updating the graphic if (updateGraphic > 3) { updateGraphic = 0; } else { updateGraphic++; } // Always fire the move event if (BuzzardMoveEvent != null) // Is anyone subscribed? { BuzzardMoveEvent(this, null); // Raise event } // Slow the rate of updating the graphic if (updateGraphic == 0) { if (BuzzardStateChange != null) { BuzzardStateChange(this, null); } } }