bool world::collideRect(const vector2f& point, int w, int h) const
{
const int x = (int)point.x;
const int y = (int)point.y;
if (!insideWorld(point))
return true;
int xMax = x + w;
int yMax = y + h;
for (int i = x; i < xMax; i++)
{
if (i < 0 || i >= w)
continue;
for (int j = y; j < yMax; j++)
{
if (j < 0 || j >= h)
continue;
int index = m_pitch / 2 * j + i;
if (m_pixelState[index])
return true;
}
}
return false;
}
My problem occurs when I have to test collisions between shots and the map. I've currently implemented shots by giving them a start velocity and a position that has the velocity added to it at every iteration. I use a sprite for each type of shot, so if I have an angle of 0 it uses the sprite image between 0-18 degrees, if it has an angle of 30 it uses the sprite between 18-36. I've been trying to figure out how to effectively check collisions between the shots and the map. I was thinking of maybe hardcoding some points (for instance at the tip of the shot) for angle 0, and then interpolating them according to the angle. I've included a screenshot of the game below to give you a better idea of what I've horribly tried to explain :)
http://img222.imageshack.us/my.php?image=screenshotfj7.png
(Couldn't figure out how to hotlink it here. :o)
My question is, does anyone have ideas on how I might check if a shot collides with the pixels? My only viable idea so far is creating the points, but I'm sure there are better and more experienced minds out there than mine with better ideas :)
Thanks in advance,
Michael.
P.S.: Chances are I've forgotten to write something vital for understanding my problem, so please let me know if you're in doubt of anything.
2d collisions between shots and map
Hey everybody. I'm currently making a hobby project where you're a bunch of penguins that for some reason want to kill each other. I use the SDL framework and C++ under Linux with Anjuta as IDE. I used to use the SDL_collision library to do my collision, but I found it to not be the best solution since it requires a rendered frame. Once I implement network this will be a problem. Instead what I wanna do is do some collision detection using a bitvector of the entire map, that indicates whether each pixel is solid. I already do this for player movement and it works perfectly. Below is the function for checking if a rectangle is collided with the level.
Do you need the shot collisions to be pixel perfect? I remember from Worms Armageddon that such an approach sometimes led to missiles exploding on a few left-over pixels from a napalm attack - pretty annoying sometimes. Hmm, now that I think of it, you could implement a system that checks for small objects and removes them if they're too small... :)
Well, anyway, you could use a bitmask for the shots, and compare each of it's 'pixels' to the world pixel that it overlaps. If there's any place where both pixels are solid, then you've got a collision. So essentially, not only your map gets a collision bit-map, but your shot images get one as well.
Note that there's no need for the collision hull to be exactly the same as the visual hull: many games use a simplified collision hull, not only because it's better for performance sake, but also because players just don't need to collide with every bit of rubble that's lying around. Just something to consider. :)
Just a note: using a 1D container for a 2D map easily leads to confusion. Off-by-1-row-or-collumn errors and such. If I were you, I'd write a GetPixel(x, y) and SetPixel(x, y) function, that wrap up the 2D coordinate to 1D index conversion. It'll prevent confusion later on. Or, better, use a 2D container, such as boost::multi_array.
Well, anyway, you could use a bitmask for the shots, and compare each of it's 'pixels' to the world pixel that it overlaps. If there's any place where both pixels are solid, then you've got a collision. So essentially, not only your map gets a collision bit-map, but your shot images get one as well.
Note that there's no need for the collision hull to be exactly the same as the visual hull: many games use a simplified collision hull, not only because it's better for performance sake, but also because players just don't need to collide with every bit of rubble that's lying around. Just something to consider. :)
Just a note: using a 1D container for a 2D map easily leads to confusion. Off-by-1-row-or-collumn errors and such. If I were you, I'd write a GetPixel(x, y) and SetPixel(x, y) function, that wrap up the 2D coordinate to 1D index conversion. It'll prevent confusion later on. Or, better, use a 2D container, such as boost::multi_array.
Thanks for responding :)
I thought about creating a bitmask but the problem is that if my users then change images manually, they'll change the collisions as well. That's not something I'd like to happen. I was thinking of creating small circles that immitate the area of the shot and check for collision with those. Don't know if this is a very viable idea though, but I'm just getting desperate since the collision part of the game is kind of keeping me from implementing the stuff I find funny :)
I thought about creating a bitmask but the problem is that if my users then change images manually, they'll change the collisions as well. That's not something I'd like to happen. I was thinking of creating small circles that immitate the area of the shot and check for collision with those. Don't know if this is a very viable idea though, but I'm just getting desperate since the collision part of the game is kind of keeping me from implementing the stuff I find funny :)
Don't do collision handling on the client side - eventually, things will go out of sync, whether users change their images or not. Let the server do the hard work, informing the clients of the actual situation, while clients tell it what actions they want to perform.
For example, what if player A and B both are close to a weapon crate? Both move at the same time, and both think they picked up the crate. Due to network delay and such, they weren't informed of the other when they picked up the crate, so both players have the new weapon, while thinking the other has not. The server thinks player A got the weapon, since it processed it's movement first... uhh, who is allowed to fire what weapon now?
Get the idea? Let the server handle the serious business, maybe even check whether player movements are within normal bounds (a player moving at 200 mph smells like cheating, right?). Let the server tell the clients what actually happened. :)
For example, what if player A and B both are close to a weapon crate? Both move at the same time, and both think they picked up the crate. Due to network delay and such, they weren't informed of the other when they picked up the crate, so both players have the new weapon, while thinking the other has not. The server thinks player A got the weapon, since it processed it's movement first... uhh, who is allowed to fire what weapon now?
Get the idea? Let the server handle the serious business, maybe even check whether player movements are within normal bounds (a player moving at 200 mph smells like cheating, right?). Let the server tell the clients what actually happened. :)
Ah yes. I completely forgot that you never should trust a client. I don't have much experience with coding network games, which is why I wanna get this collision business out of the way quickly so I can get my hands dirty with some net code :)
I'll try and do what you suggested and see how it works out. Thanks :)
I'll try and do what you suggested and see how it works out. Thanks :)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement