Game Development Community

Switch between 2 static sprites?

by FruitBatInShades · in Torque X 2D · 11/09/2009 (5:58 pm) · 6 replies

I have been trying to figure this out for a few days now! I've read through the docs but they're not the friendliest things!

Can anyone supply a basic component that allows me to select 2 Static sprites in the builder and switch between them via a trigger? I want to implement doors with different collision meshes for the open and closed state but can't even figure out how to get started!

I've tried T2DSceneObject and T2dStaticSprite but I cannot get anything to render! Any pointers greatfully recieved!

using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;

using GarageGames.Torque.Core;
using GarageGames.Torque.Util;
using GarageGames.Torque.Sim;
using GarageGames.Torque.T2D;
using GarageGames.Torque.SceneGraph;
using GarageGames.Torque.MathUtil;

namespace GarageGames.Torque.PlatformerDemo
{
    [TorqueXmlSchemaType]
    public class DoorComponent : TorqueComponent, ITickObject
    {
        //======================================================
        #region Static methods, fields, constructors
        #endregion

        //======================================================
        #region Constructors
        #endregion

        //======================================================
        #region Public properties, operators, constants, and enums

        public T2DSceneObject SceneObject
        {
            get { return Owner as T2DSceneObject; }
        }
        [TorqueXmlSchemaType(DefaultValue = "Closed")]
        public eDoorState DoorState
        {
            get { return _DoorState; }
            set { _DoorState = value; }

        }
        public bool IsOpen
        {
            get { return DoorState == eDoorState.Open; }
        }
        public bool IsClosed
        {
            get { return DoorState == eDoorState.Closed || DoorState == eDoorState.NeedsKey; }
        }
        public enum eDoorState
        {
            None=0,
            Closed=0,
            Open=1,
            NeedsKey = 2
        }
        public T2DSceneObject BackgroundSprite
        {
            get { return _BackgroundSprite; }
            set { _BackgroundSprite = value; }
        }
        public T2DSceneObject DoorSprite
        {
            get { return _DoorSprite; }
            set { _DoorSprite = value; }
        }
        public T2DStaticSprite Test
        {
            get { return _Test; }
            set { _Test = value; }
        }
        #endregion

        //======================================================
        #region Public methods

        public virtual void ProcessTick(Move move, float dt)
        {
            // todo: perform processing for component here
        }

        public virtual void InterpolateTick(float k)
        {
            // todo: interpolate between ticks as needed here
        }

        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);
        }

        #endregion
        //======================================================
        #region Private, protected, internal methods

        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner) || !(owner is T2DSceneObject))
                return false;

            // 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;
        }

        protected override void _OnUnregister()
        {
            // todo: perform de-initialization for the component

            base._OnUnregister();
        }

        protected override void _RegisterInterfaces(TorqueObject owner)
        {
            base._RegisterInterfaces(owner);

            // todo: register interfaces to be accessed by other components
            // E.g.,
            // Owner.RegisterCachedInterface("float", "interface name", this, _ourInterface);
        }


        #endregion

        //======================================================
        #region Private, protected, internal fields
        eDoorState _DoorState;
        T2DSceneObject _BackgroundSprite;
        T2DSceneObject _DoorSprite;
        T2DStaticSprite _Test;
        #endregion
    }
}

#1
11/09/2009 (6:00 pm)
P.S. Pointers to the right areas of documentation that can help me figure out the basics welcome too! Like how to get the images from the properties, how to make them render etc.
#2
11/09/2009 (9:34 pm)
There are a number of ways you can do this, if you look at the Airplane tutorial you will see how to use an animated sprite and set it to a certain frame when something happens. You could make your doors 2 frames in an animated sprite, then change the animations when triggered. That may be the easiest way.
#3
11/10/2009 (5:54 am)
I'm not sure to have understood your goal, but if I'm right the solution I see is the same used to apply different animations (and sprites) to the same scene object. This is what you need:

Add the animations to your project, then add to your door component the different properties like this:
T2DAnimationData _myAnimatedDoor1;
        T2DAnimationData _myAnimatedDoor2;
        T2DAnimationData myAnimatedDoor3;

        public T2DAnimationData MyAnimatedDoor1
        {
            get
            {
                return _myAnimatedDoor1;
            }
            set
            {
                _myAnimatedDoor1 = value;
            }
        }
        public T2DAnimationData MyAnimatedDoor2
        {
            get
            {
                return _myAnimatedDoor2;
            }
            set
            {
                _myAnimatedDoor2 = value;
            }
        }
        public T2DAnimationData MyAnimatedDoor3
        {
            get
            {
                return _myAnimatedDoor3;
            }
            set
            {
                _myAnimatedDoor3 = value;
            }
        }

Now in TXB you can assign these newly created properties to the proper animations defined in your project.

In your controller component add this fields:

PlayerComponent _player;
T2DAnimatedSprite _animatedSprite;

Then (in your controller component) add this in the PostRegister() :

_player = Owner.Components.FindComponent<PlayerComponent>();
   _animatedSprite = _player.SceneObject as T2DAnimatedSprite;

Now all you have to do us to switch on the State of your object (in the ProcessTick method) and assign the animation in this way:

public override void ProcessTick(Move move, float elapsed)
    {
      //some init code
      T2DAnimationData _anim = null;
      switch (myState) 
      {
         case state1:
                _anim = _myAnimatedDoor1;
                break;
         case state2:
                _anim = _myAnimatedDoor2;
                break;
         case state3:
                _anim = _myAnimatedDoor3;
                break;
      }
     // Apply the animation
     _animatedSprite.AnimationData = _anim;
    }

I hope this is what you wanted ;)

Cheers,
Pino
#4
11/11/2009 (3:19 pm)
I've got the door drawing now but I don't understand how! How does it know to render the sprite? All I've done is declare an T2DAnimatedSprite and now it draws.
How does TX2D decide what to render/animate?
namespace GarageGames.Torque.PlatformerDemo
{
    [TorqueXmlSchemaType]
    public class DoorComponent : TorqueComponent, ITickObject
    {
        //======================================================
        #region Static methods, fields, constructors
        #endregion

        //======================================================
        #region Constructors
        #endregion

        //======================================================
        #region Public properties, operators, constants, and enums

        public T2DSceneObject SceneObject
        public T2DAnimatedSprite AnimatedSprite

        [TorqueXmlSchemaType(DefaultValue = "Closed")]
        public eDoorState DoorState
        public bool IsOpen
        public bool IsClosed
        public enum eDoorState
        {
            None=0,
            Closed=0,
            Open=1,
            NeedsKey = 2
        }
        
        public T2DAnimationData ClosedAnimation
        public T2DAnimationData NeedsKeyAnimation
        public T2DAnimationData OpenAnimation
      #endregion

        //======================================================
        #region Public methods
        public virtual void ProcessTick(Move move, float dt)
        {
            if (AnimatedSprite.AnimationData.Equals(_ClosedAnimation))
            {
                AnimatedSprite.AnimationData = _OpenAnimation;
                //AnimatedSprite.UpdateAnimation(1);
                //AnimatedSprite.PlayAnimation(_OpenAnimation);
                //var y = AnimatedSprite.Position.Y - 1;
                //AnimatedSprite.SetPosition(new Vector2(AnimatedSprite.Position.X, y), false);
            }
            else { 
                AnimatedSprite.AnimationData = _ClosedAnimation;
                //AnimatedSprite.UpdateAnimation(2);
            }
            
        }

        public override void CopyTo(TorqueComponent obj)
        {
            base.CopyTo(obj);
        }

        #endregion
        //======================================================
        #region Private, protected, internal methods

        protected override bool _OnRegister(TorqueObject owner)
        {
            if (!base._OnRegister(owner) || !(owner is T2DSceneObject))
                return false;

            // todo: perform initialization for the component
            ProcessList.Instance.AddTickCallback(Owner, this);
            // todo: look up interfaces exposed by other components
            // E.g., 
            // _theirInterface = Owner.Components.GetInterface<ValueInterface<float>>("float", "their interface name");            

            return true;
        }

        protected override void _OnUnregister()
        {
            // todo: perform de-initialization for the component

            base._OnUnregister();
        }
        protected override void _RegisterInterfaces(TorqueObject owner)
        {
            base._RegisterInterfaces(owner);

            // todo: register interfaces to be accessed by other components
            // E.g.,
            // Owner.RegisterCachedInterface("float", "interface name", this, _ourInterface);
        }


        #endregion

        //======================================================
        #region Private, protected, internal fields
        eDoorState _DoorState;
        T2DAnimationData _ClosedAnimation;
        T2DAnimationData _NeedsKeyAnimation;
        T2DAnimationData _OpenAnimation;


        #endregion
    }
}
#5
11/11/2009 (3:29 pm)
It knows what to animate because you tell it what T2DAnimationData to use (i.e. what animation to use). TX will animate whatever you animations you tell it to.
#6
11/11/2009 (5:50 pm)
I'm not so sure that the code you posted here actually works. Your code has Public members instead of properties:
public T2DAnimationData ClosedAnimation  
         public T2DAnimationData NeedsKeyAnimation  
         public T2DAnimationData OpenAnimation

and unrelated private members (which you are actually using in the code):
T2DAnimationData _ClosedAnimation;  
         T2DAnimationData _NeedsKeyAnimation;  
         T2DAnimationData _OpenAnimation;

The proper code should be:
public T2DAnimationData ClosedAnimation
         {  
             get  
             {  
                 return _ClosedAnimation;  
             }  
             set  
             {  
                 _ClosedAnimation = value;  
             }  
         }

... and so on for all of them. You are going to fill in those animation data in the TX Builder so that's why it works.