tasting on MonoGame
[tastes.git] / Platformer2D / Platformer2D.Core / Game / Enemy.cs
blob590c58a0993fe68574441b87f35775db8c1bc941
1 #region File Description
2 //-----------------------------------------------------------------------------
3 // Enemy.cs
4 //
5 // Microsoft XNA Community Game Platform
6 // Copyright (C) Microsoft Corporation. All rights reserved.
7 //-----------------------------------------------------------------------------
8 #endregion
10 using System;
11 using Microsoft.Xna.Framework;
12 using Microsoft.Xna.Framework.Graphics;
14 namespace Platformer2D
16 /// <summary>
17 /// Facing direction along the X axis.
18 /// </summary>
19 enum FaceDirection
21 Left = -1,
22 Right = 1,
25 /// <summary>
26 /// A monster who is impeding the progress of our fearless adventurer.
27 /// </summary>
28 class Enemy
30 public Level Level
32 get { return level; }
34 Level level;
36 /// <summary>
37 /// Position in world space of the bottom center of this enemy.
38 /// </summary>
39 public Vector2 Position
41 get { return position; }
43 Vector2 position;
45 private Rectangle localBounds;
46 /// <summary>
47 /// Gets a rectangle which bounds this enemy in world space.
48 /// </summary>
49 public Rectangle BoundingRectangle
51 get
53 int left = (int)Math.Round(Position.X - sprite.Origin.X) + localBounds.X;
54 int top = (int)Math.Round(Position.Y - sprite.Origin.Y) + localBounds.Y;
56 return new Rectangle(left, top, localBounds.Width, localBounds.Height);
60 // Animations
61 private Animation runAnimation;
62 private Animation idleAnimation;
63 private AnimationPlayer sprite;
65 /// <summary>
66 /// The direction this enemy is facing and moving along the X axis.
67 /// </summary>
68 private FaceDirection direction = FaceDirection.Left;
70 /// <summary>
71 /// How long this enemy has been waiting before turning around.
72 /// </summary>
73 private float waitTime;
75 /// <summary>
76 /// How long to wait before turning around.
77 /// </summary>
78 private const float MaxWaitTime = 0.5f;
80 /// <summary>
81 /// The speed at which this enemy moves along the X axis.
82 /// </summary>
83 private const float MoveSpeed = 64.0f;
85 /// <summary>
86 /// Constructs a new Enemy.
87 /// </summary>
88 public Enemy(Level level, Vector2 position, string spriteSet)
90 this.level = level;
91 this.position = position;
93 LoadContent(spriteSet);
96 /// <summary>
97 /// Loads a particular enemy sprite sheet and sounds.
98 /// </summary>
99 public void LoadContent(string spriteSet)
101 // Load animations.
102 spriteSet = "Sprites/" + spriteSet + "/";
103 runAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "Run"), 0.1f, true);
104 idleAnimation = new Animation(Level.Content.Load<Texture2D>(spriteSet + "Idle"), 0.15f, true);
105 sprite.PlayAnimation(idleAnimation);
107 // Calculate bounds within texture size.
108 int width = (int)(idleAnimation.FrameWidth * 0.35);
109 int left = (idleAnimation.FrameWidth - width) / 2;
110 int height = (int)(idleAnimation.FrameHeight * 0.7);
111 int top = idleAnimation.FrameHeight - height;
112 localBounds = new Rectangle(left, top, width, height);
116 /// <summary>
117 /// Paces back and forth along a platform, waiting at either end.
118 /// </summary>
119 public void Update(GameTime gameTime)
121 float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
123 // Calculate tile position based on the side we are walking towards.
124 float posX = Position.X + localBounds.Width / 2 * (int)direction;
125 int tileX = (int)Math.Floor(posX / Tile.Width) - (int)direction;
126 int tileY = (int)Math.Floor(Position.Y / Tile.Height);
128 if (waitTime > 0)
130 // Wait for some amount of time.
131 waitTime = Math.Max(0.0f, waitTime - (float)gameTime.ElapsedGameTime.TotalSeconds);
132 if (waitTime <= 0.0f)
134 // Then turn around.
135 direction = (FaceDirection)(-(int)direction);
138 else
140 // If we are about to run into a wall or off a cliff, start waiting.
141 if (Level.GetCollision(tileX + (int)direction, tileY - 1) == TileCollision.Impassable ||
142 Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Passable)
144 waitTime = MaxWaitTime;
146 else
148 // Move in the current direction.
149 Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);
150 position = position + velocity;
155 /// <summary>
156 /// Draws the animated enemy.
157 /// </summary>
158 public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
160 // Stop running when the game is paused or before turning around.
161 if (!Level.Player.IsAlive ||
162 Level.ReachedExit ||
163 Level.TimeRemaining == TimeSpan.Zero ||
164 waitTime > 0)
166 sprite.PlayAnimation(idleAnimation);
168 else
170 sprite.PlayAnimation(runAnimation);
174 // Draw facing the way the enemy is moving.
175 SpriteEffects flip = direction > 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
176 sprite.Draw(gameTime, spriteBatch, Position, flip);