SDL Detection Collision Problem

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.
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.
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.
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.
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.
closed account (N36fSL3A)
BUMP
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.
are you using the SDL_collide.h/cpp from the sdl site?
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
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.
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 by Fredbill30
You are changing the velocity, not the position. Velocity can take x time to affect position. Just change position directly.
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 by Fredbill30
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.
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.
i like that!
Topic archived. No new replies allowed.