Game Development Community

some one please help me understamd simsets

by hbomega · in Torque 2D Beginner · 12/15/2013 (11:17 pm) · 14 replies

I jus need a few questions answered and i should be fine

1 how do you test a Simset object for collision

#1
12/16/2013 (3:54 am)
A simset is a list of objects and thus they cannot be tested for collision.
(It would be similar to trying a test a variable for collision, it doesn't make sense)
If you want to test if every object in a simset has collided with some object, I believe you would have to either do it in code, or doing a workaround in TorqueScript.
#2
12/16/2013 (10:56 am)
Perhaps it is a misunderstanding in the logic? Typically the physics simulation handles collision testing for you - and when a collision does happen you have access to it through the onCollision callback. In this callback you can check if one of the colliding objects belongs to a SimSet.
#3
12/16/2013 (6:10 pm)
@ MIKE thats exactly what i am trying to do, but dont seem to understand how to go about it. lets say i have a specific enemy type storing in Simset OddEnemySet now when a collision takes place with one of these objects i would like to test if it belongs to OddEnemySet then check to see if all enemy in the set is destroyed
#4
12/20/2013 (6:40 am)
new SimSet(OddEnemySet);
new SimSet(EvenEnemySet);

OddEnemySet.add(%object);
EvenEnemySet.add(%otherObject);

if(OddEnemySet.isMember(%object))
{
    // do some stuff
}

if(EvenEnemySet.isMember(%object))
{
    // do other stuff
}

// or, for instance
function MyObjectClass::onCollision(%this) // parameters omitted, just because
{
    if(OddEnemySet.isMember(%this))
    {
        // do stuff
    }
}
#5
12/20/2013 (5:10 pm)
@ Richard thanks going to try now
#6
12/20/2013 (6:02 pm)
It worked partially now i'm having problems deleting the object, everything reacts correctly except the object itself isnt deleted, i believe whats going on is when i test for the object with the following code

function MyObjectClass::onCollision(%this,%sceneobject,%collisiondetails )
{
if(OddEnemySet.isMember(%sceneobject))
{
%object = OddEnemySet.getobject(%sceneobject);
%object.delete();
}
}

what i believe is going on is i need to get the actual position of the member of OddEnemySet, so i could pass that as the argument for OddEnemySet.getobject() instead of %sceneobject, but i don't know how, and i'm not even sure i'm correct
#7
12/20/2013 (6:12 pm)
Why not just
%sceneobject.delete();
? Seems to me that would work alright.. Also doesn't getObject like need an index, and not the id of an object?
#8
12/21/2013 (7:37 am)
Actually, it might be better to use safeDelete(). But yeah, what Lucas said:
function MyObjectClass::onCollision(%this,%sceneobject,%collisiondetails )
{ 
  if(OddEnemySet.isMember(%sceneobject)) 
  { 
    %sceneobject.safeDelete();
  } 
}
Or, to be a little safer:
function MyObjectClass::onCollision(%this,%sceneobject,%collisiondetails )
{ 
  if(OddEnemySet.isMember(%sceneobject)) 
  { 
    %sceneobject.schedule(100, safeDelete); // try to avoid delete in a callback
  } 
}
I usually set up an EventManager to handle "garbage collection" because you can't delete an object in a callback on itself, sometimes not even using a schedule.
function initializeGameStateEventManager()
{
    if (!isObject(GameStateEventManager))
    {
        $GameStateEventManager = new EventManager(GameStateEventManager)
        { 
            queue = "GameStateEventManager"; 
        };
        
        // Module related signals
        GameStateEventManager.registerEvent("_DeleteRequest");
    }
    
    if (!isObject(GameStateListener))
    {
        $GameStateListener = new ScriptMsgListener(GameStateListener) 
        { 
            class = "GameStateEventListener"; 
        };
        
        // Module related subscriptions
        GameStateEventManager.subscribe(GameStateListener, "_DeleteRequest", "onDeleteRequest");
    }
}

// Cleanup the GameStateEventManager
function destroyGameStateEventManager()
{
    if (isObject(GameStateEventManager) && isObject(GameStateListener))
    {
        // Remove all the subscriptions
        GameStateEventManager.remove(GameStateListener, "_DeleteRequest");

        // Delete the actual objects
        GameStateEventManager.delete();
        GameStateListener.delete();
        
        // Clear the global variables, just in case
        $GameStateEventManager = "";
        $GameStateListener = "";
    }
}

function GameStateEventListener::onDeleteRequest(%this, %msgData)
{
    // handle GameState delete requests
    // %msgData, passed in postEvent, should carry our object's ID
    echo(" @@@ GameStateEventListener::onDeleteRequest(" @ %this @ ", " @ %msgData @")");
    %msgData.schedule(100, safeDelete);
}

// -----------
// somewhere in your code, call initializeGameStateEventManager(), then this should work
function MyObjectClass::onCollision(%this,%sceneobject,%collisiondetails )
{ 
  if(OddEnemySet.isMember(%sceneobject)) 
  { 
    GameStateEventManager.postEvent("_DeleteRequest", %sceneobject);
  } 
}
// somewhere when shutting down call destroyGameStateEventManager()
Now you've passed the "garbage collection" off to a "third-party" object and the delete happens outside of the callback.
#9
12/21/2013 (4:43 pm)
thanks guys it worked
#10
12/21/2013 (4:55 pm)
@Richard
i will definitely try to implement an eventmanager
#11
12/21/2013 (5:09 pm)
when i try usin the event manager i get the following error in the console log, and does not delete the object in game



Unable to find object: 'GameStateEventManager' attempting to call function 'postEvent'
#12
12/21/2013 (9:01 pm)
From my last post:
// somewhere in your code, call initializeGameStateEventManager(), then this should work
#13
12/22/2013 (10:25 pm)
Thanks it works great a bit slower but for a worthy cause
#14
12/23/2013 (11:30 am)
If you want to speed it up, reduce the number in the schedule call to something like 50 or 32 - but not less than 32. This is the number of milliseconds after the call to schedule() that the even will be scheduled for and script events tick at 32 milliseconds. Trying to schedule events with a time less than 32 milliseconds can cause the engine to cry about events scheduled for invalid times.

You could also try hiding the object immediately and then scheduling deletion (call %obj.setVisible(false); before the schedule() call) or immediately deleting the object, but deleting it immediately might make it hiccough - experiment.