Character.cs 10 KB

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