   Need help with 2D collision detect. C++
  I've got a screen with two sprites on it and can move one of them around fine, but it currently goes under the other sprite if I move it into the same area.  I want to know how to write a collision detection function.  Everything is 2D and in DirectX 9.0 using VC++.  Here's what I've got so far:int CollisionsDetect(sprite1, sprite2) //the sprites are structs, obv.{if sprite1.pos.x == sprite2.pos.x//don't know what to put here  Do I return a 1 or something?  How would that make the sprite not move into the area of the other sprite?  I looked all over this website and on Google for simple 2D collision detection with DirectX but couldn't really find anythingThanks.   
  Is the position vector at the upper left corner of the sprite or in the middle of the sprite?   ;  Easiest way is to define the collision boundaries of your game-objects as some type of simple geometry, like circles, rectangles or triangles (or a collection thereof) and test for collision between them.Boxes are probably the simplest, test between them point-in-box for box and all of box b's points, and vice versa.  Then do line-segment intersection tests for a's horizontal lines and b's vertical lines and vice versa.This is real basic, however, and assumes you're sprites don't rotate or anything.  There's tons of collision detection tutorials, and if you're using DirectX/XNA, XNA has it's own collision math code.   ;  I assume I'm using top-left for position vector because my Draw function is written as:d3Sprite->Draw(d3Texture,&drawRect,NULL,&sprite1.pos,0xFFFFFFFF);The sprites are simple boxes.  I use the RECT struct:RECT drawRect;  drawRect.left=sprite1.frameNumber*64;drawRect.right=drawRect.left+64;drawRect.top=sprite1.topPixel;drawRect.bottom=drawRect.top+64;and the sprite struct itself is:struct spt{D3DXVECTOR3 pos;int frameNumber;int topPixel;};It seems like coding collision itself would not be too hard, an "if sprite1.pos==sprite2.pos", then they collide.  How do I set it so that if it returns a collision, the sprite will not move into that space even if the keyboard in that direction over the other sprite is hit?  Thank you.;Quote:Original post by sysop1911It seems like coding collision itself would not be too hard, an "if sprite1.pos==sprite2.pos", then they collide. No, it's not that easy. With the simple (pos1==pos2), they would collide only if they were at the very same position in the world. This would be fine for sprites 1 pixel large, which, I presume, is not your case.Imagine you have two square-shaped sprites, each of them 50 pixels large (width = height = 50).Let's say: sprite1.pos.x = 20;   sprite1.pos.y = 40;sprite2.pos.x = 20;   sprite2.pos.y = 60;Are they colliding? By your equation they aren't, because 40!=60. But in fact they are - they are overlapping by 30 pixels vertically.The correct collision (overlapping) check for square objects would be something like:D3DXVECTOR3 dif = s1.pos - s2.pos;if (abs(dif.x) < spritesSize && abs(dif.y) < spritesSize)    yes_they_are_colliding;else    no_collision;  http://www.gamedev.net/reference/list.asp?categoryid=45#199 <-- alot of gamedev.net articles on collision.Things you need to consider for collision is how sprites move. While it can be easy to tell if two objects are colliding in a box, it's a whole different monster if your sprites are something like 16x16 and you have 64 pixels of movement for frames, so time-based colliding becomes important.If you are using rectangles to contain the sprites, there's simple line-based collision tests that'll return the distance one could cover before a collision with another object.   ;  D3DXVECTOR3 dif = s1.pos - s2.pos;if (abs(dif.x) < spritesSize && abs(dif.y) < spritesSize)    yes_they_are_colliding;else    no_collision----------------------------------------------------------------Can you explain this in a bit more in detail?  I get the basic idea that I have to calculate the area of each sprite and if any pixels in both sprite areas are the same, that's a collision, but I don't see how the above does it.  What is "spritesSize" exactly?  Let's say my sprites are 40x40, so spriteSize is 1600?  Also, what do I send to the main program to tell the sprite not to move in that area if a collision is detected?;  There are 2 things at play here.  First is collision detection, second is collision response.Collision detection does nothing more than tell you when 2 sprites are colliding.Collision response is what you do as a programmer when you find out 2 sprites are colliding.It depends on how you are moving your sprites (velocity based?  ai?  keyboard?)  but basically you could do it a couple of ways.First, the detection.  Again there are many different methods/algorithms, but the easiest by far is bounding box collision detection.  You already have a rect struct for your sprites, so you have everything you need.You're going to want to test EACH of the 4 corners of sprite1 to see if they fall within the bounding box of sprite2.PSEUDO CODE (and I'll write it out in a long unoptimized way so you can understand what's going on a bit better).  Assuming that origin is top left corner of sprite:if (( sprite1.pos.x > sprite2.pos.x ) && ( sprite1.pos.x < (sprite2.pos.x + sprite2.width )) && ( sprite1.pos.y > sprite2.pos.y ) &&( sprite1.pos.y < sprite2.pos.y + sprite2.height )   ) collision = true;Now if you wrapped that up into a function called collision or something you could then work on the response.For instance, you could keep 2 values for the position of each sprite...  current.pos.x and previous.pos.x (as well for the y component)Then before moving the sprite you could store current into previous, update current, do collision detection, and if true, just move sprite back to previous position (since you have that stored now).OR you could do the collision check BEFORE moving simply by checking the current position + the amount to be moved against the other sprite, and if true, then don't do the move.This is VERY basic, and I don't recommend you doing it this way for a commercial game or anything, but the important thing at this point is to get things up and running and working the way you want in a way you understand.  Then you can worry about optimization later.[/source]   ;Quote:Original post by sysop1911Can you explain this in a bit more in detail?  I get the basic idea that I have to calculate the area of each sprite and if any pixels in both sprite areas are the same, that's a collision, but I don't see how the above does it.  What is "spritesSize" exactly?  Let's say my sprites are 40x40, so spriteSize is 1600?It's not about area, just about coordinates. You're checking whether the rectangles are close enough to eachother on the x and y coord at the same time.spriteSize would be just 40I recommend you to take a piece of paper (chequered paper prefered), draw few possible situations and see what the coordinates are doing.Quote:Original post by sysop1911Also, what do I send to the main program to tell the sprite not to move in that area if a collision is detected?As D-Nos already said, first is the detection, second is the response. I would consider response only when collision is working ;)Anyway, the very simplest thing to do would be the following (please note that this won't be suitable for all application, it's merely a very simple example, to show the very basic principle):1. Take the player's action (movement direction).2. Compute where the player's sprite would be in the next frame given the movements.3. Check whether there would be a collision.4. If yes, ignore the action and do nothing. If not, perform the movement.   ;Quote:PSEUDO CODE (and I'll write it out in a long unoptimized way so you can understand what's going on a bit better).  Assuming that origin is top left corner of sprite:if (( sprite1.pos.x > sprite2.pos.x ) && ( sprite1.pos.x < (sprite2.pos.x + sprite2.width )) && ( sprite1.pos.y > sprite2.pos.y ) &&( sprite1.pos.y < sprite2.pos.y + sprite2.height )   ) collision = true;If sprite1.pos.x is smaller than sprite2.pos.x than you would never get a collision by this code, while in fact the sprites of course can collide. You probably meant it this way, but just for sure - to make this working you would have to check every couple twice. Let's say the code is a body of a function CheckCollision(sprite1, sprite2) { .... }and you want to check collisions between a player sprite (spritePlayer) and a particular obstacle (spriteObstacle[5]), you would have to make two calls:if (CheckCollision(spritePlayer, spriteObstacle[5]) || CheckCollision(spriteObstacle[5], spritePlayer))[Edited by - Tom KQT on May 22, 2010 8:35:58 AM]