Character.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Character.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Diagnostics;
  12. using Microsoft.Xna.Framework;
  13. using Microsoft.Xna.Framework.Content;
  14. using Microsoft.Xna.Framework.Graphics;
  15. #endregion
  16. namespace RolePlayingGameData
  17. {
  18. /// <summary>
  19. /// A character in the game world.
  20. /// </summary>
  21. #if !XBOX
  22. [DebuggerDisplay("Name = {name}")]
  23. #endif
  24. public abstract class Character : WorldObject
  25. {
  26. #region Character State
  27. /// <summary>
  28. /// The state of a character.
  29. /// </summary>
  30. public enum CharacterState
  31. {
  32. /// <summary>
  33. /// Ready to perform an action, and playing the idle animation
  34. /// </summary>
  35. Idle,
  36. /// <summary>
  37. /// Walking in the world.
  38. /// </summary>
  39. Walking,
  40. /// <summary>
  41. /// In defense mode
  42. /// </summary>
  43. Defending,
  44. /// <summary>
  45. /// Performing Dodge Animation
  46. /// </summary>
  47. Dodging,
  48. /// <summary>
  49. /// Performing Hit Animation
  50. /// </summary>
  51. Hit,
  52. /// <summary>
  53. /// Dead, but still playing the dying animation.
  54. /// </summary>
  55. Dying,
  56. /// <summary>
  57. /// Dead, with the dead animation.
  58. /// </summary>
  59. Dead,
  60. }
  61. /// <summary>
  62. /// The state of this character.
  63. /// </summary>
  64. private CharacterState state = CharacterState.Idle;
  65. /// <summary>
  66. /// The state of this character.
  67. /// </summary>
  68. [ContentSerializerIgnore]
  69. public CharacterState State
  70. {
  71. get { return state; }
  72. set { state = value; }
  73. }
  74. /// <summary>
  75. /// Returns true if the character is dead or dying.
  76. /// </summary>
  77. public bool IsDeadOrDying
  78. {
  79. get
  80. {
  81. return ((State == CharacterState.Dying) ||
  82. (State == CharacterState.Dead));
  83. }
  84. }
  85. #endregion
  86. #region Map Data
  87. /// <summary>
  88. /// The position of this object on the map.
  89. /// </summary>
  90. private Point mapPosition;
  91. /// <summary>
  92. /// The position of this object on the map.
  93. /// </summary>
  94. [ContentSerializerIgnore]
  95. public Point MapPosition
  96. {
  97. get { return mapPosition; }
  98. set { mapPosition = value; }
  99. }
  100. /// <summary>
  101. /// The orientation of this object on the map.
  102. /// </summary>
  103. private Direction direction;
  104. /// <summary>
  105. /// The orientation of this object on the map.
  106. /// </summary>
  107. [ContentSerializerIgnore]
  108. public Direction Direction
  109. {
  110. get { return direction; }
  111. set { direction = value; }
  112. }
  113. #endregion
  114. #region Graphics Data
  115. /// <summary>
  116. /// The animating sprite for the map view of this character.
  117. /// </summary>
  118. private AnimatingSprite mapSprite;
  119. /// <summary>
  120. /// The animating sprite for the map view of this character.
  121. /// </summary>
  122. [ContentSerializer(Optional = true)]
  123. public AnimatingSprite MapSprite
  124. {
  125. get { return mapSprite; }
  126. set { mapSprite = value; }
  127. }
  128. /// <summary>
  129. /// The animating sprite for the map view of this character as it walks.
  130. /// </summary>
  131. /// <remarks>
  132. /// If this object is null, then the animations are taken from MapSprite.
  133. /// </remarks>
  134. private AnimatingSprite walkingSprite;
  135. /// <summary>
  136. /// The animating sprite for the map view of this character as it walks.
  137. /// </summary>
  138. /// <remarks>
  139. /// If this object is null, then the animations are taken from MapSprite.
  140. /// </remarks>
  141. [ContentSerializer(Optional=true)]
  142. public AnimatingSprite WalkingSprite
  143. {
  144. get { return walkingSprite; }
  145. set { walkingSprite = value; }
  146. }
  147. /// <summary>
  148. /// Reset the animations for this character.
  149. /// </summary>
  150. public virtual void ResetAnimation(bool isWalking)
  151. {
  152. state = isWalking ? CharacterState.Walking : CharacterState.Idle;
  153. if (mapSprite != null)
  154. {
  155. if (isWalking && mapSprite["Walk" + Direction.ToString()] != null)
  156. {
  157. mapSprite.PlayAnimation("Walk", Direction);
  158. }
  159. else
  160. {
  161. mapSprite.PlayAnimation("Idle", Direction);
  162. }
  163. }
  164. if (walkingSprite != null)
  165. {
  166. if (isWalking && walkingSprite["Walk" + Direction.ToString()] != null)
  167. {
  168. walkingSprite.PlayAnimation("Walk", Direction);
  169. }
  170. else
  171. {
  172. walkingSprite.PlayAnimation("Idle", Direction);
  173. }
  174. }
  175. }
  176. /// <summary>
  177. /// The small blob shadow that is rendered under the characters.
  178. /// </summary>
  179. private Texture2D shadowTexture;
  180. /// <summary>
  181. /// The small blob shadow that is rendered under the characters.
  182. /// </summary>
  183. [ContentSerializerIgnore]
  184. public Texture2D ShadowTexture
  185. {
  186. get { return shadowTexture; }
  187. set { shadowTexture = value; }
  188. }
  189. #endregion
  190. #region Standard Animation Data
  191. /// <summary>
  192. /// The default idle-animation interval for the animating map sprite.
  193. /// </summary>
  194. private int mapIdleAnimationInterval = 200;
  195. /// <summary>
  196. /// The default idle-animation interval for the animating map sprite.
  197. /// </summary>
  198. [ContentSerializer(Optional=true)]
  199. public int MapIdleAnimationInterval
  200. {
  201. get { return mapIdleAnimationInterval; }
  202. set { mapIdleAnimationInterval = value; }
  203. }
  204. /// <summary>
  205. /// Add the standard character idle animations to this character.
  206. /// </summary>
  207. private void AddStandardCharacterIdleAnimations()
  208. {
  209. if (mapSprite != null)
  210. {
  211. mapSprite.AddAnimation(new Animation("IdleSouth", 1, 6,
  212. MapIdleAnimationInterval, true));
  213. mapSprite.AddAnimation(new Animation("IdleSouthwest", 7, 12,
  214. MapIdleAnimationInterval, true));
  215. mapSprite.AddAnimation(new Animation("IdleWest", 13, 18,
  216. MapIdleAnimationInterval, true));
  217. mapSprite.AddAnimation(new Animation("IdleNorthwest", 19, 24,
  218. MapIdleAnimationInterval, true));
  219. mapSprite.AddAnimation(new Animation("IdleNorth", 25, 30,
  220. MapIdleAnimationInterval, true));
  221. mapSprite.AddAnimation(new Animation("IdleNortheast", 31, 36,
  222. MapIdleAnimationInterval, true));
  223. mapSprite.AddAnimation(new Animation("IdleEast", 37, 42,
  224. MapIdleAnimationInterval, true));
  225. mapSprite.AddAnimation(new Animation("IdleSoutheast", 43, 48,
  226. MapIdleAnimationInterval, true));
  227. }
  228. }
  229. /// <summary>
  230. /// The default walk-animation interval for the animating map sprite.
  231. /// </summary>
  232. private int mapWalkingAnimationInterval = 80;
  233. /// <summary>
  234. /// The default walk-animation interval for the animating map sprite.
  235. /// </summary>
  236. [ContentSerializer(Optional = true)]
  237. public int MapWalkingAnimationInterval
  238. {
  239. get { return mapWalkingAnimationInterval; }
  240. set { mapWalkingAnimationInterval = value; }
  241. }
  242. /// <summary>
  243. /// Add the standard character walk animations to this character.
  244. /// </summary>
  245. private void AddStandardCharacterWalkingAnimations()
  246. {
  247. AnimatingSprite sprite = (walkingSprite == null ? mapSprite : walkingSprite);
  248. if (sprite != null)
  249. {
  250. sprite.AddAnimation(new Animation("WalkSouth", 1, 6,
  251. MapWalkingAnimationInterval, true));
  252. sprite.AddAnimation(new Animation("WalkSouthwest", 7, 12,
  253. MapWalkingAnimationInterval, true));
  254. sprite.AddAnimation(new Animation("WalkWest", 13, 18,
  255. MapWalkingAnimationInterval, true));
  256. sprite.AddAnimation(new Animation("WalkNorthwest", 19, 24,
  257. MapWalkingAnimationInterval, true));
  258. sprite.AddAnimation(new Animation("WalkNorth", 25, 30,
  259. MapWalkingAnimationInterval, true));
  260. sprite.AddAnimation(new Animation("WalkNortheast", 31, 36,
  261. MapWalkingAnimationInterval, true));
  262. sprite.AddAnimation(new Animation("WalkEast", 37, 42,
  263. MapWalkingAnimationInterval, true));
  264. sprite.AddAnimation(new Animation("WalkSoutheast", 43, 48,
  265. MapWalkingAnimationInterval, true));
  266. }
  267. }
  268. #endregion
  269. #region Content Type Reader
  270. /// <summary>
  271. /// Reads a Character object from the content pipeline.
  272. /// </summary>
  273. public class CharacterReader : ContentTypeReader<Character>
  274. {
  275. /// <summary>
  276. /// Reads a Character object from the content pipeline.
  277. /// </summary>
  278. protected override Character Read(ContentReader input,
  279. Character existingInstance)
  280. {
  281. Character character = existingInstance;
  282. if (character == null)
  283. {
  284. throw new ArgumentNullException("existingInstance");
  285. }
  286. input.ReadRawObject<WorldObject>(character as WorldObject);
  287. character.MapIdleAnimationInterval = input.ReadInt32();
  288. character.MapSprite = input.ReadObject<AnimatingSprite>();
  289. if (character.MapSprite != null)
  290. {
  291. character.MapSprite.SourceOffset =
  292. new Vector2(
  293. character.MapSprite.SourceOffset.X - 32,
  294. character.MapSprite.SourceOffset.Y - 32);
  295. }
  296. character.AddStandardCharacterIdleAnimations();
  297. character.MapWalkingAnimationInterval = input.ReadInt32();
  298. character.WalkingSprite = input.ReadObject<AnimatingSprite>();
  299. if (character.WalkingSprite != null)
  300. {
  301. character.WalkingSprite.SourceOffset =
  302. new Vector2(
  303. character.WalkingSprite.SourceOffset.X - 32,
  304. character.WalkingSprite.SourceOffset.Y - 32);
  305. }
  306. character.AddStandardCharacterWalkingAnimations();
  307. character.ResetAnimation(false);
  308. character.shadowTexture = input.ContentManager.Load<Texture2D>(
  309. @"Textures\Characters\CharacterShadow");
  310. return character;
  311. }
  312. }
  313. #endregion
  314. }
  315. }