#region File Description //----------------------------------------------------------------------------- // Character.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; #endregion namespace RolePlayingGameData { /// /// A character in the game world. /// #if !XBOX [DebuggerDisplay("Name = {name}")] #endif public abstract class Character : WorldObject { #region Character State /// /// The state of a character. /// public enum CharacterState { /// /// Ready to perform an action, and playing the idle animation /// Idle, /// /// Walking in the world. /// Walking, /// /// In defense mode /// Defending, /// /// Performing Dodge Animation /// Dodging, /// /// Performing Hit Animation /// Hit, /// /// Dead, but still playing the dying animation. /// Dying, /// /// Dead, with the dead animation. /// Dead, } /// /// The state of this character. /// private CharacterState state = CharacterState.Idle; /// /// The state of this character. /// [ContentSerializerIgnore] public CharacterState State { get { return state; } set { state = value; } } /// /// Returns true if the character is dead or dying. /// public bool IsDeadOrDying { get { return ((State == CharacterState.Dying) || (State == CharacterState.Dead)); } } #endregion #region Map Data /// /// The position of this object on the map. /// private Point mapPosition; /// /// The position of this object on the map. /// [ContentSerializerIgnore] public Point MapPosition { get { return mapPosition; } set { mapPosition = value; } } /// /// The orientation of this object on the map. /// private Direction direction; /// /// The orientation of this object on the map. /// [ContentSerializerIgnore] public Direction Direction { get { return direction; } set { direction = value; } } #endregion #region Graphics Data /// /// The animating sprite for the map view of this character. /// private AnimatingSprite mapSprite; /// /// The animating sprite for the map view of this character. /// [ContentSerializer(Optional = true)] public AnimatingSprite MapSprite { get { return mapSprite; } set { mapSprite = value; } } /// /// The animating sprite for the map view of this character as it walks. /// /// /// If this object is null, then the animations are taken from MapSprite. /// private AnimatingSprite walkingSprite; /// /// The animating sprite for the map view of this character as it walks. /// /// /// If this object is null, then the animations are taken from MapSprite. /// [ContentSerializer(Optional=true)] public AnimatingSprite WalkingSprite { get { return walkingSprite; } set { walkingSprite = value; } } /// /// Reset the animations for this character. /// public virtual void ResetAnimation(bool isWalking) { state = isWalking ? CharacterState.Walking : CharacterState.Idle; if (mapSprite != null) { if (isWalking && mapSprite["Walk" + Direction.ToString()] != null) { mapSprite.PlayAnimation("Walk", Direction); } else { mapSprite.PlayAnimation("Idle", Direction); } } if (walkingSprite != null) { if (isWalking && walkingSprite["Walk" + Direction.ToString()] != null) { walkingSprite.PlayAnimation("Walk", Direction); } else { walkingSprite.PlayAnimation("Idle", Direction); } } } /// /// The small blob shadow that is rendered under the characters. /// private Texture2D shadowTexture; /// /// The small blob shadow that is rendered under the characters. /// [ContentSerializerIgnore] public Texture2D ShadowTexture { get { return shadowTexture; } set { shadowTexture = value; } } #endregion #region Standard Animation Data /// /// The default idle-animation interval for the animating map sprite. /// private int mapIdleAnimationInterval = 200; /// /// The default idle-animation interval for the animating map sprite. /// [ContentSerializer(Optional=true)] public int MapIdleAnimationInterval { get { return mapIdleAnimationInterval; } set { mapIdleAnimationInterval = value; } } /// /// Add the standard character idle animations to this character. /// private void AddStandardCharacterIdleAnimations() { if (mapSprite != null) { mapSprite.AddAnimation(new Animation("IdleSouth", 1, 6, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleSouthwest", 7, 12, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleWest", 13, 18, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleNorthwest", 19, 24, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleNorth", 25, 30, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleNortheast", 31, 36, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleEast", 37, 42, MapIdleAnimationInterval, true)); mapSprite.AddAnimation(new Animation("IdleSoutheast", 43, 48, MapIdleAnimationInterval, true)); } } /// /// The default walk-animation interval for the animating map sprite. /// private int mapWalkingAnimationInterval = 80; /// /// The default walk-animation interval for the animating map sprite. /// [ContentSerializer(Optional = true)] public int MapWalkingAnimationInterval { get { return mapWalkingAnimationInterval; } set { mapWalkingAnimationInterval = value; } } /// /// Add the standard character walk animations to this character. /// private void AddStandardCharacterWalkingAnimations() { AnimatingSprite sprite = (walkingSprite == null ? mapSprite : walkingSprite); if (sprite != null) { sprite.AddAnimation(new Animation("WalkSouth", 1, 6, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkSouthwest", 7, 12, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkWest", 13, 18, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkNorthwest", 19, 24, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkNorth", 25, 30, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkNortheast", 31, 36, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkEast", 37, 42, MapWalkingAnimationInterval, true)); sprite.AddAnimation(new Animation("WalkSoutheast", 43, 48, MapWalkingAnimationInterval, true)); } } #endregion #region Content Type Reader /// /// Reads a Character object from the content pipeline. /// public class CharacterReader : ContentTypeReader { /// /// Reads a Character object from the content pipeline. /// protected override Character Read(ContentReader input, Character existingInstance) { Character character = existingInstance; if (character == null) { throw new ArgumentNullException("existingInstance"); } input.ReadRawObject(character as WorldObject); character.MapIdleAnimationInterval = input.ReadInt32(); character.MapSprite = input.ReadObject(); if (character.MapSprite != null) { character.MapSprite.SourceOffset = new Vector2( character.MapSprite.SourceOffset.X - 32, character.MapSprite.SourceOffset.Y - 32); } character.AddStandardCharacterIdleAnimations(); character.MapWalkingAnimationInterval = input.ReadInt32(); character.WalkingSprite = input.ReadObject(); if (character.WalkingSprite != null) { character.WalkingSprite.SourceOffset = new Vector2( character.WalkingSprite.SourceOffset.X - 32, character.WalkingSprite.SourceOffset.Y - 32); } character.AddStandardCharacterWalkingAnimations(); character.ResetAnimation(false); character.shadowTexture = input.ContentManager.Load( @"Textures\Characters\CharacterShadow"); return character; } } #endregion } }