XNA Creators Club Online
Page 1 of 1 (9 items)
Sort Posts: Previous Next

2D Collision between 2 sprites

Last post 06-07-2008 11:35 AM by Sparkworker. 8 replies.
  • 05-12-2008 11:36 PM

    2D Collision between 2 sprites

    hi, I was wondering if anybody can help me. I have two sprites, one of a fighter, the other a bookcase. The bookcase is stationary and what I want to do is to have the fighter collide with the bookcase on the four sides. I've looked through samples and tutorials and can't quite find what I need. What I'm trying to do is have a method in the update that I can pass in the name of a rectangle for what ever sprite(of any size and position) and have it collide properly.

    thanks 

  • 05-13-2008 12:14 AM In reply to

    Re: 2D Collision between 2 sprites

    What do you mean by "collide properly?" What do the Collision Series tutorials not do that you need them to do?

     

  • 05-13-2008 12:25 PM In reply to

    Re: 2D Collision between 2 sprites

    http://forums.xna.com/thread/61307.aspx

     

    I wrote a pretty good brute force collision algorithm in that thread. It's the second post. You'll have to change the variables and some of the logic around so that it will fit in your game (I wrote it was a general algorithm to get the idea across).

  • 05-23-2008 3:22 AM In reply to

    Re: 2D Collision between 2 sprites

    JohnWestMinor:

    http://forums.xna.com/thread/61307.aspx

     

    I wrote a pretty good brute force collision algorithm in that thread. It's the second post. You'll have to change the variables and some of the logic around so that it will fit in your game (I wrote it was a general algorithm to get the idea across).

    I have taken the liberty of copying/pasting said code, and properly formatting it here, so it's a lot easier to read =]

    for(i=0;i<collisionobjectscount;i++)  
    {  
           xcollision=false;  
           ycollision=false;  
    // I have four sets to check for positive and negative speed values.  
    //this checks if the object is past something before the speed is added and if it's past something after. If it isn't past it before, but is after the speed is added, there's an X axis collision. For there to be a real collision there needs to be an X and Y axis collision.  
            if(Xposition>=collisionobject[ i ].X+collisionobject[ i ].spaceoffset && Xposition+Xspeed<=collisionobject[ i ].X-collisionobject[ i ].spaceoffset)  
            {  
                xcollision=true;  
            }  
    //this checks if the object is past something before the speed is added and if it's past something after. If it isn't past it before, but is after the speed is added, there's an X axis collision. For there to be a real collision there needs to be an X and Y axis collision.  
            if(Xposition<=collisionobject[ i ].X-collisionobject[ i ].spaceoffset && Xposition+Xspeed>=collisionobject[ i ].X+collisionobject[ i ].spaceoffset)  
            {  
                xcollision=true;  
            }  
    //this checks if the object is past something before the speed is added and if it's past something after. If it isn't past it before, but is after the speed is added, there's a Y axis collision. For there to be a real collision there needs to be an X and Y axis collision.  
            if(Yposition>=collisionobject[ i ].Y+collisionobject[ i ].spaceoffset && Yposition+Yspeed<=collisionobject[ i ].Y-collisionobject[ i ].spaceoffset)  
            {  
                ycollision=true;  
            }  
    //this checks if the object is past something before the speed is added and if it's past something after. If it isn't past it before, but is after the speed is added, there's a Y axis collision. For there to be a real collision there needs to be an X and Y axis collision.  
            if(Yposition<=collisionobject[ i ].Y-collisionobject[ i ].spaceoffset && Yposition+Yspeed>=collisionobject[ i ].Y+collisionobject[ i ].spaceoffset)  
            {  
                ycollision=true;  
            }  
            if(ycollision==true && xcollision==true)  
            {  
            //these adjust the speed to hit the object rather than to go through it.  
                if(xspeed>0)  
                {  
                    Xspeed=Xspeed-((Xposition+Xspeed)-(collisionobject[ i ].X-collisionobject[ i ].spaceoffset));  
                }  
                if(xspeed<0)  
                {  
                    Xspeed=Xspeed+((collisionobject[ i ].X+collisionobject[ i ].spaceoffset)-(Xposition-Xspeed));  
                }  
                if(Yspeed>0)  
                {  
                    Yspeed=Yspeed-((Yposition+Yspeed)-(collisionobject[ i ].Y-collisionobject[ i ].spaceoffset));  
                }  
                if(Yspeed<0)  
                {  
                    Xspeed=Xspeed+((collisionobject[ i ].Y+collisionobject[ i ].spaceoffset)-(Yposition-Yspeed));  
                }  
            }  
    }  
    Xposition+=Xspeed;  
    Yposition+=Yspeed; 
  • 05-27-2008 12:41 PM In reply to

    Re: 2D Collision between 2 sprites

    You should have a look at the Bounding Box class and google it and see if you come up with anything ;).
    Independent Game Developer - Blog
  • 05-27-2008 6:20 PM In reply to

    Re: 2D Collision between 2 sprites

    For actual collision based on mass and velocity you can try this, it is in 2D but should be easy enough to convert. However if you're going to be using physics I'd recommend a 2D physics engine like Farseer.

     

    public void ProcessEntityCollision(GameTime gameTime, ref DynamicEntity FirstEntity, ref DynamicEntity SecondEntity)  
            {  
                Vector3 FirstToSecondVect = MathUtils.VectorFirstToSecond(FirstEntity.position, SecondEntity.position);  
                FirstToSecondVect.Normalize();  
     
                float a1 = Vector3.Dot(FirstEntity.VelocityVector, FirstToSecondVect);  
                float a2 = Vector3.Dot(SecondEntity.VelocityVector, FirstToSecondVect);  
     
                float MassTotal = FirstEntity.Mass + SecondEntity.Mass;  
     
                float optimizedP = (2.0f * (a1 - a2)) / MassTotal;  
     
                Vector3 FirstDirection = FirstEntity.VelocityVector - optimizedP * SecondEntity.Mass * FirstToSecondVect;  
                Vector3 SecondDirection = SecondEntity.VelocityVector + optimizedP * FirstEntity.Mass * FirstToSecondVect;  
     
                FirstEntity.VelocityVector = FirstDirection * FirstEntity.Elasticity;  
                SecondEntity.VelocityVector = SecondDirection * SecondEntity.Elasticity;  
     
                maintainMinimumDistance(ref FirstEntity, ref SecondEntity);  
            }  
     
            public void maintainMinimumDistance(ref DynamicEntity FirstEntity, ref DynamicEntity SecondEntity)  
            {  
                float distanceToEntity = MathUtils.VectorFirstToSecond(FirstEntity.position, SecondEntity.position).Length();  
     
                float radiiSum = FirstEntity.BoundingSphere.Radius + SecondEntity.BoundingSphere.Radius;  
     
                float MassTotal = FirstEntity.Mass + SecondEntity.Mass;  
     
                if (distanceToEntity < radiiSum)  
                {  
                    Vector3 newPos = MathUtils.VectorFirstToSecond(FirstEntity.position, SecondEntity.position) * (distanceToEntity - radiiSum) * (SecondEntity.Mass / MassTotal);  
                    FirstEntity.SetPosition(FirstEntity.position + newPos);  
                    SecondEntity.SetPosition(SecondEntity.position - newPos);  
                }  
            } 
    XNA QuickStart Engine | My site
    "I'll be whatever I want to do!", Philip J. Fry
  • 06-04-2008 3:31 AM In reply to

    Re: 2D Collision between 2 sprites

     

    What I'm looking for isn't that complex. What I'm trying to accopmlish is to have a character sprite move around (x, y) and for now only have other stationary sprites (such as bookcase, chairs, tables). I am using rectangle collision (or trying to) to obstruct movement when in contact with other sprites. Here's the code I'm trying to use, it works with on one side it bounces the character back one pixel but makes the character jump around on the other sides. I  must note that I am using the GameObject class from the beginners videos for the stationary sprites.

     

    private void Collision(GameObject)  
            {  
     
                if (characterRect.Bottom > GameObject.rect.Top && characterRect.Top < GameObject.rect.Bottom)  
                {  
                    if (characterRect.X < GameObject.position.X)  
                    {  
                        if (characterRect.Intersects(GameObject.rect))  
                        {  
                            Position.X = (GameObject.rect.Left - 1);  
                        }  
                    }  
     
                    if (characterRect.X > GameObject.position.X)  
                        {  
                            if (characterRect.Intersects(GameObject.rect))  
                            {  
                                Position.X = (GameObject.rect.Right + 1);  
                            }  
                        }  
     
                    }  
                  
                if (characterRect.Right > GameObject.rect.Left && characterRect.Left < GameObject.rect.Right)  
                {  
                    if (characterRect.Y > GameObject.position.Y)  
                    {  
                        if (characterRect.Intersects(GameObject.rect))  
                        {  
                            Position.Y = (GameObject.rect.Bottom + 1);  
                        }  
                    }  
                    if (characterRect.Y  < GameObject.position.Y)  
                    {  
                        if (characterRect.Intersects(GameObject.rect))  
                        {  
                            Position.Y = (GameObject.rect.Top - 1);  
                        }  
                    }  
                }  
            } 

     the outer if statements are to check if the character sprite is within the top and bottom( for side collision) and within the left and right (for top and bottom collision), I can't think of another way to accomplish this.

  • 06-04-2008 6:42 AM In reply to

    Re: 2D Collision between 2 sprites

    I'm not too sure about your logic there.

    This makes more sense to me:

                    // Assuming characterRect encompasses the character...  
                    // ...  
                    if (characterRect.Right > GameObject.rect.Left)     
                    {     
                        if (characterRect.Intersects(GameObject.rect))     
                        {     
                            Position.X = (GameObject.rect.Left - characterRect.Width - 1);     
                        }     
                    }     
        
                    if (characterRect.Left < GameObject.rect.Right)     
                        {     
                            if (characterRect.Intersects(GameObject.rect))     
                            {     
                                Position.X = (GameObject.rect.Right + 1);     
                            }     
                        }     
        
                    }   
                    // ... 

    You'd do something similar with the Y direction.

    --
    Ruina et Stragos
    XNA SA
    --
  • 06-07-2008 11:35 AM In reply to

    Re: 2D Collision between 2 sprites

    Honestly, I'd use mesh collision whenever possible. It allows the best possible resoloution, and you don't need five billion if/then statements.

    All you need is something to store the points of many triangles - objects make that easy.

     

    Then when you want to check for collisions, just raycast between two lines.

     

    Here's a bit of my raycast code - checks to see if two lines cross each other. This should help you alot - and I'd change the x1, y1 to vector2s... I wrote this a while ago, so yeah.... I haven't fixed that to a more standard use yet. Hope this helps... It's probly overkill maybe, but it'