C # / XNA - 2D collision bug?

I have quite a bit of code here, but it's relatively simple.

These are all snippets from different classes, all the references are correct, but I think I made a math mistake somewhere and I cannot find it. It always finds a collision on the y-axis by a pixel before it occurs. I haven't tried it with different X-axis positions, but it seems to be close to them next to them.

The "mapSection" structure simply contains the two coordinates of the Vector2s block — the top-left and bottom-left blocks.

tileManager.def_ts is the default tile width and height (32). The size of the player is 32x64.

The toWorldSpace function is doing nothing right now, except to return, so that's not a problem.

When I say block coordinate, I mean what index the block has in the tile array (Ex 0, 0 is the first block, 0, 1 is the second block on the Y-axis, 1, 3 are 1 block on the X-axis and 3 on the axis Y, I don't mean actual pixels.)

From the mosaic motor class:

    public mapSection toMapMinMax(Vector2 position, Vector2 size)
        position = toWorldSpace(position);

        position.X = (float)Math.Floor(position.X / tileManager.def_ts);
        position.Y = (float)Math.Floor(position.Y / tileManager.def_ts);

        size.X = (float)Math.Floor(size.X / tileManager.def_ts);
        size.Y = (float)Math.Floor(size.Y / tileManager.def_ts);

        return new mapSection(position, position + size);

    public bool collision(Vector2 screenPosition, Vector2 size)
        mapSection mapCollisionPossibilities = toMapMinMax(screenPosition, size);

        for (int y = (int)mapCollisionPossibilities.topLeft.Y; y <= mapCollisionPossibilities.bottomRight.Y; y++)
            for (int x = (int)mapCollisionPossibilities.topLeft.X; x <= mapCollisionPossibilities.bottomRight.X; x++)
                if (x >= 0 && y >= 0 && y < tiles.Count && x < tiles[y].Count)
                    if (tileManager.tileTypes[tiles[y][x]].collideable == true)
                        return true;

        return false;


And this is the code from the player class:

        if (!tEngine.collision(position + new Vector2(0, 1), new Vector2(32, 64)))
            position.Y += 1;


I add "Vector2 (0, 1)" because I want to see if there is a pixel collision further down; so it falls until it stumbles. This is very simple, but this is just to test the collision mechanism that doesn't work.

enter image description here

An error is shown there. You can see that the player is too tall.

In the figure, "X:" is the X coordinate of the top left box, "X2:" is the X coordinate of the bottom right box, and "Y:" and "Y2: except Y. They are read directly from mapSection.

If anyone can spot why this is happening, it will be widely appreciated.


If you cannot understand any section of the code, just post in the comments and I will be happy to explain, or if you think that I was too nonspecific in some area of ​​this post.


source to share

1 answer

EDIT . For the tile coordinates problem, your toMapMinMax code should be something like this:

EDIT2 : Subtract (1, 1) from bottomRight, since that's the size we're adding.

public mapSection toMapMinMax(Vector2 position, Vector2 size)
    Vector2 topLeft = position;
    Vector2 bottomRight = position + size - new Vector2(1, 1);

    topLeft.X = (float)Math.Floor(topLeft.X / tileManager.def_ts);
    topLeft.Y = (float)Math.Floor(topLeft.Y / tileManager.def_ts);
    bottomRight.X = (float)Math.Floor(bottomRight.X / tileManager.def_ts);
    bottomRight.Y = (float)Math.Floor(bottomRight.Y / tileManager.def_ts);

    return new mapSection(topLeft, bottomRight);


Also, I was wrong in my previous comment; you want the <= signs in your two loops because most of the time you will be checking 6 chunks.

for the problem separately:

For you to be able to see the symbol at a certain number of pixels, the drawing code and the collision code must be different. If they were the same, for example if they were both 15px (you bump into 15px too early, but you also draw 15px forward), you won't see any change.

The 1 pixel gap indicates the 1 pixel difference between calculating the draw coordinate and calculating the collision coordinates. This 1 pixel difference is most likely caused by rounding differences, it is likely that you are calling Math.Floor in collisional code but not rounding coordinates in drawing code. (I would suggest that you are probably just passing the Vector2 position directly into the SpriteBatch.Draw method).



All Articles