-1

Okay, so I have been searching for hours without any results and really hope that you could help me. I'm having some trouble getting the intersect to work. Nothing happends when my classes collide which is probably me being blind but also really new to XNA. I have created a Shoot-Em-Up game and I want the game to end as the player controlled space shuttle collides with an enemy.

Using classes; Game1.cs, Player.cs and Enemy.cs. Notice that I have only pasted the info I think is necessary to figure this out.

Game1.cs

protected override void LoadContent()
{
    shuttle = new Player(Content.Load<Texture2D>(@"spaceship"), new Vector2(300, 400), new Vector2(24, 24), spriteBatch);
}

protected override void Update(GameTime gameTime)
{
    if (random.Next(0, 70) < droprate)
    {
        int posX = random.Next(20, 580);
        enemyList.Add(new Enemy(Content.Load<Texture2D>(@"enemy1"), new Vector2(posX, -50), new Vector2(24, 24), spriteBatch));
        droprate += 0.10;
    }

    foreach (Enemy e in enemyList)
    {
        if (shuttle.rectangle.Intersects(e.rectangle))
        Exit();
    }
}

Player.cs

    public Rectangle rectangle;

    public Player(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
    {
        this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);
    }
    public override void Update(GameTime gameTime)
    {

        KeyboardState keyboardState = Keyboard.GetState();
        if (keyboardState.IsKeyDown(Keys.Right))
        {
            initialPos.X += 9;
        }
        if (keyboardState.IsKeyDown(Keys.Left))
        {
            initialPos.X -= 9;
        }
        if (keyboardState.IsKeyDown(Keys.Up))
        {
            initialPos.Y -= 5;
        }
        if (keyboardState.IsKeyDown(Keys.Down))
        {
            initialPos.Y += 5;
        }

        initialPos.X = MathHelper.Clamp(initialPos.X, 18, screenWidth - 18);
        initialPos.Y = MathHelper.Clamp(initialPos.Y, 24, screenHeight - 24);
        base.Update(gameTime);
    }

Enemy.cs

public Rectangle rectangle;

public Enemy(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
{
    this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);
}
    public override void Update(GameTime gameTime)
    {
        initialPos.Y += 3.5f;
        if (initialPos.X < 300)
            initialPos.X += 0.41f;
        if (initialPos.X > 300)
            initialPos.X -= 0.41f;
    }
Arvin Ashrafi
  • 621
  • 2
  • 7
  • 9
  • 1
    Do the player or enemies move? You don't appear to ever update their collision bounds after initially creating them. – Cole Campbell Jan 16 '14 at 19:21
  • the player/shuttle is controlled by me, while the enemy space ships are constantly moving towards the bottom of the screen. – Arvin Ashrafi Jan 16 '14 at 19:29
  • And are you ever updating the value of `rectangle` for your `Enemy` and `Player` objects? You are using the `Intersects()` method correctly, which implies that the data you're giving it is wrong. – Cole Campbell Jan 16 '14 at 19:38
  • this I am not sure about. I could post my update functions and perhaps then you would understand better. – Arvin Ashrafi Jan 16 '14 at 19:41
  • have you stepped through with a debugger? Might help to see if you are working with the data you think you are – Robb Jan 16 '14 at 19:45

2 Answers2

1
public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;
    if (initialPos.X < 300)
        initialPos.X += 0.41f;
    if (initialPos.X > 300)
        initialPos.X -= 0.41f;

You should be moving the rectangle member of your player and enemy classes. You set them once in the constructor. The initial player rectangle at the bottom of the screen will never intersect the initial enemies positions you marked at the top.

Im not even sure what initialPos is, but if you want to do it this way and sprites are moving, you need to make sure you move the hitboxes along with the sprites.

public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;
    rectangle.Y +=  3.5f;
    if (initialPos.X < 300){
        initialPos.X += 0.41f;
        rectangle.X += 0.41f;
}
    if (initialPos.X > 300)
        initialPos.X -= 0.41f;
        rectangle.X -= 0.41f;
}

Edit: Use RectangleF for floating point precision.

Edit2: In games, commonly, the hitbox is a fraction amount smaller than the sprites/models size. This will stop hits from registering from open space in non rectangular sprites like spaceships. :)

Edit3: OR

public override void Update(GameTime gameTime)
{
    initialPos.Y += 3.5f;

    if (initialPos.X < 300) initialPos.X += 0.41f;
    if (initialPos.X > 300) initialPos.X -= 0.41f;


    rectangle.X -= Convert.ToInt32(initialPos.X);
    rectangle.Y += Convert.ToInt32(initialPos.Y);

}

edit 4: Will the rectangles move at all?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace TestBench{
    class Program{
        static void Main(string[] args){
        float f = 0.0F;
        int Y = 0;

        for (int i = 0; i < 10; i++) {
            f += 0.41F;
            Y = Convert.ToInt32(f);

            Debug.WriteLine("Float: " + f + " Int32 " + Y);

        }

        }
    }
}

Results:

Float: 0.41 Int32 0
Float: 0.82 Int32 1
Float: 1.23 Int32 1
Float: 1.64 Int32 2
Float: 2.05 Int32 2
Float: 2.46 Int32 2
Float: 2.87 Int32 3
Float: 3.28 Int32 3
Float: 3.69 Int32 4
Float: 4.1 Int32 4
C4F
  • 662
  • 7
  • 18
  • yes, I understand what you mean. But I cannot the cordinates of a rectangle cannot be expressed in float. It has to be in int, how do I bypass this? – Arvin Ashrafi Jan 16 '14 at 19:56
  • Use rectangleF : http://msdn.microsoft.com/en-us/library/system.drawing.rectanglef(v=vs.110).aspx – C4F Jan 16 '14 at 20:13
  • @TheC4Fox, XNA doesn't have RectangleF. What you could do, @ArvinAshrafi, is simply store the positions as floats like you are doing, and at the end of every update call, convert the float values into a rectangle like you do when you initialized the Players/Enemy :`this.rectangle = new Rectangle(Convert.ToInt32(initialPos.X), Convert.ToInt32(initialPos.Y), 48, 48);` – davidsbro Jan 16 '14 at 20:17
  • @davidsbro Using XNA framework means he cant use the drawing library? – C4F Jan 16 '14 at 20:19
  • @TheC4Fox No, but I think it be easier just to convert float values into the XNA rectangle because he wouldn't have to convert the RectangleF into a rectangle if he wanted to use it in, say, a spritebatch.Draw(), and other XNA functions, and a human isn't going to be able to detect if the collision rectangle is off by 0.9f. I just was throwing that out there because it would be done either way – davidsbro Jan 16 '14 at 20:23
  • well, if i convert it to Int it cannot contain decimals, right? So I really don't know how to do this. – Arvin Ashrafi Jan 16 '14 at 20:25
  • @ArvinAshrafi, yeah, but you can still store the values as floats, in your `initialPos`, and just round them to ints. Say, for example, in 4 update calls `initialPos` has the following X values : 0.6f, 1.01f, 1.42f, and 1.83f. The rectangle will have the X values of 1,1,1,2. This, IMO, should be accurate enough not to notice. So even though there are no decimals, you still have the accurate values in your `initialPsos` – davidsbro Jan 16 '14 at 20:29
  • also, I don't think this would work since I am constantly adding to initialPos.Y and initialPos.X constantly. That would mean that I'm adding 0.41f which is the same as 0 all the time. Therefor the rectangle isn't moving. – Arvin Ashrafi Jan 16 '14 at 20:44
  • @ArvinAshrafi Are your sprites moving? – C4F Jan 16 '14 at 20:49
  • yes, I'm moving the user controlled sprite while the enemy sprites are moving aswell – Arvin Ashrafi Jan 16 '14 at 20:53
  • Using my edit3 above with both enemies and player position hitboxes, they will intersect very very very soon to when your sprites intersect. The rectangles will be moving based on position numbers being rounded down to integers. It will move, only at a loss of resolution. Ill show you your loss in resolution in edit 4. – C4F Jan 16 '14 at 20:54
  • Dont worry, OP will deliver. Lets just wait. – C4F Jan 17 '14 at 18:00
  • http://weknowmemes.com/wp-content/uploads/2012/01/op-will-surely-deliver-lets-just-wait.jpg – C4F Jan 30 '14 at 14:07
0

If you want to use float values, you could simply convert your float values in initialPos into a rectangle everytime. The initialPos would keep it's accuracy, and the rectangle would just round the float values. Or you could create your own RectangleF structure that works with all XNA's other objects (Giving some credit to @TheC4Fox since I borrowed from his idea about floating-point rectangles...just made it so that the RectangleF would be compatible with XNA's other functions easily. +1 for your answer bro since it Answered the OP's original Q). For example:

public struct RectangleF
{
    float w = 0;
    float h = 0;
    float x = 0;
    float y = 0;

    public float Height
    {
        get { return h; }
        set { h = value; }
    }

    //put Width, X, and Y properties here

    public RectangleF(float X, float Y, float width, float height)
    {
        w = width;
        h = height;
        x = X;
        y = Y;
    }

    public bool Intersects(Rectangle refRectangle)
    {
        Rectangle rec = new Rectangle((int)x, (int)y, (int)w, (int)h);
        if (rec.Intersects(refRectangle)) return true;
        else return false;
    }
}

Then you would declare this in your Player and Enemy classes:

public RectangleF rectangle;

public Enemy(Texture2D texture, Vector2 initialPos, Vector2 origin, SpriteBatch spriteBatch) : base(texture, initialPos, origin, spriteBatch)
{
    this.rectangle = new RectangleF(initialPos.X, initialPos.Y, 48, 48);
}
public override void Update(GameTime gameTime)
{
    rectangle.Y += 3.5f;
    if (rectangle.X < 300)
        rectangle.X += 0.41f;
    if (rectangle.X > 300)
        rectangle.X -= 0.41f;
}

HTH

davidsbro
  • 2,761
  • 4
  • 23
  • 33