Character Animation Component
by Jester Carvalho · in Torque X 2D · 09/19/2010 (4:48 pm) · 2 replies
I am trying to create an animation and simplify its fire component when asked to find last rotation. Right now i am using a modified version of Darth's AnimatedCharaterComponent from his "Arena Shooter" tutorial. What I am trying to accomplish is having 1 walking animation and 8 direction (rotation) animations. This may be more simple then i am trying to make it. I want to be able to Use left thumbstick (or w.a.s.d.) to move forward, back, and side-to-side, and right thumbstick (or up,down,left,right) to control the rotation and call on that directions animation. This way when our "Player" is facing 1 direction we can still strafe or move forward back still fire in the same direction. As it is now after the modifications (aka messed something up), my player rotates and i can get him to strafe but i have to use both w.a.s.d. and arrow keys at the same time. Also my "Player" fires north unless a arrow key is held down and the fire button is pushed. I think this error is from my character component but not positive.
Here is my cs file.
Here is my cs file.
#region Public properties, operators, constants, and enums
public T2DSceneObject SceneObject
{
get { return Owner as T2DSceneObject; }
}
public T2DAnimatedSprite AnimatedSprite
{
get { return Owner as T2DAnimatedSprite; }
}
public T2DAnimationData AnimNorth
{
get { return _animNorth; }
set { _animNorth = value; }
}
public T2DAnimationData AnimNorthWest
{
get { return _animNorthWest; }
set { _animNorthWest = value; }
}
public T2DAnimationData AnimWest
{
get { return _animWest; }
set { _animWest = value; }
}
public T2DAnimationData AnimSouthWest
{
get { return _animSouthWest; }
set { _animSouthWest = value; }
}
public T2DAnimationData AnimSouth
{
get { return _animSouth; }
set { _animSouth = value; }
}
public T2DAnimationData AnimSouthEast
{
get { return _animSouthEast; }
set { _animSouthEast = value; }
}
public T2DAnimationData AnimEast
{
get { return _animEast; }
set { _animEast = value; }
}
public T2DAnimationData AnimNorthEast
{
get { return _animNorthEast; }
set { _animNorthEast = value; }
}
[TorqueXmlSchemaType(DefaultValue = "true")]
public bool Active
{
get { return _active; }
set { _active = value; }
}
#endregion
//======================================================
#region Public methods
//A simple method that takes in one of the Animations and then checks to see whether or not its playing
//It then plays it.
public void PlayMyAnimation(T2DAnimationData animationData)
{
if (AnimatedSprite.AnimationData != animationData || !AnimatedSprite.IsAnimationPlaying)
{
AnimatedSprite.PlayAnimation(animationData);
AnimatedSprite.PlayAnimation();
}
}
//Every tick this method will be called and check for movement from the user.
public virtual void ProcessTick(Move move, float dt)
{
if (_active)
{
if (move != null)
{
//Here we use one of those Torque Utilities, accesed via the using statement at the top.
//We take a value from user input and convert it to an angle.
//There are a number of directions that we could potentially be in and they are mapped to positions
//of the xbox controller thumbsticks, or the arrow keys.
_rotation = T2DVectorUtil.AngleFromInput(new Vector2(move.Sticks[1].X, move.Sticks[1].Y));
if(move.Sticks[1].X != 0f || move.Sticks[1].Y != 0f)
{
_pcrotation = _rotation;
_lastrotation.Value = _rotation;
}
//Pushing up and to the right on the Right Thumbstick corresponds to a North East direction.
//So we send that information to the PlayMyAnimation Method.
if ((move.Sticks[1].X > 0) && (move.Sticks[1].Y > 0))
{
PlayMyAnimation(_animNorthEast);
}
else if ((move.Sticks[1].X > 0) && (move.Sticks[1].Y < 0))
{
PlayMyAnimation(_animSouthEast);
}
else if ((move.Sticks[1].X < 0) && (move.Sticks[1].Y > 0))
{
PlayMyAnimation(_animNorthWest);
}
else if ((move.Sticks[1].X < 0) && (move.Sticks[1].Y < 0))
{
PlayMyAnimation(_animSouthWest);
}
else if (move.Sticks[1].X > 0)
{
PlayMyAnimation(_animEast);
}
else if (move.Sticks[1].X < 0)
{
PlayMyAnimation(_animWest);
}
else if (move.Sticks[1].Y > 0)
{
PlayMyAnimation(_animNorth);
}
else if (move.Sticks[1].Y < 0)
{
PlayMyAnimation(_animSouth);
}
else if (move.Sticks[0].X != 0f || move.Sticks[0].Y != 0f)
{
AnimatedSprite.PlayAnimation();
}
else
{
AnimatedSprite.PauseAnimation();
}
// set our test object's Velocity based on stick/keyboard input
_sceneObject.Physics.VelocityX = move.Sticks[0].X * 18.0f;
_sceneObject.Physics.VelocityY = -move.Sticks[0].Y * 18.0f;
Velocity.X = _sceneObject.Physics.VelocityX;
Velocity.Y = _sceneObject.Physics.VelocityY;
_velocity.Value = Velocity;
}
}
}
public virtual void InterpolateTick(float k)
{
// todo: interpolate between ticks as needed here
}
public override void CopyTo(TorqueComponent obj)
{
//These CopyTo methods are here for when you want to make a clone of your SceneObject.
//The Clone will inherit all the properties of the parent set here.
base.CopyTo(obj);
AnimatedCharacterComponent obj2 = obj as AnimatedCharacterComponent;
obj2._animNorth = _animNorth;
obj2._animNorthWest = _animNorthWest;
obj2._animWest = _animWest;
obj2._animSouthWest = _animSouthWest;
obj2._animSouth = _animSouth;
obj2._animSouthEast = _animSouthEast;
obj2._animEast = _animEast;
obj2._animNorthEast = _animNorthEast;
obj2._lastrotation = _lastrotation;
obj2._rotation = _rotation;
obj2._position = _position;
obj2._sceneObject = _sceneObject;
}
#endregion
//======================================================
#region Private, protected, internal methods
//Some things to process when the Component is first registered in the scene.
//Here we setup an inputmap.
protected override bool _OnRegister(TorqueObject owner)
{
if (!base._OnRegister(owner) || !(Owner is T2DSceneObject))
return false;
// retain a reference to this component's owner object
_sceneObject = owner as T2DSceneObject;
_SetupInputMap(_sceneObject, 0, "gamepad0", "keyboard");
_active = true;
// tell the process list to notifiy us with ProcessTick and InterpolateTick events
ProcessList.Instance.AddTickCallback(Owner, this);
// todo: perform initialization for the component
// todo: look up interfaces exposed by other components
// E.g.,
// _theirInterface = Owner.Components.GetInterface<ValueInterface<float>>("float", "their interface name");
return true;
}
//This method is where we define things like which button or key does what.
//For the moment, just know that it works :)
private void _SetupInputMap(TorqueObject player, int playerIndex, String gamePad, String keyboard)
{
// Set player as the controllable object
PlayerManager.Instance.GetPlayer(playerIndex).ControlObject = player;
// Get input map for this player and configure it
InputMap inputMap = PlayerManager.Instance.GetPlayer(playerIndex).InputMap;
int gamepadId = InputManager.Instance.FindDevice(gamePad);
if (gamepadId >= 0)
{
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.LeftThumbX, MoveMapTypes.StickAnalogHorizontal, 0);
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.LeftThumbY, MoveMapTypes.StickAnalogVertical, 0);
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.RightThumbX, MoveMapTypes.StickAnalogHorizontal, 1);
inputMap.BindMove(gamepadId, (int)XGamePadDevice.GamePadObjects.RightThumbY, MoveMapTypes.StickAnalogVertical, 1);
}
// keyboard controls
int keyboardId = InputManager.Instance.FindDevice(keyboard);
if (keyboardId >= 0)
{
inputMap.BindMove(keyboardId, (int)Keys.D, MoveMapTypes.StickDigitalRight, 0);
inputMap.BindMove(keyboardId, (int)Keys.A, MoveMapTypes.StickDigitalLeft, 0);
inputMap.BindMove(keyboardId, (int)Keys.W, MoveMapTypes.StickDigitalUp, 0);
inputMap.BindMove(keyboardId, (int)Keys.S, MoveMapTypes.StickDigitalDown, 0);
inputMap.BindMove(keyboardId, (int)Keys.Right, MoveMapTypes.StickDigitalRight, 1);
inputMap.BindMove(keyboardId, (int)Keys.Left, MoveMapTypes.StickDigitalLeft, 1);
inputMap.BindMove(keyboardId, (int)Keys.Up, MoveMapTypes.StickDigitalUp, 1);
inputMap.BindMove(keyboardId, (int)Keys.Down, MoveMapTypes.StickDigitalDown, 1);
}
}
protected override void _OnUnregister()
{
// todo: perform de-initialization for the component
base._OnUnregister();
}
//Interfaces are for exposing variables to other components that your Object might have.
//I expose rotation and position here. This is so any projectiles the player fires will be able to use the
//rotation and position of the player when they are shot.
protected override void _RegisterInterfaces(TorqueObject owner)
{
base._RegisterInterfaces(owner);
// Owner.RegisterCachedInterface("float", "interface name", this, _ourInterface);
Owner.RegisterCachedInterface("float", "rotation", this, _lastrotation);
Owner.RegisterCachedInterface("Vector2", "position", this, _position);
Owner.RegisterCachedInterface("Vector2", "velocity", this, _velocity);
}
#endregion
//======================================================
#region Private, protected, internal fields
//This is where we declare all of our variables! It's a very important space.
ValueInPlaceInterface<float> _lastrotation = new ValueInPlaceInterface<float>();
ValueInPlaceInterface<Vector2> _position = new ValueInPlaceInterface<Vector2>();
Vector2 Velocity = new Vector2();
ValueInPlaceInterface<Vector2> _velocity = new ValueInPlaceInterface<Vector2>();
public static float _pcrotation;
float _rotation;
T2DSceneObject _sceneObject;
T2DAnimationData _animNorth;
T2DAnimationData _animNorthWest;
T2DAnimationData _animWest;
T2DAnimationData _animSouthWest;
T2DAnimationData _animSouth;
T2DAnimationData _animSouthEast;
T2DAnimationData _animEast;
T2DAnimationData _animNorthEast;
public static bool _active;
#endregion
}
}if anyone has any thoughts or ideas plz let me know. Thank you in advance.
#2
09/19/2010 (11:40 pm)
This worked Great. Thank You. Solved My first Problem. Now trying to Solve my next Problem. My character now does not play any animations when using left thumb stick. (this is my doing) I took out the play specific animations to keep from looking in 1 direction and shooting in another direction. I am now trying to figure out a way to call on "LastAnimation". I know this must be possible just don't have the experience to figure it out. I am attempting to do this so it looks as if the player is walking not sliding when a direction is pushed. At this point not trying to implement a strafe animation or walk back animation just same animation that my "Player" was playing when I rotated him last. I will update the code above so you all can see the changes i have made. Again Thank You Alex for your quick response. Line 138 is where I try to call on "PlayAnimation" and does not do a Darn thing.
Torque Owner Alex Richards
if(move.Sticks[1].X != 0f || move.Sticks[1].Y != 0f) _rotation = T2DVectorUtil.AngleFromInput(new Vector2(move.Sticks[1].X, move.Sticks[1].Y));