Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

fatherjohn666

help with stl's and sphere colliding

This topic is 5776 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys. Im gonna explain this a simple as possible. I have two stl lists. one holds X number of asteroids the other holds x number of missles. I have coded it so that when I fire a missle and it reaches a certain point, that specific link on that missle list is .erase()'d I want to tie this in with the asteroid link list so if the rocket and asteroid collide (sphere collision being used) then they both die. My problem is tieing the two link lists in together to check for this. Whether or not this is a good method is another arguement, but if you can enlighten me with some help, i would most certainly appreciate it. here is the code for running through the lists, straight from my draw() function (this is opengl)
        
	for(astWalker = asteroidList.begin(); astWalker != asteroidList.end(); astWalker++)	
	{	// now update each animation for each rocket in the list!

		astWalker->Animate(elapsedSeconds); 
		astWalker->Draw();
	}

	// now we traverse our rockets link list, this one DRAWS the rockets

	if(rocketList.size() > 0)	// dont bother unless we have something to play with!

	{
		for(rokWalker = rocketList.begin();	rokWalker != rocketList.end(); rokWalker++)
					// now update each animation for each rocket in the list!

		{	
			rokWalker->Animate(); 
			
			// now we traverse our asteroid link list, this one TESTS FOR COLLISIONS

			for(astWalker = asteroidList.begin(); astWalker != asteroidList.end(); astWalker++)	
			
				// now check if the collision spheres radius total is <=

				// the length of the distance between the asteroid and the missle

			{	
				float radi = (astWalker->size + rokWalker->size);
				float dist = (astWalker->position - rokWalker->position).Length();
				
				if (  dist <  radi)
				{	// if so, kill the asteroid AND the rocket, and continue


					asteroidList.erase(astWalker);
					rocketList.erase(rokWalker);
					
				}

			}	// COOL!

		
			if (rokWalker->death())		// has this rocket hit its distance?

				rocketList.erase(rokWalker++);	// if so, kill it.


		}

	}	// that was easy	


  
in my main.h file elsewhere I have the following declarations
  
using namespace std;	// not quite sure what this does, however its essential for link lists

list<CRocket> rocketList;				// initialize a rocket link list

list<CAsteroid> asteroidList;			// initialize an asteroid link list

list<CRocket>::iterator rokWalker;		// asteroid list walker

list<CAsteroid>::iterator astWalker;	// asteroid list walker

  
but thats not the hassle. I get strange results, crashes....you name it, but no accurate sphereical collisions. If you can help me recode this, I would severly appreciate it. PS: Everything was fine until I had this sphere stuff old code was:
       
	for(astWalker = rocketList.begin(); astWalker != rocketList.end(); astWalker++)
		
					// now update each animation for each rocket in the list!

				{	
					astWalker->Animate(elapsedSeconds); 
					astWalker->draw(); 
				}

		// now we traverse our rockets link list

	if(rocketList.size() > 0)	// dont bother unless we have something to play with!

	{
		// ok we declare an iterator to be something to "walk" through the list 

		// starting at the beginning, finishing at the last node (rocket) on the list

		
		for(rokWalker = rocketList.begin(); rokWalker != rocketList.end(); rokWalker++)
		
					// now update each animation for each rocket in the list!

				{	
					rokWalker->Animate(); 
					if (rokWalker->death())		// has this rocket hit its distance?

						rocketList.erase(rokWalker++);	// if so, kill it.

				}
	}	// that was easy

  
which as you can see was fine. The new trick is to implement the sphere collision. Thats where im struggling to tie the functions together. Cheers ~~~~~~~~~~~~~~~~~~~~~~~~~ http://on.to/oni [edited by - fatherjohn666 on December 1, 2002 7:22:38 AM]

Share this post


Link to post
Share on other sites
Advertisement
Well, I think I see the problem here...

quote:
Original post by fatherjohn666

  // now we traverse our rockets link list, this one DRAWS the rockets

if(rocketList.size() > 0) // dont bother unless we have something to play with!

{
for(rokWalker = rocketList.begin(); rokWalker != rocketList.end(); rokWalker++)
// now update each animation for each rocket in the list!

{
rokWalker->Animate();

// now we traverse our asteroid link list, this one TESTS FOR COLLISIONS

for(astWalker = asteroidList.begin(); astWalker != asteroidList.end(); astWalker++)

// now check if the collision spheres radius total is <=

// the length of the distance between the asteroid and the missle

{
float radi = (astWalker->size + rokWalker->size);
float dist = (astWalker->position - rokWalker->position).Length();

if ( dist < radi)
{ // if so, kill the asteroid AND the rocket, and continue

asteroidList.erase(astWalker);
rocketList.erase(rokWalker);

}

} // COOL!



When you call list::erase(pos) it returns an iterator to the next item in the list. This because the element of the list that pos used to point to is now gone (along with the linked list pointers that allow you to advance pos to the next item).

That means that when you have a collision and go back to the top of the for loop, astWalker++ accesses some random garbage where an asteroid used to be and uses that to work out where the next asteroid is. This is not a good thing . What you need to do instead is use the return value of erase(pos) as the next iterator when an asteroid/rocket is erased, and use ++pos otherwise. Something like this should do it:


  astWalker = asteroidList.begin();
while(astWalker != asteroidList.end())
{
if(/*snip collision testing code*/)
{
astWalker = erase(astWalker);
}
else
{
++astWalker;
}
}



You'll have to be pretty careful when you erase the rocket too. If you do it on the first collision, subsequent collsion checks will crash. It would probably be easiest to just count the number of asteroids a rocket has collided with and then erase the rocket if the count is greater than zero.


  for(rokWalker = rocketList.begin(); rokWalker != rocketList.end(); rokWalker++)
// now update each animation for each rocket in the list!

{
rokWalker->Animate();
if (rokWalker->death()) // has this rocket hit its distance?

rocketList.erase(rokWalker++); // if so, kill it.

}


Here you got lucky . Using the postincrement operator means that rokWalker gets incremented to point to the next rocket, but the old value is returned. When erase returns, you already have an iterator to the next item in the list. Unfortunately, it gets incremented again by the for loop, so one rocket is skipped after
each rocket that dies. At least it doesn't crash though .

PS: "using namespace std;" lets you refer to things defined in "namespace std" without having to fully qualify their name. Everything in the standard library is in the std namespace, so you need to use the name std::list<whatever> rather than list<whatever>, unless you have "using namespace std;" somewhere before the list<whatever> line. Google should have plenty of hits for "C++ namespace" if you want to find out more.

EDIT: Put the tags in the right place this time...

[edited by - Krunk on December 1, 2002 9:11:49 AM]

Share this post


Link to post
Share on other sites
Excellent,good explanation, makes sense, unfortunately I cant try it atm (at work on a non gl laptop) but i will try it later and let you know

thanks



~~~~~~~~~~~~~~~~~~~~~~~~~

http://on.to/oni

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!