SDL Detection Collision Problem

Mar 27, 2013 at 5:54pm
closed account (N36fSL3A)

This is my project file:
http://www.filedropper.com/kyden

SDL collision is the problem this time. When this is downloaded, look at collision.cpp, player.cpp, and kyden.cpp.

I'm trying to make my player stop when he/she collides with the crate. If you play Kyden.exe, you can clearly see the box can only collide with Y coordinates(Or is it X?). Also, its all buggy when I collide with the top of the screen, the box is unable to leave from its grip.

There is no errors whatsoever, its just buggy. Thanks in advance for the help I recieve.
Mar 27, 2013 at 6:27pm
Might have better luck putting this on pastebin. I'm sure not opening a random zip file.

As for some of the errors you're describing, what I've done is if collision gets "stuck" (ie the object enters another object so collision detection stops it from moving altogether) is to basically just move the object back a tiny amount after collision. It's not noticeable to the eye, and it keeps it from getting stuck.

But there's probably better ways. My experience with graphics and games is pretty limited.
Mar 27, 2013 at 7:05pm
closed account (N36fSL3A)
But there are many source files :(. Also, why would I post something like a virus(since that's what you're getting at.) In a zip file on forums? Wouldn't I get banned?

Yea, I attempted trying to move the sprite back but no matter what I tried, it failed.
Mar 27, 2013 at 7:59pm
What I do is, every time an object tries to move, I have it check for collisions with other nearby objects and walls and such (collision detection is done by the objects themselves and only when they try to move move). I detect collisions by simply reducing the size of each object's bounding box by 10% (to allow some overlap) and then checking if the moving object would overlap the other object if it were allowed to move. Then all I do is figure out how much it would overlap by, and take that much off of its motion vector so that it can't overlap (except by the 10% allowance). Since all the detection is done by a single thread (the main thread), there's no way two objects can move simultaneously, which would circumvent the detection. Of course, it's done so fast by the computer that the player can't tell that it's not simultaneous.

I'd like to do pixel-by-pixel detection rather than just using boxes but I think that would be too slow and complicated to do for every object.
Mar 27, 2013 at 9:53pm
closed account (N36fSL3A)
Rectangular collision fits my purposes for now, I'm planning on changing that.

I check for a collision every CPU cycle, as collision detection is in the player's update function. The problem is that the rectangular box won't move back once it collides. Also, the left & right side of the rectangle won't collide with the player's bounding box for some reason.
Mar 27, 2013 at 10:37pm
closed account (N36fSL3A)
BUMP
Mar 27, 2013 at 11:37pm
Fredbill30 wrote:
The problem is that the rectangular box won't move back once it collides

That's why you check before you allow objects to move. Then you only let them move so far as to not collide with anything.
Mar 28, 2013 at 1:59am
are you using the SDL_collide.h/cpp from the sdl site?
Mar 28, 2013 at 2:09am
just a thought, keep a previous position variable in update or your class so that when player collides with crate, you just revert the players position to the previous.

That way when it renders again, the player is in the same position as last time.


Seems efficient, it is simply copying at most one rectangle, and at least one y-coord
Mar 28, 2013 at 7:33am
I'd like to do pixel-by-pixel detection rather than just using boxes but I think that would be too slow and complicated to do for every object.

Usually per-pixel detection is done after the bounding boxes overlap, so that it is skipped altogether if the objects are not touching.
Mar 28, 2013 at 11:09am
closed account (N36fSL3A)
chrisname wrote:
That's why you check before you allow objects to move. Then you only let them move so far as to not collide with anything.


I know. If you look at the code, I attempt to move back 1 pixel. Before I posted, I attempted moving back 5 pixels, but it still didn't work.

Something like:
1
2
3
4
if(BoxTouchesCrateXorScreen || (CollBox + SpriteWidth > ScreenWidth || Collision = true)
{
     Xvel -= 1;
}


^
| Pseudo Code
Last edited on Mar 28, 2013 at 11:15am by Fredbill30
Mar 28, 2013 at 12:36pm
You are changing the velocity, not the position. Velocity can take x time to affect position. Just change position directly.
Mar 29, 2013 at 9:28pm
closed account (N36fSL3A)
I changed it to directly affect postition. Now look
1
2
3
4
5
6
7
8
9
		if(Collision || (CollBox.x < 0) || ( CollBox.x + 32 > 600))
		{
			X = X - 1;
		}

		if(Collision || (CollBox.y < 0 ) || ( CollBox.y + 32 > 800))
		{
			Y = Y - 1;
		}

This time when I collide with the crate I move through the crate slowly.
Last edited on Mar 29, 2013 at 9:30pm by Fredbill30
Mar 29, 2013 at 11:58pm
well, -1 may not be enough. if your position is changing at a rate of, say, 6px per frame then 1 is not enough. That is why I suggested simply having a 'previous' variable so before you update, you copy the position to previous, that way on collision, just revert position to previous. That way when it renders, the character is in the same position.
Mar 30, 2013 at 12:30am
I would calculate the amount of overlap and just subtract that amount from the position:
1
2
3
4
5
6
7
8
9
10
11
// Update position.
object_a.position.x += velocity.x * time;
object_a.position.y += velocity.y * time;

// Check for and correct any collisions.
for (object_b : nearby_objects) {
    if ((object_a.position.x < object_b.position.x) && (object_a.position.x + object_a.size.x > object_b.position.x)
        object_a.position.x -= object_a.position.x + object_a.size.x - object_b.position.x;
    if ((object_a.position.y < object_b.position.y) && (object_a.position.y + object_a.size.y > object_b.position.y)
        object_a.position.y -= object_a.position.y + object_a.size.y - object_b.position.y;
}

Of course this code assumes that object_a is moving from left-to-right or top-to-bottom; you would have to account for the opposite directions too.
Mar 30, 2013 at 1:00am
i like that!
Topic archived. No new replies allowed.