Removing objects from the world
by Matthew Barney · in Torque X 2D · 11/14/2007 (12:37 pm) · 12 replies
Hello, I posted this over in Getting Started but I've been having more luck getting responses here in General discussion so I thought I'd repost an issue I'm having.
I'm having a bit of a problem removing instances of an object from my game world. Here's the idea:
The player can clone themselves, however they are only allowed to make so many clones and when they try to make a new one the oldest one is removed from the game. I've tried using unregister to unregister the oldest one and then creating a new one with the same name and registering it but when I try to reregister the object it complains about having not been reset. I tried using reset on it but it doesn't seem to make a difference.
I tried to work around this by marking the oldest one for deletion, then deleting it. While this seems to get rid of the components tied to the object I still have the animation on screen.
Any hints or tips?
I'm having a bit of a problem removing instances of an object from my game world. Here's the idea:
The player can clone themselves, however they are only allowed to make so many clones and when they try to make a new one the oldest one is removed from the game. I've tried using unregister to unregister the oldest one and then creating a new one with the same name and registering it but when I try to reregister the object it complains about having not been reset. I tried using reset on it but it doesn't seem to make a difference.
I tried to work around this by marking the oldest one for deletion, then deleting it. While this seems to get rid of the components tied to the object I still have the animation on screen.
Any hints or tips?
#2
11/14/2007 (2:02 pm)
I gave each clone a name but beyond that, nothing to track them.
#3
Back to keeping track of your clones... I would probably use a queue or a linkedlist to hold references to the clones in the same component that creates the clones. See System.Collections.Generic for how to use queues and linkedlists. That's in the .net framework help.
Queues operate on the first in first out principal. You always remove the oldest one first.
C#'s linkedlists on the other hand allow you to add and remove from anywhere in the list. They are actually doubly linked lists. This structure can work like a queue does with the benefit of removing and adding from anywhere if needed.
11/14/2007 (2:52 pm)
Sorry for more questions, but what is the code you are using to delete old objects? It sounds like you are setting object.MarkForDelete = true, but also Unregistering it with the TorqueObjectDatabase. It's not necessary to unregiester when you mark for delete, that is handled for you.Back to keeping track of your clones... I would probably use a queue or a linkedlist to hold references to the clones in the same component that creates the clones. See System.Collections.Generic for how to use queues and linkedlists. That's in the .net framework help.
Queues operate on the first in first out principal. You always remove the oldest one first.
C#'s linkedlists on the other hand allow you to add and remove from anywhere in the list. They are actually doubly linked lists. This structure can work like a queue does with the benefit of removing and adding from anywhere if needed.
#4
if (_ghostCount == 6)
{
T2DSceneObject _ghost = TorqueObjectDatabase.Instance.FindObject("ghost0");
TorqueObjectDatabase.Instance.Unregister(_ghost);
_ghost.Reset();
T2DSceneObject _player = TorqueObjectDatabase.Instance.FindObject("Player");
_ghostCount = 0;
System.Console.WriteLine(_ghost.Name);
_ghost.Components.FindComponent().setQueue(_savedMove);
_ghost.Position = _player.Position;
_ghost.Layer = _player.Layer;
TorqueObjectDatabase.Instance.Register(_ghost);
_ghostCount++;
}
11/14/2007 (3:28 pm)
Here's the code I was using:if (_ghostCount == 6)
{
T2DSceneObject _ghost = TorqueObjectDatabase.Instance.FindObject
TorqueObjectDatabase.Instance.Unregister(_ghost);
_ghost.Reset();
T2DSceneObject _player = TorqueObjectDatabase.Instance.FindObject
_ghostCount = 0;
System.Console.WriteLine(_ghost.Name);
_ghost.Components.FindComponent
_ghost.Position = _player.Position;
_ghost.Layer = _player.Layer;
TorqueObjectDatabase.Instance.Register(_ghost);
_ghostCount++;
}
#5
11/14/2007 (3:51 pm)
So when you set MarkForDelete on the object it doesn't disappear?
#6
What happens before and after this? What is Reset() supposed to do? I created an object then unregistered it and reset it. the object variable contained the same data after calling Reset(). Is there a reason why you are reusing _ghost to register a the same scene object at the _players position? What is setQueue() acomplishing.
This line though, did remove my scene object. I use MarkForDelete personally.
On a different note I kept thinking _ghost and _player were class variables not local variables. The underscore convention is usuaually used on private class variables.
11/14/2007 (6:20 pm)
More questions.What happens before and after this? What is Reset() supposed to do? I created an object then unregistered it and reset it. the object variable contained the same data after calling Reset(). Is there a reason why you are reusing _ghost to register a the same scene object at the _players position? What is setQueue() acomplishing.
TorqueObjectDatabase.Instance.Unregister(_ghost);
This line though, did remove my scene object. I use MarkForDelete personally.
On a different note I kept thinking _ghost and _player were class variables not local variables. The underscore convention is usuaually used on private class variables.
#7
I guess I don't need to reuse the same object, at the time it seemed like a good way of doing it but I guess not.
My knowledge of C#/Torque is kinda low so SetQueue is my way of passing a queue of info (move list) to the clones.
Can you show me an example of how to use MarkForDelete? I have to admit I come from a mostly C++ background so some of this stuff is really knew to me.
11/14/2007 (9:22 pm)
I don't know what Reset is supposed to do, all I know is if I put Unregister and run it complains that the object wasn't reset.I guess I don't need to reuse the same object, at the time it seemed like a good way of doing it but I guess not.
My knowledge of C#/Torque is kinda low so SetQueue is my way of passing a queue of info (move list) to the clones.
Can you show me an example of how to use MarkForDelete? I have to admit I come from a mostly C++ background so some of this stuff is really knew to me.
#8
11/15/2007 (6:40 am)
Calling MarkForDelete on the object already calls UnRegister, so I don't think you really need to call it. So if the player tries to clone themselves, get a reference to oldest clone and use MarkForDelete on it . Then clone the new.oldObject.MarkForDelete = true;
T2DSceneObject newObject = TorqueObjectDataBase.Instance.CloneObject<T2dSceneObject>("objectTemplate");
newObject.Position = ClonePosition;
newObject.Visible = true;
TorqueObjectDatabase.Instance.Register(newObject);
#9
It doesn't seem like it should be this hard to remove a character from the game world...
11/15/2007 (12:59 pm)
I tried that rwillis and I get an error message when the code occurs. "Cannot render objects without materials."It doesn't seem like it should be this hard to remove a character from the game world...
#10
Mathew, I think you are going to need to rethink how you keep track of your clones. I would go about this by creating a component to attach to the player, say it's called CloningComponent. This component would hold a list of all clones currently in play, and handle adding and deleting clones. The function to add a clone would be fired from a keypress or whatever your criteria might be. In my mind the process would go something like this.
Request to create a new clone is received
Clone the player or player template, register it in the DB, and push it to the end of a linked list.
Check the length of the linked list,
if it's more than the allowed number of clones,
get the object at the front of the list
set its markfordelete property to true
remove it from the linked list
I whipped this up real quick.
EDIT: I just want to add that this list can also be used to handle updates on all clones via a foreach. Clones could also have their own component that controls their AI.
Some variables.
And the process in C#
11/15/2007 (2:48 pm)
I just want to add that the MarkForDelete property just adds the object to a ready to delete list that gets checked by the object database each time through the game loop. It doesn't remove immediatly.Mathew, I think you are going to need to rethink how you keep track of your clones. I would go about this by creating a component to attach to the player, say it's called CloningComponent. This component would hold a list of all clones currently in play, and handle adding and deleting clones. The function to add a clone would be fired from a keypress or whatever your criteria might be. In my mind the process would go something like this.
Request to create a new clone is received
Clone the player or player template, register it in the DB, and push it to the end of a linked list.
Check the length of the linked list,
if it's more than the allowed number of clones,
get the object at the front of the list
set its markfordelete property to true
remove it from the linked list
I whipped this up real quick.
EDIT: I just want to add that this list can also be used to handle updates on all clones via a foreach. Clones could also have their own component that controls their AI.
Some variables.
// Private variables owned by the component private LinkedList<T2DSceneObject> _cloneList = new LinkedList<T2DSceneObject>(); private int _maxNumClones = 4;
And the process in C#
// Create a clone function
// If there are too many, delete the oldest one.
T2DSceneObject temp = TorqueObjectDatabase.Instance.CloneObject<T2DSceneObject>("CloneTemplate");
temp.Position = Vector2.Zero;
temp.Rotation = 0f;
temp.Physics.Velocity = Vector2.Zero;
TorqueObjectDatabase.Instance.Register(temp);
_cloneList.AddLast(temp);
if (_cloneList.Count > _maxNumClones)
{
_cloneList.First.Value.MarkForDelete = true;
_cloneList.RemoveFirst();
}
#11
11/15/2007 (6:39 pm)
I'm not sure how the list helps. I tried what you've suggested but its the same problem where the MarkedForDelete doesn't work. I'm still getting the same error about rendering as I had before. I tried setting the sprite to not visible but same thing.
#12
The benefit of the list is that it keeps the objects in order, and you can itterate through the list if you need to. It knows how many items are in it and it is searchable if you need it to be.
11/15/2007 (7:43 pm)
Hmm, your problem might be elsewhere in your code. I'd have to see a full code listing to try and help you further. You can contact me on msn if you'd like further help. My address is jtron5050@gmail.com.The benefit of the list is that it keeps the objects in order, and you can itterate through the list if you need to. It knows how many items are in it and it is searchable if you need it to be.
Torque Owner Joshua A. Thomas