A Strange Problem....
by Lee-Orr Orbach · in Torque X 2D · 06/25/2007 (8:45 am) · 7 replies
Hello!!
I have a small problem with components in torqueX. I am making a game which will have pickups, and these pickups should be able to change a few things(score, lives, time, speed, etc...). I decided to make a pickup component in order to manage all the pickups, and this component allows editing of the change amount in each field in TXB. I noticed that all the pickups in my game do the same thing, even though I gave different values. In addition, I know that if I enable(allow creation of) only one pickup at a time, it does what it should do.
I checked this thing by debuging and seeing how it decides what to change, and how much to change it, and it turnes out the list pickup I created in TXB makes all pickups do what it does.... this means that if I add a component to an object, it actually creates only one instance of the component that is shared among all other objects that use this component. problem is, if it were so, how do the physics, collision, movement and so on components work, and if it isn't so, could someone help me understand the problem?
thanks,
Lee-Orr
Edit: I now also checked it with another component, and what happened supports the creation of only one instance of each component, instead of one instance per object.
I have a small problem with components in torqueX. I am making a game which will have pickups, and these pickups should be able to change a few things(score, lives, time, speed, etc...). I decided to make a pickup component in order to manage all the pickups, and this component allows editing of the change amount in each field in TXB. I noticed that all the pickups in my game do the same thing, even though I gave different values. In addition, I know that if I enable(allow creation of) only one pickup at a time, it does what it should do.
I checked this thing by debuging and seeing how it decides what to change, and how much to change it, and it turnes out the list pickup I created in TXB makes all pickups do what it does.... this means that if I add a component to an object, it actually creates only one instance of the component that is shared among all other objects that use this component. problem is, if it were so, how do the physics, collision, movement and so on components work, and if it isn't so, could someone help me understand the problem?
thanks,
Lee-Orr
Edit: I now also checked it with another component, and what happened supports the creation of only one instance of each component, instead of one instance per object.
#2
I have a set of 2D sprites that I insert to the TXB and to the scene. then I add a component "PickupComponent", which has intigers in it that represent the value of change for each attribute the pickup might change(default = 0), to each of the sprites. I also make them templates. I then edit the values to my liking, save the level, and run my game. now, I made two pickups(as a test), one "life_pickup" and one "score_pickup", and since I made the "score_pickup" last in the editor, when I play, both the "life_pickup" and the "score_pickup" act the way the "score_pickup" should have acted... I create the individual pickups by programming, cloning the template, due to my games requirements, so that might affect the components too...
component code:
06/25/2007 (12:35 pm)
I'll explain whats happening to me in a different way, that might help, and I'll post the code in the end...I have a set of 2D sprites that I insert to the TXB and to the scene. then I add a component "PickupComponent", which has intigers in it that represent the value of change for each attribute the pickup might change(default = 0), to each of the sprites. I also make them templates. I then edit the values to my liking, save the level, and run my game. now, I made two pickups(as a test), one "life_pickup" and one "score_pickup", and since I made the "score_pickup" last in the editor, when I play, both the "life_pickup" and the "score_pickup" act the way the "score_pickup" should have acted... I create the individual pickups by programming, cloning the template, due to my games requirements, so that might affect the components too...
component code:
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 StarterGame
{
[TorqueXmlSchemaType]
public class PickupComponent : 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; }
}
public int Lives_Change
{
get
{
return lives_Change;
}
set
{
lives_Change = value;
}
}
public int Bonus_Change
{
get
{
return bonus_Change;
}
set
{
bonus_Change = value;
}
}
public int Score_Change
{
get
{
return score_Change;
}
set
{
score_Change = value;
}
}
public int Pickup_Number
{
get
{
return pickup_number;
}
set
{
pickup_number = value;
}
}
public int Safe_Time
{
get
{
return safe_time;
}
set
{
safe_time = value;
}
}
public int Speed_Change
{
get
{
return speed_change;
}
set
{
speed_change = 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);
PickupComponent obj2 = (PickupComponent)obj;
obj2.Score_Change = Score_Change;
obj2.Safe_Time = Safe_Time;
obj2.Speed_Change = speed_change;
obj2.Pickup_Number = pickup_number;
obj2.Bonus_Change = bonus_Change;
obj2.Lives_Change = lives_Change;
}
#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);
Owner = (T2DSceneObject)owner;
T2DOnCollisionDelegate _OnPickupCollision2 = OnPickupCollision;
Owner.Collision.OnCollision = _OnPickupCollision2;
}
static T2DOnCollisionDelegate _OnPickupCollision = OnPickupCollision;
[TorqueXmlSchemaType]
public static T2DOnCollisionDelegate OOnPickupCollisionDelegate
{
get
{
return _OnPickupCollision;
}
set
{
_OnPickupCollision = value;
}
}
public static void OnPickupCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
{
if (theirObject.Name.Equals("Player"))
{
MyGame.Instance.Main_Game.Score += score_Change;
MyGame.Instance.Main_Game.Lives += lives_Change;
MyGame.Instance.Main_Game.Bonus += bonus_Change;
ourObject.MarkForDelete = true;
}
}
#endregion
//======================================================
#region Private, protected, internal fields
T2DSceneObject Owner;
static int lives_Change;
static int bonus_Change;
static int score_Change;
static int pickup_number;
static int safe_time;
static int speed_change;
#endregion
}
}
#3
06/25/2007 (12:35 pm)
.txscene file<StaticSprite name="Double_Health_Template">
<CreateWithPhysics>false</CreateWithPhysics>
<CreateWithCollision>false</CreateWithCollision>
<Components inPlace="true">
<T2DCollisionComponent type="GarageGames.Torque.T2D.T2DCollisionComponent">
<Images>
<T2DPolyImage type="GarageGames.Torque.T2D.T2DPolyImage">
<CollisionPolyBasis>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.14141</X>
<Y>-0.34343</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.02020</X>
<Y>-0.33838</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.13131</X>
<Y>-0.29293</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.23737</X>
<Y>-0.19192</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.31313</X>
<Y>-0.03535</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.31313</X>
<Y>0.06566</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.30808</X>
<Y>0.19192</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.18687</X>
<Y>0.32323</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.03535</X>
<Y>0.39899</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.08081</X>
<Y>0.41919</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.23232</X>
<Y>0.40404</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.30303</X>
<Y>0.35354</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.37879</X>
<Y>0.25758</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.43434</X>
<Y>0.14646</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.44949</X>
<Y>-0.04040</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.38384</X>
<Y>-0.18182</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.25758</X>
<Y>-0.30303</Y>
</Vector2>
</CollisionPolyBasis>
<CollisionPolyScale>
<X>1</X>
<Y>1</Y>
</CollisionPolyScale>
</T2DPolyImage>
</Images>
<RenderCollisionBounds>false</RenderCollisionBounds>
<CollidesWith>
<object objTypeRef="electron" />
<object objTypeRef="enemy" />
<object objTypeRef="pickup" />
<object objTypeRef="player" />
<object objTypeRef="startposition" />
<object objTypeRef="wall" />
</CollidesWith>
<ResolveCollision valueOf="GarageGames.Torque.T2D.T2DPhysicsComponent.BounceCollision" />
<SolveOverlap>true</SolveOverlap>
<CollisionMaterial nameRef="DefaultCollisionMaterial" />
</T2DCollisionComponent>
<T2DPhysicsComponent type="GarageGames.Torque.T2D.T2DPhysicsComponent">
<Velocity>
<X>0</X>
<Y>0</Y>
</Velocity>
<AngularVelocity>0.0</AngularVelocity>
<InverseMass>1.0</InverseMass>
<RotationScale>1.0</RotationScale>
<ProcessCollisionsAtRest>false</ProcessCollisionsAtRest>
</T2DPhysicsComponent>
<PickupComponent type="StarterGame.PickupComponent">
<Lives_Change>2</Lives_Change>
<Bonus_Change>0</Bonus_Change>
<Score_Change>0</Score_Change>
<Pickup_Number>0</Pickup_Number>
<Safe_Time>0</Safe_Time>
<Speed_Change>0</Speed_Change>
</PickupComponent>
<RandomMovmentComponent type="StarterGame.RandomMovmentComponent">
<Speed_X>15.000</Speed_X>
<Speed_Y>15.000</Speed_Y>
</RandomMovmentComponent>
</Components>
<ObjectType>
<object objTypeRef="t2dSpriteType" />
<object objTypeRef="pickup" />
</ObjectType>
<Pool>false</Pool>
<PoolWithComponents>false</PoolWithComponents>
<IsTemplate>true</IsTemplate>
<IsPersistent>false</IsPersistent>
<Layer>0</Layer>
<Size>
<X>10.000</X>
<Y>10.000</Y>
</Size>
<Position>
<X>40.000</X>
<Y>-47.719</Y>
</Position>
<Rotation>0</Rotation>
<CollisionsEnabled>true</CollisionsEnabled>
<Visible>true</Visible>
<VisibilityLevel>1</VisibilityLevel>
<FlipX>false</FlipX>
<FlipY>false</FlipY>
<SortPoint>
<X>0.000000</X>
<Y>0.000000</Y>
</SortPoint>
<Material nameRef="doublehealthpickupMaterial" />
</StaticSprite>
#4
thanks for the help :)
06/25/2007 (12:35 pm)
<StaticSprite name="Score_Template">
<CreateWithPhysics>false</CreateWithPhysics>
<CreateWithCollision>false</CreateWithCollision>
<Components inPlace="true">
<T2DCollisionComponent type="GarageGames.Torque.T2D.T2DCollisionComponent">
<Images>
<T2DPolyImage type="GarageGames.Torque.T2D.T2DPolyImage">
<CollisionPolyBasis>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.10843</X>
<Y>-0.31884</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.22892</X>
<Y>-0.19807</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.28193</X>
<Y>-0.08696</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.31084</X>
<Y>0.05797</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.25783</X>
<Y>0.24638</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.15181</X>
<Y>0.35266</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>0.02651</X>
<Y>0.39614</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.16627</X>
<Y>0.40580</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.28193</X>
<Y>0.34300</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.37831</X>
<Y>0.26570</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.46506</X>
<Y>0.06280</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.41687</X>
<Y>-0.09179</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.29157</X>
<Y>-0.28502</Y>
</Vector2>
<Vector2 type="Microsoft.Xna.Framework.Vector2">
<X>-0.12289</X>
<Y>-0.35266</Y>
</Vector2>
</CollisionPolyBasis>
<CollisionPolyScale>
<X>1</X>
<Y>1</Y>
</CollisionPolyScale>
</T2DPolyImage>
</Images>
<RenderCollisionBounds>false</RenderCollisionBounds>
<CollidesWith>
<object objTypeRef="wall" />
<object objTypeRef="player" />
<object objTypeRef="enemy" />
<object objTypeRef="electron" />
<object objTypeRef="startposition" />
<object objTypeRef="pickup" />
</CollidesWith>
<ResolveCollision valueOf="GarageGames.Torque.T2D.T2DPhysicsComponent.BounceCollision" />
<SolveOverlap>true</SolveOverlap>
<CollisionMaterial nameRef="DefaultCollisionMaterial" />
</T2DCollisionComponent>
<T2DPhysicsComponent type="GarageGames.Torque.T2D.T2DPhysicsComponent">
<Velocity>
<X>0</X>
<Y>0</Y>
</Velocity>
<AngularVelocity>0.0</AngularVelocity>
<InverseMass>1.0</InverseMass>
<RotationScale>1.0</RotationScale>
<ProcessCollisionsAtRest>false</ProcessCollisionsAtRest>
</T2DPhysicsComponent>
<RandomMovmentComponent type="StarterGame.RandomMovmentComponent">
<Speed_X>15</Speed_X>
<Speed_Y>15</Speed_Y>
</RandomMovmentComponent>
<PickupComponent type="StarterGame.PickupComponent">
<Lives_Change>0</Lives_Change>
<Bonus_Change>0</Bonus_Change>
<Score_Change>1000</Score_Change>
<Pickup_Number>0</Pickup_Number>
<Safe_Time>0</Safe_Time>
<Speed_Change>0</Speed_Change>
</PickupComponent>
</Components>
<ObjectType>
<object objTypeRef="t2dSpriteType" />
<object objTypeRef="pickup" />
</ObjectType>
<Pool>false</Pool>
<PoolWithComponents>false</PoolWithComponents>
<IsTemplate>true</IsTemplate>
<IsPersistent>false</IsPersistent>
<Layer>0</Layer>
<Size>
<X>10.000</X>
<Y>10.000</Y>
</Size>
<Position>
<X>57.911</X>
<Y>-47.523</Y>
</Position>
<Rotation>0</Rotation>
<CollisionsEnabled>true</CollisionsEnabled>
<Visible>true</Visible>
<VisibilityLevel>1</VisibilityLevel>
<FlipX>false</FlipX>
<FlipY>false</FlipY>
<SortPoint>
<X>0.000000</X>
<Y>0.000000</Y>
</SortPoint>
<Material nameRef="scorepickupMaterial" />
</StaticSprite>thanks for the help :)
#5
06/25/2007 (12:46 pm)
@Lee-Orr - I suspect this is your problem:static int lives_Change; static int bonus_Change; static int score_Change;There is only one instance of a static variable per class. With your code as it is now, every time you access the Lives_Change property (i.e. once for each of your objects with the component), it will set the single lives_Change variable to that value.
#6
06/25/2007 (1:22 pm)
OK.... Thanks...(I didn't think of that...)
#7
@Lee-Orr - Don't sweat it. I make mistakes like that all the time! ;)
06/25/2007 (7:45 pm)
Good catch, Dan.@Lee-Orr - Don't sweat it. I make mistakes like that all the time! ;)
Torque Owner Thomas Buscaglia
How are you creating the pickups and how are they configured? Would you mind posting a code sample of the public properties on your pickup component and a sample of two different pickups from the .txscene file? I'm having a little trouble visualizing exactly what's happening and why.