0
\$\begingroup\$

Got a problem, with collision detection, I need to detect collision between bullets and meteors using nested loop for this, but it isn't working.

                            } 
                }
                    check();
                    LoadMeteors();      
        base.Update(gameTime);
    }





    public void LoadMeteors()
    {

        int randY = random.Next(100, 400);
        if (spawn >= 0.5)
        {
            spawn = 0;

                meteors.Add(new Meteor(Content.Load<Texture2D>("Backgrounds/meteori"), new Vector2(800, randY), new Rectangle(0,0,50,50)));
        }
    }

    public void SpawnBullet()
    {

        bullets.Add(new Bullet(Content.Load<Texture2D>("Backgrounds/pula"), new Vector2(rocket.rectangle.X + 20, rocket.rectangle.Y + 20), new Rectangle(0, 0, 10, 5)));
        soundEffect.Play();

    }
    public void check()
    {

        for (k = 0; k < bullets.Count; k++)
        {
            for (i = 0; i < meteors.Count; i++)
            {
                if (bullets[k].rectangle.Intersects(meteors[i].rectangle))
                {
                    meteors[i].isVisible = false;
                }
            }
        }
    }

that is my meteor class:

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;

namespace Rocket
{
   class Meteor
 {
    public Texture2D texture;
    public Rectangle rectangle;
    public Vector2 position;
    public Vector2 velocity;

    public bool isVisible = true;

    Random random = new Random();
    int randX, randY;

    public Meteor(Texture2D newTexture, Vector2 newPosition, Rectangle newRectangle)
    {

        texture = newTexture;
        position = newPosition;
        rectangle = newRectangle;
        randY = random.Next(-4, 4);
        randX = random.Next(-4,-1);

        velocity = new Vector2(7, 0);
    }


   public void Update(GraphicsDevice graphics)
    {

        position -= velocity;
        if (position.X < 0 - texture.Width)
            isVisible = false;
    }
   public void Draw(SpriteBatch spriteBatch)
   {

       spriteBatch.Draw(texture, position, rectangle, Color.White);


   }


}
}

and that is my bullet class:

    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.Input;
  using Microsoft.Xna.Framework.Media;

 namespace Rocket
{
class Bullet
{
    public Texture2D texture;
    public Rectangle rectangle;
    public Vector2 position;
    public Vector2 velocity;

    public bool isVisible = true;

    public Bullet(Texture2D newTexture, Vector2 newPosition, Rectangle newRectangle)
    {

        texture = newTexture;
        position = newPosition;
        rectangle = newRectangle;

        velocity = new Vector2(10, 0);
    }


    public void Update(GraphicsDevice graphics)
    {
       position += velocity;
               if (position.X < 0 - texture.Width)
            isVisible = false;
    }
   public void Draw(SpriteBatch spriteBatch)
   {
       spriteBatch.Draw(texture, position, rectangle, Color.Aqua);

   }
    }

so, I call function Check(): in update method, than in that function i check for collision, but it isn't detecting collision, also meteor and bullet classes, both have rectangle, I don't get any errors and it seems to be right, thanks for any help!

\$\endgroup\$
2
  • \$\begingroup\$ No offence, but honest advise. Read a couple of C# books/tutorials. If looked at your question(s) and your responses to the answers people provided- but XNA is not the issue, I advise you to get a bit more basic knowledge of the programming language C# and basic programming principles/patterns. It helps you understand what to do if people provide basic directions as "you should update the x position" \$\endgroup\$
    – Felsir
    Jan 18, 2016 at 23:03
  • \$\begingroup\$ yes you are right! :d \$\endgroup\$
    – Nick
    Jan 19, 2016 at 4:49

4 Answers 4

1
\$\begingroup\$

From your code:

for (k = 0; k < bullets.Count; k++)
{
    for (k = 0; k < meteors.Count; k++)
    {
        if (rocket.rectangle.Intersects(meteors[k].rectangle))
        {
            meteors[k].isVisible = false;
        }
    }
}

You use the same iterator in both for loops. It also looks as though you are reusing that (global) iterator from somewhere else in the code; Unless you have a very good reason for doing so, you should likely be using local iterators that are initialized in the for loop.

Ex. for(int i = 0; i < 1000; i++)

A fix for this might be:

for (int iB = 0; iB < bullets.Count; iB++)
{
    for (int iM = 0; iM < meteors.Count; iM++)
    {
        if (rocket.rectangle.Intersects(meteors[iM].rectangle))
        {
            meteors[iM].isVisible = false;
        }
    }
}

But I don't know how you are specifying the location or bounding box of the actual bullets. At the moment it looks like the rocket.rectangle might be at a fixed location because you never update it's position in these loops.

\$\endgroup\$
5
  • \$\begingroup\$ no i can't do this because, i spawn unknown number of bullets and meteors, so this loop checks collision between every bullet and every meteor. \$\endgroup\$
    – Nick
    Jan 18, 2016 at 15:55
  • 1
    \$\begingroup\$ @Nick, JonBee isn't referring to the count part but the fact you use 'k' in both for loops. In general the iterator in a for loop is scoped only to that loop. Hence the for(int i=0 part. In your code the K in the inner meteor loop causes the K in the outer bullet loop to skip a lot of bullets (in fact, all bullets if the meteors outnumber the bullets). So in itself the code of the loops is wrong and should be corrected as JonBee suggests. \$\endgroup\$
    – Felsir
    Jan 18, 2016 at 17:52
  • \$\begingroup\$ Like @Felsir said, the way your current loop is setup, it will likely skip most if not all bullets. I'll update my answer to make the change more clear. \$\endgroup\$
    – JonBee
    Jan 18, 2016 at 18:59
  • \$\begingroup\$ hey i copied this loop by mistake, I will update my question \$\endgroup\$
    – Nick
    Jan 19, 2016 at 4:46
  • \$\begingroup\$ thanks, I am starter in XNA and i thought that rectangle moves automatically when i change position :d thanks you helped me a lot! \$\endgroup\$
    – Nick
    Jan 19, 2016 at 4:54
1
\$\begingroup\$

Best thing you could do here, is just convert your Rectangle variables into a read-only property. This way you only need to update your position, and your Rectangle will always be up to date:

class Bullet {
    public Rectangle rectangle { 
        get { return new Rectangle((int)position.X, (int)position.y, 10, 5); }
}


class Meteor {    
    public Rectangle rectangle { 
        get { return new Rectangle((int)position.X, (int)position.y, 50, 50); }
    }    
}

Replace your "public Rectangle rectangle;" in both your Bullet and Meteor classes with the above Rectangle properties, and it should fix your issue.

\$\endgroup\$
1
  • \$\begingroup\$ yup, i tried this but now in meteor class X position is not updating, they just don't appear cause are out of screen :d I don't know so much XNA to correct this mistake :( \$\endgroup\$
    – Nick
    Jan 18, 2016 at 15:51
0
\$\begingroup\$

Looks like you are only updating the position vector. When you are checking for intersection the rectangles haven't moved.

You could change the rectangles x,y values as well but you have to change your spriteBatch.Draw call and omit the position.

You might be tempted to skip the position vector entirely and only use the rectangles position. I don't think that's a good idea since (as far as I know) the rectangle members are of int type. You would get a very choppy movement or if the velocity is too small, it won't move at all.

\$\endgroup\$
1
  • \$\begingroup\$ yes you are right, I am not changing position of rectangles :D i just don't know how to do it! \$\endgroup\$
    – Nick
    Jan 18, 2016 at 15:53
0
\$\begingroup\$

I'm a VB person, so I don't know the C syntax, isn't there a For Each loop you can use instead of using your k variable? For each will loop all, it doesn't care how many.

\$\endgroup\$
1
  • \$\begingroup\$ yes, there is, i will try it \$\endgroup\$
    – Nick
    Jan 19, 2016 at 4:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .