GPWiki.org
GPWiki.org
It is currently Tue Jun 18, 2013 10:31 pm

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sun Jan 30, 2011 7:13 pm 
Rookie

Joined: Sun Jan 30, 2011 6:21 pm
Posts: 3
Hi everyone. I've frequented this site a lot in the past (mostly when it evolved from Lucky's VB Gaming Site in 2004). Lately I've gotten back into toying with game programming and I've actually got something to work! I'm having issues with my collision detection though. Before you suggest a tutorial check out how my game is set up:
I'm writing a side-scrolling platformer type of game. My game uses sound as it's only form of output (each sound plays in relation to the player. Pitch is increased when a sound goes up on the y axis so you can hear when it's above you and it pans from left/right when it moves on the x-axis). Since there are no graphics being drawn too the screen I only have one "layer" of objects and no tiles. Basically every object is a rectangle; ground, platforms, players, enemies etc. I have them all in a giant list. DUring the game loop I call the think method on each entity. I also loop through the entities again (O(n^2 or something like that) to check to see if the entity which just "thought" is colliding with another one by using a function which checks to see if the rects' edges are overlapping. The reason I do it this way is so that every object can have its own "collide" method. I.e. the player entity's collide method would check to see what the player's colliding with. If it's an enemy it will hurt itself, if it's a wall it will set it's x velocity to 0 etc. Collision code for a simple enemy would call it's destroy method on any collision (so it explodes when it collides with something). The reason I want to have it set up this way is so that any object can collide with any other object in the game world regardless of where the player is or what she's doing. The only problem is that only one of the two collision methods for an object are being called i.e. the enemy is exploding but by the time the player checks what's collided with it the enemy has already died and been rendered inactive. (if I tell it to remain active the player will continuously be collidingg with it until the user presses an arrow key to move ).
I hope I'm being clear here. A lot of opensource games I've looked at have each object check to see if it's colliding on its update/think method. I'm tempted to do this but this wouldn't give me what I want which is independent collision methods for each object. I don't want one object to be exploding *and* decreasing the player's health; I want the player to decrease it's own health. I'm writing this game in Python with PySFML. I'll post a code sample if anyone would like to see one (won't do it here since I'd need to describe more and this post is already pretty long). I've already had some ideas of how to fix it but they weren't working either (i.e. having all collisions in a python set w/o duplicates but that wouldn't allow an enemy to hit a player multiple times in a row).
Thanks and if anything I'd like to know if I've posted this in the right board. I could see how it could go under "game design." Thanks and I look forward to helping with everyone. This forum looks really friendly (unlike a lot of RTFM game development forums).

James


Top
 Profile  
 
PostPosted: Sun Jan 30, 2011 9:17 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3746
Location: South Africa
Welcome to GPWiki, James! That sounds like a very interesting game idea! :)

Quote:
The only problem is that only one of the two collision methods for an object are being called i.e. the enemy is exploding but by the time the player checks what's collided with it the enemy has already died and been rendered inactive.


I'm not sure how're you doing the loop, but supposing you have something like this:
Code:
private void CheckCollision()
{
   for (int i = 0; i < gameObjects.Count; i++)
   {
      for (int j = i+1; j < gameObjects.Count; j++)
      {
         if (gameObjects[i].Status == ObjectStatus.Active && gameObjects[j].Status== ObjectStatus.Active)
            if (gameObjects[i].Rectangle.Intersects(gameObjects[j].Rectangle))
            {
               gameObjects[j].Collision(gameObjects[i]);
               gameObjects[i].Collision(gameObjects[j]);
            }
      }
   }
}


Basically, call both collide methods whenever there's a collision, then both entities can decide what to do based on the collision. So checking for collisions doesn't happen with the respective entity's think method, but during the main loop of the game.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Mon Jan 31, 2011 7:07 am 
Rookie

Joined: Sun Jan 30, 2011 6:21 pm
Posts: 3
Thanks IGTHORN. I was actually already checking my collisions outside each object's think method in the main game loop. The one thing I was missing was calling both collide methods (of objects i and j in your example). I figured that since all the objects would be looped through both methods would eventually be called. I forgot of ccourse I was blowing up one of the objects before the other object would have a chance to collide with it.
I do foresee a small glitch though. I'm using this collision code in a simple space iinvaders-style game I wrote to test my ideas about game objects, collisions etc. As of now all objects will be dynamic but in my sidescrolling game there will be platforms, ground and wall entities so forth. Like I said I'm using the same entity classes for platforms and other static objects as I am using for the player and enemies. since I'm looping through all entities (and since platforms don't usually move or explode) the collide method for whatever platform the player is currently walking on and the player will be called twice during the game loop (i.collide+j.collide, i.collide+j.collide) since we're checking each one of those at least twice. This shouldn't make mucch of a difference since the only thing I'd have the player do when it "collides" with a platform is stand on it but it'll result in more function calls. I could probably have the player rectangle hover 0.01 units above the flloor entity so there's not technically an intersection and have another method check for a floor 0.01 under the player. I'm still uncomfortable keeping code in the game which I know can potentially be inefficient. Then again if it works it works. Is having the player rect hover a good idea or should I think of another way of handling collisions?


Top
 Profile  
 
PostPosted: Mon Jan 31, 2011 3:09 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3746
Location: South Africa
It shouldn't happen twice because of the bounds of the for loops. It will only be called once per pair of game objects, because the second loop goes from i+1 to entityCount.

Try to avoid hacks like hovering the player over the ground :) Stuff like that tends to bite you later.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Wed Feb 02, 2011 9:00 pm 
Rookie

Joined: Sun Jan 30, 2011 6:21 pm
Posts: 3
Thanks. That method actually works perfectly! I was using a list comprehension in python (basically a for-each loop) and comparing the current object in the update/think loop to the one in my collision loop (to avoid objects colliding with themselves) but now I see how it would be more efficient to actually use two indicies. That way I can avoid looping through all the entities n times (where n is the number of entities). Very cool!

James


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group