TorqueX/ListsTXB
From TDN
|
[edit] Introduction
This example assumes that you have explored the basic concepts about Torque X (TX) and Torque X Builder (TXB)
[edit] The CodeThe code does most of the explaining of what each part does.
using System;
using System.Collections.Generic;
//Used for GarageGames' version of the deserializer
//[TorqueXmlDeserializeInclude]
using GarageGames.Torque.Core;
//Used by C# to tell it that the public property can be deserializer
//[XmlElement(ElementName = "MyListedExamples")]
using System.Xml.Serialization;
//used for the ReadOnlyArray
using GarageGames.Torque.Util;
using Microsoft.Xna.Framework;
//To allow use of interface IT2DForceGenerator
using GarageGames.Torque.Sim;
using GarageGames.Torque.T2D;
namespace GarageGames.Torque.PlatformerFramework
{
[TorqueXmlSchemaType] //This is so it can be exported into the schema of components used by TXB
class PodComponent : TorqueComponent
{
//[TorqueXmlDeserializeInclude]
//tells the compiler that it's to be exported in the XML schema
//The same effect can be achieved using a public varible, but it's
//considered bad programming to declare public fields
[TorqueXmlDeserializeInclude]
//[XmlElement(ElementName = "Forces")]
//Tells the complier the name of the property to be written to the XML file
//If this is left out, the default name will be the varible name. In this case "rubble"
[XmlElement(ElementName = "RubbleValues")]
//Will store a list of rubble created in TXB
private List<Rubble> rubble;
protected override bool _OnRegister(TorqueObject owner)
{
if (rubble != null)
{
//loop through the "rubble" array
foreach (Rubble singleObject in rubble)
{
//Check to see if the object exists in the scene
//This should always be true since we have a nice list where we choose the object, but sometimes things get deleted!!
T2DSceneObject sceneObject = TorqueObjectDatabase.Instance.FindObject<T2DSceneObject>(singleObject.SceneObject.Name);
if (sceneObject != null)
{
//get a copy of the selected object that we will throw around
sceneObject = (T2DSceneObject)sceneObject.Clone();
sceneObject.Position = ((T2DSceneObject)Owner).Position;
//Add the component that created this T2DSceneObject!!
sceneObject.Components.AddComponent(singleObject);
//Register the object with the database. Otherwise you won't find it!
TorqueObjectDatabase.Instance.Register(sceneObject);
}
}
}
return base._OnRegister(owner);
}
}
/// <summary>
/// This is simply a container that holds various values
/// </summary>
public class Rubble : TorqueComponent, IT2DForceGenerator
{
//======================================================
#region Private, protected, internal fields
//The position where this object will stop
private Vector2 finalPosition;
//The time taken to get to distanation
private float time;
//The rate to rotate the object
private float rotationSpeed;
//The object that will be created and moved around
private T2DSceneObject sceneObject;
//Whether the finalPosition is relative to the Owner of the component
private bool relative;
//Stores the owner(TorqueObject) as (T2DSceneObject)
T2DSceneObject myOwner;
// force interface
TorqueInterfaceWrap<IT2DForceGenerator> _forceInterface = new TorqueInterfaceWrap<IT2DForceGenerator>();
//The distance from start to the final position
float distance;
//The starting position of the owner object
Vector2 startPosition;
#endregion
//======================================================
#region Public properties, operators, constants, and enums
/// <summary>
/// The time in which this component should reach the [finalPosition]
/// </summary>
[TorqueXmlSchemaType(DefaultValue = "10")]
public float Time
{
get { return time; }
set { time = value; }
}
/// <summary>
/// The coordinates that this object should move to
/// (DefaultValue = "5 5") gives the vector a value of Vector(5,5)
/// </summary>
[TorqueXmlSchemaType(DefaultValue = "25 25")]
public Vector2 FinalPosition
{
get { return finalPosition; }
set { finalPosition = value; }
}
/// <summary>
/// The rate of rotation for the object
/// </summary>
[TorqueXmlSchemaType(DefaultValue = "10")]
public float Rotation
{
get { return rotationSpeed; }
set { rotationSpeed = value; }
}
/// <summary>
/// The object(a TXB template) that will be created. In TXB this will show up as a
/// list of T2DSceneObjects that you have given names. T2DSceneObject names are given in the
/// "Scripting" component, also it's recomended to mark them as "Template" by ticking the box.
/// This lets you create as many as you wish(clones) to the object without desetroying it
/// </summary>
public T2DSceneObject SceneObject
{
get { return sceneObject; }
set { sceneObject = value; }
}
/// <summary>
/// Whether the FinalPosition of this object should be relative to
/// the SceneObject that owns this component. A bool value in TXB
/// looks like a tickbox. If the default value is "1" then it's ticked,
/// "0" for unticked
/// </summary>
[TorqueXmlSchemaType(DefaultValue = "1")]
public bool Relative
{
get { return relative; }
set { relative = value; }
}
#endregion
//======================================================
#region Public methods
/// <summary>
/// IT2DForceGenerator interface method. Called by the Physics component before the current move is processed.
/// </summary>
public virtual void PreUpdateForces(Move move, float elapsed){}
/// <summary>
/// IT2DForceGenerator interface method. Called by the Physics component after the current move is processed.
/// </summary>
public virtual void PostUpdateForces(Move move, float elapsed)
{
if (Vector2.Distance(myOwner.Position, startPosition) > distance)
{
//This means we have arrived at our finalPosition!
myOwner.Physics.Velocity = Vector2.Zero;
}
}
/// <summary>
/// Start the movement!
/// </summary>
public void Start()
{
//speed = distance(vector) / time
myOwner.Physics.Velocity = (startPosition - FinalPosition) / time;
}
#endregion
//======================================================
#region Private, protected, internal methods
protected override bool _OnRegister(TorqueObject owner)
{
//Find Owner as a T2DSceneObject
myOwner = ((T2DSceneObject)owner);
//myOwner.Physics is another Component which is by default added in
//every component, but you should check if it exists
T2DPhysicsComponent physics = myOwner.Physics;
Assert.Fatal(physics != null, "The component " + myOwner.Name + " requires a T2DPhysics component");
//Add rotation to the Owner object
physics.AngularVelocity = Rotation;
//Store some varibles
startPosition = myOwner.Position;
if (Relative){
finalPosition += myOwner.Position;
}
//calulate the distance form the start position to the finalPosition
distance = Vector2.Distance(myOwner.Position, finalPosition);
Start();
return base._OnRegister(owner);
}
/// <summary>
/// This method allows us to register iterfaces. IT2DForceGenerator is an example of an interface
/// </summary>
/// <param name="owner">Owner of the component</param>
protected override void _RegisterInterfaces(TorqueObject owner)
{
// register the force generator interface to allow us to get
// pre- and post- update physics callbacks
Owner.RegisterCachedInterface("force", String.Empty, this, _forceInterface);
}
#endregion
}
}
[edit] Importing the code in a game
[edit] The PodComponentNow that you've successfully imported the component into TXB it's time to add it to an object. The object can be anything of your choice. This object will be the one that creates the rubble objects. [edit] The Rubble ComponentThe podComponent also requires other T2DScenceObjects to be created to be attached to the podComponent. To do this create a component(s), they can be anything you like, making sure that they have the T2DPhysicsComponent. Give it them a name in the scripting tab. [edit] Time to bring it togetherNow that we have a T2DSceneObject set up with the podComponent installed and object(s) with a scripted name. We can now add Rubble to our podComponent. Fill in the details required and press the little green button. This will add those values to a RubbleComponent when the game is run. You can create multiple values of Rubble for the PodComponent. See the image. [edit] Behind the scenesWhen you save the scene, the values are written into the level data. When the scene loads it finds the PodComponent and its list of Rubble. Then looks at the T2DScenceObject that the rubble is referencing creates a template of it and then adds the Rubble component to it. [edit] ConclusionI hope this gives a little more insight into how the XML schema is created and methods to create lists types in TXB. |



