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

Multiple Collissions?

Last post 6/29/2009 6:46 AM by Storm Kiernan. 7 replies.
  • 6/27/2009 7:19 PM

    Multiple Collissions?

    I'm going nuts trying to figure this out but what you see here is basically "rain drops" falling into "buckets". There are four instances of RainBucket and they are strung together horizontally and their Vector2 position is clamped to the Mouse.GetState()X & Y values, AND the bounds of the Viewport. I'm not positive how to go about checking for collission with each of these. I've tried looping through the rainDropList and seeing if they collide with any of the rainBuckList objects but I get out-of-bound exceptions, or only one bucket works. Here's the  updated code:
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using Microsoft.Xna.Framework; 
    using Microsoft.Xna.Framework.Audio; 
    using Microsoft.Xna.Framework.Content; 
    using Microsoft.Xna.Framework.GamerServices; 
    using Microsoft.Xna.Framework.Graphics; 
    using Microsoft.Xna.Framework.Input; 
    using Microsoft.Xna.Framework.Media; 
    using Microsoft.Xna.Framework.Net; 
    using Microsoft.Xna.Framework.Storage; 
     
    namespace RainCatcher2 
        public class Game1 : Microsoft.Xna.Framework.Game 
        { 
            GraphicsDeviceManager graphics; 
            SpriteBatch spriteBatch; 
            public Random random = new Random(); 
            public List<RainDrop> rainDropList = new List<RainDrop>(); 
            public List<RainBucket> rainBucketList = new List<RainBucket>(); 
            public Rectangle viewPortRect; 
            private float timer = 0f; 
            private float interval = 1000f; 
            private Texture2D blueTexture; 
            public Game1() 
            { 
                graphics = new GraphicsDeviceManager(this); 
                Content.RootDirectory = "Content"
            } 
            protected override void Initialize() 
            { 
                viewPortRect = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height); 
                RainBucket blue = new RainBucket(this); 
                blue.texture = Content.Load<Texture2D>("bluebox"); 
                rainBucketList.Add(blue); 
                RainBucket red = new RainBucket(this); 
                red.texture = Content.Load<Texture2D>("bluebox"); 
                rainBucketList.Add(red); 
                RainBucket green = new RainBucket(this); 
                green.texture = Content.Load<Texture2D>("bluebox"); 
                rainBucketList.Add(green); 
                RainBucket yellow = new RainBucket(this); 
                yellow.texture = Content.Load<Texture2D>("bluebox"); 
                rainBucketList.Add(yellow); 
                base.Initialize(); 
            } 
            protected override void LoadContent() 
            { 
                spriteBatch = new SpriteBatch(GraphicsDevice); 
                blueTexture = Content.Load<Texture2D>("bluedrop"); 
            } 
            protected override void UnloadContent() 
            { 
            } 
            protected override void Update(GameTime gameTime) 
            { 
                timer -= gameTime.ElapsedGameTime.Milliseconds; 
                if (timer <= 0) 
                { 
                    timer = interval; 
                    RainDrop drop = new RainDrop(this); 
                    switch (random.Next(3)) 
                    { 
                        case 0: drop.texture = blueTexture; break
                        case 1: drop.texture = blueTexture; break
                        case 2: drop.texture = blueTexture; break
                        case 3: drop.texture = blueTexture; break
     
                    } 
                    drop.position.X = random.Next(viewPortRect.Width - drop.texture.Width); 
                    rainDropList.Add(drop); 
                } 
                for (int i = 0; i < rainDropList.Count; i++) 
                    rainDropList[i].Update(gameTime); 
                for (int i = 0; i < rainBucketList.Count; i++) 
                    rainBucketList[i].Update(gameTime); 
                for (int i = 0; i < rainBucketList.Count; i++) 
                { 
                    for (int j = 0; j < rainDropList.Count; j++) 
                    { 
                        if (rainDropList[j].collissionRectangle.Intersects(rainBucketList[i].collissionRectangle)) 
                        { 
                            rainDropList.RemoveAt(j); 
                            j--; 
                        } 
                    } 
                } 
                base.Update(gameTime); 
            } 
            protected override void Draw(GameTime gameTime) 
            { 
                GraphicsDevice.Clear(Color.Black); 
                spriteBatch.Begin(); 
                foreach (RainDrop drop in rainDropList) 
                { 
                    spriteBatch.Draw(drop.texture, drop.position, Color.White); 
                } 
                foreach (RainBucket bucket in rainBucketList) 
                { 
                    spriteBatch.Draw(bucket.texture, bucket.position, Color.White); 
                } 
                spriteBatch.End(); 
                base.Draw(gameTime); 
            } 
        } 
        public class GameObject 
        { 
            public Texture2D texture; 
            public Vector2 position; 
            public Rectangle collissionRectangle; 
     
            protected Game1 game; 
     
            public GameObject(Game1 game) 
            { 
                this.game = game; 
            } 
     
            public virtual void Update(GameTime gameTime) 
            { 
                collissionRectangle = new Rectangle( 
                (int)position.X, 
                (int)position.Y, 
                texture.Width, 
                texture.Height 
                ); 
            } 
        } 
        public class RainDrop : GameObject 
        { 
            public float velocity = 0.1f; 
            public string color; 
            public RainDrop(Game1 game) : base(game) 
            { 
            } 
            public override void Update(GameTime gameTime) 
            { 
                position.Y += velocity * gameTime.ElapsedRealTime.Milliseconds; 
                base.Update(gameTime); 
            } 
        } 
        public class RainBucket : GameObject 
        { 
            public string color; 
            public RainBucket(Game1 game) : base(game) 
            {  
            } 
            public override void Update(GameTime gameTime) 
            { 
                for (int i = 0; i < game.rainBucketList.Count; i++) 
                { 
                    game.rainBucketList[i].position.X = game.rainBucketList[i].position.X + game.rainBucketList[i].texture.Width; 
                } 
                //Clamps the buckets to the viewport boundaries 
                position = new Vector2( 
                    (int)MathHelper.Clamp(Mouse.GetState().X, 0, game.GraphicsDevice.Viewport.Width - texture.Width * game.rainBucketList.Count), 
                    (int)MathHelper.Clamp(Mouse.GetState().Y, 0, game.GraphicsDevice.Viewport.Height - texture.Height) 
                    ); 
                base.Update(gameTime); 
            } 
        } 

  • 6/27/2009 10:26 PM In reply to

    Re: Multiple Collissions?

    Where does the exception occur?

    Though, just from glancing at it, I think the problem might be in your RainDrop Update.  You have a for loop, and you are removing elements in a list within the loop.  In some cases I believe this can cause problems.  If an element is removed, the next element will take the place of the one that was just removed, and the one in that spot will be skipped over in the next iteration of the for loop.  Usually when I work with lists I use foreeach the majority of the time.
  • 6/27/2009 10:51 PM In reply to

    Re: Multiple Collissions?

    You shouldn't be walking over the raindrop list in RainDrop.Update and removing raindrops. You should do that in Game.Update.

    Also, when you remove a raindrop, you need to subtract 1 from i to avoid skipping items.
    Kevin Gadd, Squared Interactive
    Development Blog | Twitter
    Help playtest my game, Inferus!
  • 6/28/2009 10:52 AM In reply to

    Re: Multiple Collissions?

    You have several errors that could be causing null pointer exceptions.  Go through your code and everywher in a for loop you see *.Count change it to *.Count -1.  You use the count then plug it into a 0 based array, so if you have 8 items in an array count will return 8, but your array goes from 0 to 7.  Thus when you try to access number 8 you get and exception.
  • 6/28/2009 11:08 AM In reply to

    Re: Multiple Collissions?

    RedJester:
    You have several errors that could be causing null pointer exceptions.  Go through your code and everywher in a for loop you see *.Count change it to *.Count -1.  You use the count then plug it into a 0 based array, so if you have 8 items in an array count will return 8, but your array goes from 0 to 7.  Thus when you try to access number 8 you get and exception.


    I don't see any errors for loops. i<Count working just right...

    [Edit]
    When you removing drops, you should decrease i value.

    for (int i=0; i<dropList.Count; i++)
    {
        if (a > b)
        {
            dropList.RemoveAt(i);
            i--;
        }
    }
    FontBuilder TrueType Font Editor
  • 6/28/2009 11:42 AM In reply to

    Re: Multiple Collissions?

    For multiple collisions you have to check every raindrop against every bucket. The easiest way of doing that is by using double nested foreach loops as such

    foreach( RainBucket bucket in rainBucketList ) 
      foreach( RainDrop drop in rainDropList ) 
      { 
        if ( /* drop intersects bucket */ ) 
        { 
          // Do whatever is supposed to happen when a drop hits a bucket 
        } 
      } 



    Also, you absolutely shouldn't do this

    switch (random.Next(3)) 
      case 0: drop.texture = Content.Load<Texture2D>("bluedrop"); break;  
      case 1: drop.texture = Content.Load<Texture2D>("bluedrop"); break;  
      case 2: drop.texture = Content.Load<Texture2D>("bluedrop"); break;  
      case 3: drop.texture = Content.Load<Texture2D>("bluedrop"); break;  
    }  



    Loading a new Texture2D for each drop is a huge waste wich you can easily avoid by reusing the same Texture2D whenever you make a new drop:

    private Texture2D bluedrop; 
     
    // Load the texture in LoadContent 
    protected override void LoadContent() 
      spriteBatch = new SpriteBatch(GraphicsDevice); 
      bluedrop = Content.Load<Texture2D>("bluedrop"); 


    Then whenever you're making a new drop just reuse that texture with drop.texture = bluedrop;
  • 6/29/2009 2:22 AM In reply to

    Re: Multiple Collissions?

    I updated the code in my original post to what I have currently. There are no crashes, but the collission only works on the first circle and not the other three. Any ideas?
  • 6/29/2009 6:46 AM In reply to

    Re: Multiple Collissions?

    Hey guys. Thanks for all of the help. I got it to work!
Page 1 of 1 (8 items) Previous Next