Gravitational Pull - Math done, need help with coding
by Tyler Slabinski · in Torque Game Builder · 07/28/2010 (3:20 am) · 11 replies
For the past 2 or so hours (not counting the minor bugs I ran into when starting), I've been working on a script that gives a gravitational force between a "planet" (object effected by gravity), and a "star" (object emitting the pull). Here is my quick script:
Gravity.cs
Now this script works perfectly when there is a single star and a single planet in the level, but what fun would that be? This script completely breaks when you add a second star or planet. It treats all the planets as a single entity, and they can only be effected by one star.
I am not very good at editing the engine source code, so I was wondering if anyone could help me walk through this, since I know it would be crazy having 20+ planets doing all that math at once.
Gravity.cs
function starClass::onLevelLoaded(%this, %scenegraph)
{
$Star = %this;
}
function planetClass::onLevelLoaded(%this, %scenegraph)
{
$Planet = %this;
$Planet.enableUpdateCallBack();
}
function planetClass::onUpdate(%this)
{
%starX = $Star.getPositionX();
%starY = $Star.getPositionY();
%starPos = $Star.getPosition();
%planetX = $Planet.getPositionX();
%planetY = $Planet.getPositionY();
%planetPos = $Planet.getPosition();
%distance = t2dVectorDistance(%starPos, %planetPos);
%pastX = $Planet.getLinearVelocityX();
%pastY = $Planet.getLinearVelocityY();
%x = (%starX - %planetX) * 1 / (%distance);
%y = (%starY - %planetY) * 1 / (%distance);
%this.setLinearVelocity(%x + %pastX, %y + %pastY);
}Now this script works perfectly when there is a single star and a single planet in the level, but what fun would that be? This script completely breaks when you add a second star or planet. It treats all the planets as a single entity, and they can only be effected by one star.
I am not very good at editing the engine source code, so I was wondering if anyone could help me walk through this, since I know it would be crazy having 20+ planets doing all that math at once.
About the author
Working on prototype.
#2
07/28/2010 (5:38 pm)
If you want to use the code you provided, you need to get rid of those globals. function starClass::onLevelLoaded(%this, %scenegraph)
{
$Star = %this;
}
function planetClass::onLevelLoaded(%this, %scenegraph)
{
//$Planet = %this;
//$Planet.enableUpdateCallBack();
%this.enableUpdateCallBack();
}
function planetClass::onUpdate(%this)
{
%starX = $Star.getPositionX();
%starY = $Star.getPositionY();
%starPos = $Star.getPosition();
%planetX = %this.getPositionX();
%planetY = %this.getPositionY();
%planetPos = %this.getPosition();
%distance = t2dVectorDistance(%starPos, %planetPos);
%pastX = %this.getLinearVelocityX();
%pastY = %this.getLinearVelocityY();
%x = (%starX - %planetX) * 1 / (%distance);
%y = (%starY - %planetY) * 1 / (%distance);
%this.setLinearVelocity(%x + %pastX, %y + %pastY);
}That should work if you only have one star and many planets.
#3
This works using multiple planets, but only one star can be on the scene at a time. I have an idea for adding more stars, but it requires making separate classes and functions for each.
Does anyone know how I could use this on multiple stars?
07/30/2010 (12:08 am)
Okay, I just finished (at least for a prototype) a script that will give an object gravity towards another object:function starClass::onLevelLoaded(%this, %scenegraph)
{
$star = %this;
}
//Update a callback every frame for the planet (%this)
function planetClass::onLevelLoaded(%this, %scenegraph)
{
%this.enableUpdateCallBack();
}
function planetClass::onUpdate(%this)
{
%pastX = %this.getLinearVelocityX();
%pastY = %this.getLinearVelocityY();
%distance = t2dVectorDistance($star.getPosition(), %this.getPosition());
%x = $star.getPositionX() - %this.getPositionX();
%y = $star.getPositionY() - %this.getPositionY();
%sum = mAbs(%x) + mAbs(%y);
%powerX = castGravityX(%sum, %x, %distance);
%powerY = castGravityY(%sum, %y, %distance);
%this.setLinearVelocity(%powerX + %pastX, %powerY + %pastY);
}
function castGravityX(%sum, %x, %distance)
{
%x = %x / %sum;
return (%x / %distance) * 300;
}
function castGravityY(%sum, %y, %distance)
{
%y = %y / %sum;
return (%y / %distance) * 300;
}This works using multiple planets, but only one star can be on the scene at a time. I have an idea for adding more stars, but it requires making separate classes and functions for each.
Does anyone know how I could use this on multiple stars?
#4
I'd *HIGHLY* recommend that you process all of the objects in one loop.
The other option is to make a SimSet of the Stars (instead of using a global variable). Then each planet can iterate over the SimSet of Stars in order to calculate their pull. You can write something like this:
07/30/2010 (1:56 am)
There's a couple of options I can think of.I'd *HIGHLY* recommend that you process all of the objects in one loop.
The other option is to make a SimSet of the Stars (instead of using a global variable). Then each planet can iterate over the SimSet of Stars in order to calculate their pull. You can write something like this:
new SimSet(StarList);
function starClass::onLevelLoaded( %this, %scenegraph )
{
StarList.add( %this );
}
function planetClass::onUpdate( %this )
{
%cStars = StarList.getCount();
for( %i = 0; %i < %cStars; %i++ )
{
%star = StarList.getObject( %i );
... and so on ...
}
}
#5
07/30/2010 (1:56 am)
P.S. If you do the latter method, don't forget to either clean up the SimSet between levels!
#6
EDIT: It's starting to work now! Thanks for the help. I wish I knew enough of the engine to turn the math into code (instead of script), but I am just working on a prototype right now, so I guess it doesn't matter.
Here is the finished script:
Gravity.cs
07/30/2010 (2:52 am)
I never should have skipped the chapter of simsets in that old Torque book.EDIT: It's starting to work now! Thanks for the help. I wish I knew enough of the engine to turn the math into code (instead of script), but I am just working on a prototype right now, so I guess it doesn't matter.
Here is the finished script:
Gravity.cs
new SimSet(StarList);
function starClass::onLevelLoaded(%this, %scenegraph)
{
StarList.add(%this);
}
//Update a callback every frame for the planet (%this)
function planetClass::onLevelLoaded(%this, %scenegraph)
{
%this.enableUpdateCallBack();
}
function planetClass::onUpdate(%this)
{
%cStars = StarList.getCount();
for( %i = 0; %i < %cStars; %i++ )
{
%star = StarList.getObject(%i);
%pastX = %this.getLinearVelocityX();
%pastY = %this.getLinearVelocityY();
%distance = t2dVectorDistance(%star.getPosition(), %this.getPosition());
%x = %star.getPositionX() - %this.getPositionX();
%y = %star.getPositionY() - %this.getPositionY();
%sum = mAbs(%x) + mAbs(%y);
%powerX = castGravityX(%sum, %x, %distance);
%powerY = castGravityY(%sum, %y, %distance);
%this.setLinearVelocity(%powerX + %pastX, %powerY + %pastY);
}
}
function castGravityX(%sum, %x, %distance)
{
%x = %x / %sum;
return (%x / %distance) * 300;
}
function castGravityY(%sum, %y, %distance)
{
%y = %y / %sum;
return (%y / %distance) * 300;
}
#7
Error: cannot change namespace parent linkage of Star from t2dStaticSprite to Star.
Error: cannot change namespace parent linkage of planet from t2dStaticSprite to planet.
Please help.
09/09/2010 (3:40 pm)
I' trying implement the above code but get the following console errors: Error: cannot change namespace parent linkage of Star from t2dStaticSprite to Star.
Error: cannot change namespace parent linkage of planet from t2dStaticSprite to planet.
Please help.
#8
09/09/2010 (3:54 pm)
Ok, I've fixed that error on my own; it had nothing to do with your code was a fragment of an old function that i forgot to completely comment out. Now the console says that it compiled your script. However nothing seems to happen. I assigned the "planet" and star classes each to an object.
#9
09/09/2010 (4:00 pm)
I'm wondering where exactly you put the command to execute the script to get it working.
#10
09/09/2010 (4:09 pm)
Ok, I got it working. But when an object hits the ground it moves back an forth along the ground. Is there a fix for this?
#11
09/09/2010 (7:38 pm)
You are going to need to make some sort of code for friction. I may be able to find time in a few hours to try something, but I am not sure if it will work.
Associate William Lee Sims
Machine Code Games