GameObject.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.Xna.Framework;
  6. using Microsoft.Xna.Framework.Graphics;
  7. using Tile_Engine;
  8. namespace Gemstone_Hunter
  9. {
  10. public class GameObject
  11. {
  12. #region Declarations
  13. protected Vector2 worldLocation;
  14. protected Vector2 velocity;
  15. protected int frameWidth;
  16. protected int frameHeight;
  17. protected bool enabled;
  18. protected bool flipped = false;
  19. protected bool onGround;
  20. protected Rectangle collisionRectangle;
  21. protected int collideWidth;
  22. protected int collideHeight;
  23. protected bool codeBasedBlocks = true;
  24. protected float drawDepth = 0.85f;
  25. protected Dictionary<string, AnimationStrip> animations =
  26. new Dictionary<string, AnimationStrip>();
  27. protected string currentAnimation;
  28. #endregion
  29. #region Properties
  30. public bool Enabled
  31. {
  32. get { return enabled; }
  33. set { enabled = value; }
  34. }
  35. public Vector2 WorldLocation
  36. {
  37. get { return worldLocation; }
  38. set { worldLocation = value; }
  39. }
  40. public Vector2 WorldCenter
  41. {
  42. get
  43. {
  44. return new Vector2(
  45. (int)worldLocation.X + (int)(frameWidth / 2),
  46. (int)worldLocation.Y + (int)(frameHeight / 2));
  47. }
  48. }
  49. public Rectangle WorldRectangle
  50. {
  51. get
  52. {
  53. return new Rectangle(
  54. (int)worldLocation.X,
  55. (int)worldLocation.Y,
  56. frameWidth,
  57. frameHeight);
  58. }
  59. }
  60. public Rectangle CollisionRectangle
  61. {
  62. get
  63. {
  64. return new Rectangle(
  65. (int)worldLocation.X + collisionRectangle.X,
  66. (int)WorldRectangle.Y + collisionRectangle.Y,
  67. collisionRectangle.Width,
  68. collisionRectangle.Height);
  69. }
  70. set { collisionRectangle = value; }
  71. }
  72. #endregion
  73. #region Helper Methods
  74. private void updateAnimation(GameTime gameTime)
  75. {
  76. if (animations.ContainsKey(currentAnimation))
  77. {
  78. if (animations[currentAnimation].FinishedPlaying)
  79. {
  80. PlayAnimation(animations[currentAnimation].NextAnimation);
  81. }
  82. else
  83. {
  84. animations[currentAnimation].Update(gameTime);
  85. }
  86. }
  87. }
  88. #endregion
  89. #region Map-Based Collision Detection Methods
  90. private Vector2 horizontalCollisionTest(Vector2 moveAmount)
  91. {
  92. if (moveAmount.X == 0)
  93. return moveAmount;
  94. Rectangle afterMoveRect = CollisionRectangle;
  95. afterMoveRect.Offset((int)moveAmount.X, 0);
  96. Vector2 corner1, corner2;
  97. if (moveAmount.X < 0)
  98. {
  99. corner1 = new Vector2(afterMoveRect.Left,
  100. afterMoveRect.Top + 1);
  101. corner2 = new Vector2(afterMoveRect.Left,
  102. afterMoveRect.Bottom - 1);
  103. }
  104. else
  105. {
  106. corner1 = new Vector2(afterMoveRect.Right,
  107. afterMoveRect.Top + 1);
  108. corner2 = new Vector2(afterMoveRect.Right,
  109. afterMoveRect.Bottom - 1);
  110. }
  111. Vector2 mapCell1 = TileMap.GetCellByPixel(corner1);
  112. Vector2 mapCell2 = TileMap.GetCellByPixel(corner2);
  113. if (!TileMap.CellIsPassable(mapCell1) ||
  114. !TileMap.CellIsPassable(mapCell2))
  115. {
  116. moveAmount.X = 0;
  117. velocity.X = 0;
  118. }
  119. if (codeBasedBlocks)
  120. {
  121. if (TileMap.CellCodeValue(mapCell1) == "BLOCK" ||
  122. TileMap.CellCodeValue(mapCell2) == "BLOCK")
  123. {
  124. moveAmount.X = 0;
  125. velocity.X = 0;
  126. }
  127. }
  128. return moveAmount;
  129. }
  130. private Vector2 verticalCollisionTest(Vector2 moveAmount)
  131. {
  132. if (moveAmount.Y == 0)
  133. return moveAmount;
  134. Rectangle afterMoveRect = CollisionRectangle;
  135. afterMoveRect.Offset((int)moveAmount.X, (int)moveAmount.Y);
  136. Vector2 corner1, corner2;
  137. if (moveAmount.Y < 0)
  138. {
  139. corner1 = new Vector2(afterMoveRect.Left + 1,
  140. afterMoveRect.Top);
  141. corner2 = new Vector2(afterMoveRect.Right - 1,
  142. afterMoveRect.Top);
  143. }
  144. else
  145. {
  146. corner1 = new Vector2(afterMoveRect.Left + 1,
  147. afterMoveRect.Bottom);
  148. corner2 = new Vector2(afterMoveRect.Right - 1,
  149. afterMoveRect.Bottom);
  150. }
  151. Vector2 mapCell1 = TileMap.GetCellByPixel(corner1);
  152. Vector2 mapCell2 = TileMap.GetCellByPixel(corner2);
  153. if (!TileMap.CellIsPassable(mapCell1) ||
  154. !TileMap.CellIsPassable(mapCell2))
  155. {
  156. if (moveAmount.Y > 0)
  157. onGround = true;
  158. moveAmount.Y = 0;
  159. velocity.Y = 0;
  160. }
  161. if (codeBasedBlocks)
  162. {
  163. if (TileMap.CellCodeValue(mapCell1) == "BLOCK" ||
  164. TileMap.CellCodeValue(mapCell2) == "BLOCK")
  165. {
  166. if (moveAmount.Y > 0)
  167. onGround = true;
  168. moveAmount.Y = 0;
  169. velocity.Y = 0;
  170. }
  171. }
  172. return moveAmount;
  173. }
  174. #endregion
  175. #region Public Methods
  176. public void PlayAnimation(string name)
  177. {
  178. if (!(name == null) && animations.ContainsKey(name))
  179. {
  180. currentAnimation = name;
  181. animations[name].Play();
  182. }
  183. }
  184. public virtual void Update(GameTime gameTime)
  185. {
  186. if (!enabled)
  187. return;
  188. float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
  189. updateAnimation(gameTime);
  190. if (velocity.Y != 0)
  191. {
  192. onGround = false;
  193. }
  194. Vector2 moveAmount = velocity * elapsed;
  195. moveAmount = horizontalCollisionTest(moveAmount);
  196. moveAmount = verticalCollisionTest(moveAmount);
  197. Vector2 newPosition = worldLocation + moveAmount;
  198. newPosition = new Vector2(
  199. MathHelper.Clamp(newPosition.X, 0,
  200. Camera.WorldRectangle.Width - frameWidth),
  201. MathHelper.Clamp(newPosition.Y, 2 * (-TileMap.TileHeight),
  202. Camera.WorldRectangle.Height - frameHeight));
  203. worldLocation = newPosition;
  204. }
  205. public virtual void Draw(SpriteBatch spriteBatch)
  206. {
  207. if (!enabled)
  208. return;
  209. if (animations.ContainsKey(currentAnimation))
  210. {
  211. SpriteEffects effect = SpriteEffects.None;
  212. if (flipped)
  213. {
  214. effect = SpriteEffects.FlipHorizontally;
  215. }
  216. spriteBatch.Draw(
  217. animations[currentAnimation].Texture,
  218. Camera.WorldToScreen(WorldRectangle),
  219. animations[currentAnimation].FrameRectangle,
  220. Color.White, 0.0f, Vector2.Zero, effect, drawDepth);
  221. }
  222. }
  223. #endregion
  224. }
  225. }