Game Development Community

Behavior loads infinite objects and I need one

by rennie moffat · in Torque Game Builder · 02/04/2010 (12:16 am) · 6 replies

EDIT. Please view latest reply as this thread has been updated. Thurs, Feb 4th 3.11pm



Hi there, I am facing my first major problem in terms of engineering and I am not sure how to best go about it.

I have a game where Star, can pick up a starsStar. This starsStar, once picked up can be moved. Wherever Star goes, it goes. The starsStar can then be dropped thru a dismount at which point Star will go back to the starLoader to pick up a new starsStar and the cycle continues.

This is where my question comes in.

I have created a behavior which loads a new starsStar as I want it to, however since I am using onUpdate to check to position of starsStar, when the original starsStar is moved, the computer loads a new starsStar, then another, and another, on and on infinitely, crashing the game.

I need to find a way so that only one starsStar loads at a time.

This is the loaders behavior.
Any help is very appreciated.
Thanks
Ren

if(!isObject(starRejenerator))
{
	%template = new BehaviorTemplate(starRejenerator);
	
	%template.friendlyName = "star rejenerator";
	%template.description = "adds new star to scene when one is dropped";
	%template.behaviorType = "AI";
	
	%template.addBehaviorField(starsStar, "object behavior must clone", object, "", t2dSceneObject);
}

function starRejenerator::onBehaviorAdd(%this)
{
	%this.owner.enableUpdateCallback();
}

function starRejenerator::onUpdate(%this)
{
	%this.starLoader();
}

function starRejenerator::starLoader(%this)
{
	if(!isObject(%this.starsStar))
	return;
	
	%starsStarPos = %this.starsStar.getPosition();
	%loadPos = %this.owner.getPosition();
	
	if(%starsStarPos == %loadPos)
    return;
			
	if(%starsStarPos != %loadPos)	
	%starsStar = %this.starsStar.cloneWithBehaviors();
	%starsStar.setPosition(%this.owner.getPosition());
}

About the author

My thanks to Garage Games and the Garage Games Community combined with owned determination I got one game up, Temple Racer and I am looking to build more interesting, fun games for the mass market of the iOS app store.


#1
02/04/2010 (2:47 am)
First off, you really should make this a new C++ class. Doing something that has this many constant actions in script is going to cause a potential performance problem.

Now a few problems I see in your script....

if(%starsStarPos != %loadPos)     
    %starsStar = %this.starsStar.cloneWithBehaviors();  
    %starsStar.setPosition(%this.owner.getPosition());

With this code, you will be calling .setPosition no matter what - even if the new star is not created. Always wrap your if statements in brackets, even if there is only one line. Less chances of bugs or forgetting something that way.

Next, based on this code, yes, you will get infinite stars being created. What it looks like you are doing is creating an object, and if it ever moves, creating another object, and if that ever moves creating another object, and so forth. But since you don't do any object registration, then the new object is just going to be triggering for a new object to be created. This behavior needs a solid rewrite.

Maybe something like this will do you better:

if(!isObject(starRejenerator))  
{  
    %template = new BehaviorTemplate(starRejenerator);  
      
    %template.friendlyName = "star rejenerator";  
    %template.description = "adds new star to scene when one is dropped";  
    %template.behaviorType = "AI";  
      
    %template.addBehaviorField(starsStar, "object behavior must clone", object, "", t2dSceneObject);  
    %template.addBehaviorField(activeStar, "Currently mounted star", object, "", t2dSceneObject);
}  
  
function starRejenerator::onBehaviorAdd(%this)  
{  
    %this.owner.enableUpdateCallback();  
}  
  
function starRejenerator::onUpdate(%this)  
{  
    %this.starLoader();  
}  
  
function starRejenerator::starLoader(%this)  
{  
    if(!isObject(%this.starsStar))  
   {
       return;  
   }
      
    %starsStarPos = %this.activeStar.getPosition();  
    %loadPos = %this.owner.getPosition();  
      
    if(%starsStarPos == %loadPos)  
   {
     return;  
   }       
    else
   {
    %this.activeStar = %this.starsStar.cloneWithBehaviors();  
    %this.activeStar.setPosition(%this.owner.getPosition());  
   }
}
#2
02/04/2010 (9:58 am)
I see a problem in this as how will the computer know when it is done with activeStar or not?


If the first starsStar on load level is activeStar, then it is replaced by starsStar, if mounted. Then when I drop activeStar.... nothing is done. I go back to starsStar, oick it up and the same problem will occur.

I am considering creating a loop, with say 7 stars available so, starsStar1, load, pick it up, load starsStar2 etc, then upon reaching starsStar7, it reloads starsStar1.

Is this type of programming ideal?



Also, if anyone has any other ideas, I would love to hear it. And thanks Dave.

#3
02/04/2010 (11:23 am)
I have thought of something like this, and it may well work, but not currently.


I was thinking I would copy paste a bunch of starsStar and make it so they all line up, side by side, horizontally (in the game they will be hidden, except for the one, that is available for mount). Then at the very end I have the loadPusher, a block object which will simply have a linear velocity if no star is in the loaded position. The dream is that it (the loadPusher), push the remaining starsStar's along until one starsStar, the next in line to be taken, is in the loadedPosition.

So, if no starsStar in loadedPos, loadPusher has an xVelocity of X. if a starsStar is in loadedPosition, loadPusher xVelocity = 0.

The problem I am thinking is, with so many starsStar on screen, how does the computer differentiate each one? Anyhow I am still considering a numbered starsStar system too.

here is the code for the loadPusher. Again any thoughts are welcome.
Ren

if(!isObject(starLoader))
{
	%template = new BehaviorTemplate(starLoader);
	
	%template.friendlyName = "Star Loader";
	%template.description = "Loads Stars";
	%template.behaviorType = "AI";
	
	%template.addBehaviorField(starsStar1, "object 1", object, "", t2dSceneObject);
	%template.addBehaviorField(starsStar2, "object 2", object, "", t2dSceneObject);
	%template.addBehaviorField(starsStar3, "object 3", object, "", t2dSceneObject);
	%template.addBehaviorField(starsStar4, "object 4", object, "", t2dSceneObject);
	%template.addBehaviorField(loadedXPos, "position lead object will be pushed to", float, "");
	%template.addBehaviorField(pushSpeed, "speed of loader push", float, "");
}

function starLoader::onBehaviorAdd(%this)
{
	%this.owner.enableUpdateCallback();
}

function starLoader::onUpdate(%this)
{
	%this.updateLoader(); 
}


function starLoader::updateLoader(%this)
{	
	%starsStar1XPos = getWord(%this.starsStar1.getPosition(), 0);
	
	if(%starsStar1XPos == %this.loadedXPos)
	{
		%this.owner.setLinearVelocityX(0);
	}
	
	if(%starsStar1XPos != %this.loadedXPos)
	{
		%this.owner.setLinearVelocityX(%this.pushSpeed);
	}
	
	%starsStar2XPos = getWord(%this.starsStar2.getPosition(), 0);
	
	if(%starsStar2XPos == %this.loadedXPos)
	{
		%this.owner.setLinearVelocityX(0);
	}
	
	%starsStar3XPos = getWord(%this.starsStar3.getPosition(), 0);
	
	if(%starsStar3XPos == %this.loadedXPos)
	{
		%this.owner.setLinearVelocityX(0);
	}

	%starsStar4XPos = getWord(%this.starsStar4.getPosition(), 0);
	
	if(%starsStar4XPos == %this.loadedXPos)
	{
		%this.owner.setLinearVelocityX(0);
	}


}

The problem with this code is that the pusher is unable to push the starStars. It tries but cannot. I have plaid with physics and collisions to every possible condition ( i think) and notta. I was not expecting the pusher to not be able to push objects.


:?
#4
02/04/2010 (1:57 pm)
I guess the stupid question is,
do I need to have an onUpdate call?


The reason I put it there, but in theory, could I create a sequence of events that will happen and upon player eventually having to pick up starsStar at load point, when the player hits that mark, I could call a new starsSar?

I think so.

again, any insight is welcome.



#5
02/04/2010 (4:08 pm)
OK.
so i have made up a behavior with 4 objects. starsStar1 thru to starsStar4. When 3 of the starsStar's position do not equal the loadPosition, I set the odd one out to loadPosition. This in theory should work. I simply have all required objects on screen, name it code it.

BUT WHY WONT THIS GOOOO????!!!!!

ps. that is supposed to be a long winded "go", not a loud "goo".


Thanks,
Ren

ps. I am not seeing my echo calls. :?

if(!isObject(starRejenerator))  
{  
    %template = new BehaviorTemplate(starRejenerator);  
      
    %template.friendlyName = "star rejenerator";  
    %template.description = "adds new star to scene when one is dropped";  
    %template.behaviorType = "AI";  
      
    %template.addBehaviorField(starsStar1, "object behavior must clone", object, "", t2dSceneObject);
    %template.addBehaviorField(starsStar2, "object behavior must clone", object, "", t2dSceneObject); 
    %template.addBehaviorField(starsStar3, "object behavior must clone", object, "", t2dSceneObject);
    %template.addBehaviorField(starsStar4, "object behavior must clone", object, "", t2dSceneObject); 
 
          
    %template.addBehaviorField(loadPosition, "position Star will be parked in for loading", float, 0);
    %template.addBehaviorField(starsStarLoadPosX, "position Star will be parked in for loading", float, 15);
    %template.addBehaviorField(starsStarLoadPosY, "position Star will be parked in for loading", float, 15);      
      
}  
  
function starRejenerator::onBehaviorAdd(%this)  
{  
   %this.owner.enableUpdateCallback();
}

function starRejenerator::onUpdate(%this)
{
    %this.updateLoader(); 
    echo("inOnUpdate________");
}

function starRejenerator::updateLoader(%this)
{ 
	echo("--------in updateLoader");
	
     
   %starsStar1Pos = %this.starsStar1.getPosition();
   %starsStar2Pos = %this.starsStar2.getPosition();
   %starsStar3Pos = %this.starsStar3.getPosition();  
   %starsStar4Pos = %this.starsStar4.getPosition();

   
   if(%this.starsStar1Pos != %this.starsStarLoadPos)
   {
   	if(%starsStar2Pos != %this.starsStarLoadPos)
   	{
   		if(%starsStar3Pos != %this.starsStarLoadPos)
   		{
   			%this.starsStar4.setPosition(%this.starsStarLoadPosX, %this.starsStarLoadPosY);
   		}
   	}	
   }
  
   else if(%this.starsStar1Pos != %this.starsStarLoadPos)
   {
   	if(%starsStar2Pos != %this.starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %this.starsStarLoadPos)
   		{
   			%this.starsStar3.setPosition(%this.starsStarLoadPos);
   		}
   	}	
   } 
      	
 else if(%this.starsStar1Pos != %this.starsStarLoadPos)
   {
   	if(%starsStar3Pos != %this.starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %this.starsStarLoadPos)
   		{
   			%this.starsStar2.setPosition(%this.starsStarLoadPos);
   		}
   	}	
   }	
   
 else if(%this.starsStar2Pos != %this.starsStarLoadPos)
   {
   	if(%starsStar3Pos != %this.starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %this.starsStarLoadPos)
   		{
   			%this.starsStar1.setPosition(%this.starsStarLoadPos);
   		}
   	}	
   }	
}
#6
02/05/2010 (12:47 pm)
my last post was late in the day yesterday and I have noticed some obvious errors I did not see yesterday.

I have ammended them but no go. I am wondering if anyone can help me thru this.

thanks.



if(!isObject(starRejenerator))  
{  
    %template = new BehaviorTemplate(starRejenerator);  
      
    %template.friendlyName = "star rejenerator";  
    %template.description = "adds new star to scene when one is dropped";  
    %template.behaviorType = "AI";  
      
    %template.addBehaviorField(starsStar1, "object behavior must clone", object, "", t2dSceneObject);
    %template.addBehaviorField(starsStar2, "object behavior must clone", object, "", t2dSceneObject); 
    %template.addBehaviorField(starsStar3, "object behavior must clone", object, "", t2dSceneObject);
    %template.addBehaviorField(starsStar4, "object behavior must clone", object, "", t2dSceneObject); 
 
}  
  
function starRejenerator::onBehaviorAdd(%this)  
{  
   %this.owner.enableUpdateCallback();
   %this.starsStar1.setPosition(%this.owner.getPosition());
}

function starRejenerator::onUpdate(%this)
{
    %this.updateLoader(); 
    echo("inOnUpdate________");
}

function starRejenerator::updateLoader(%this)
{ 
	echo("--------in updateLoader");
	
   %starsStarLoadPos = %this.owner.getPosition();
     
   %starsStar1Pos = %this.starsStar1.getPosition();
   %starsStar2Pos = %this.starsStar2.getPosition();
   %starsStar3Pos = %this.starsStar3.getPosition();  
   %starsStar4Pos = %this.starsStar4.getPosition();

   
   if(%this.starsStar1Pos != %starsStarLoadPos)
   {
   	if(%starsStar2Pos != %starsStarLoadPos)
   	{
   		if(%starsStar3Pos != %starsStarLoadPos)
   		{
   			%this.starsStar4.setPosition(%starsStarLoadPos);
   		}
   	}	
   }
  
   else if(%this.starsStar1Pos != %starsStarLoadPos)
   {
   	if(%starsStar2Pos != %starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %starsStarLoadPos)
   		{
   			%this.starsStar3.setPosition(%starsStarLoadPos);
   		}
   	}	
   } 
      	
 else if(%this.starsStar1Pos != %starsStarLoadPos)
   {
   	if(%starsStar3Pos != %starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %starsStarLoadPos)
   		{
   			%this.starsStar2.setPosition(%starsStarLoadPos);
   		}
   	}	
   }	
   
 else if(%this.starsStar2Pos != %starsStarLoadPos)
   {
   	if(%starsStar3Pos != %starsStarLoadPos)
   	{
   		if(%starsStar4Pos != %starsStarLoadPos)
   		{
   			%this.starsStar1.setPosition(%starsStarLoadPos);
   		}
   	}	
   }	
}