2
\$\begingroup\$

I've made a temporarily method for collision with all the blocks on the screen. (I used almost the same method in the past, but only for one block at the time.)

So I start in the Sprite class. I use a list named tileCollision and I make a new list in the constructor for the tiles:

public List<Rectangle> tileCollision { get; set; }

public Sprite(GraphicsDevice gd,Texture2D collisionImage, Texture2D textureImage, Vector2 position, Point frameSize, Point currentFrame)
{
    this.collisionImage = collisionImage;
    this.textureImage = textureImage;
    this.position = position;
    this.frameSize = frameSize;
    this.currentFrame = currentFrame;
    depth = 0;
    // the Rectangle list
    tileCollision = new List<Rectangle>();
}

This is the collision method for the Sprite class (NOTE: this class is abstract):

public virtual void Collision (Rectangle collisionRect, List<Rectangle> tileCollision)
{
}

So now we can have a look at the PlayerMovement class, derived from the Sprite class. This is the Collision method (NOTE: the TileSprite class (class for my tiles) also contains a collision rectangle):

public override void Collision(Rectangle collisionRect, List<Rectangle> tileCollision)
{
    foreach (Rectangle rect in tileCollision)
    {
        if (collisionRect.Intersects(rect))
        {

            stopping = true;
            walking = false;

            if (collisionRect.X < rect.X)
            {

                fallingTest = false;
                stopping = true;

                if (left)
                {
                    stopping = false;
                    fallingTest = false;
                }
            }

            if (collisionRect.X > rect.X)
            {

                fallingTest = false;
                stopping = true;

                if (!left)
                {
                    stopping = false;
                    fallingTest = false;
                }
            }

            if (collisionRect.Y <= rect.Y - 50)
            {
                ground = true;
                fallingTest = true;
                stopping = false;

                if (moving)
                {
                    walking = true;
                }
            }

            if (collisionRect.Y >= rect.Y + rect.Height)
            {

                stopping = true;

                if (moving)
                {
                    walking = true;
                }
            }
        }
        if (!collisionRect.Intersects(rect))
        {
            fallingTest = false;
            stopping = false;

            ground = false;

            if (moving)
            {
                walking = true;
            }
        }
    }
}

And finally, this is my SpriteManagerGeneral class (the class where I "connect" everything for sprite handling). The dirt tiles are added to the tileCollision list (NOTE: just for testing):

// childTiles list is not used for collision
tileBase.childTiles.Add(dirt);
tileBase.tileCollision.Add(dirt4.bCollisionRect);
tileBase.childTiles.Add(dirt2);
tileBase.tileCollision.Add(dirt3.bCollisionRect);
tileBase.childTiles.Add(dirt3);
tileBase.tileCollision.Add(dirt2.bCollisionRect);
tileBase.childTiles.Add(dirt4);
tileBase.tileCollision.Add(dirt.bCollisionRect); 

My update method for the collision looks like this:

playerBase.children.ForEach(c => c.Collision(player.collisionRect, tileBase.tileCollision));

(playerBase is the base of the player that contains a list (children) with all the body parts in it)

So now my problem: my problem is that my game only uses the collision logic on the LAST item (Rectangle) added to the tileCollision.

You see here that dirt is added as the last item, so the collision will work on this block, but not on the others.

I want it so that the method loops through every item instead of the last item.

\$\endgroup\$
1
\$\begingroup\$

I used if (!collisionRect.Intersects(rect)) in my collision method but that means that IF one tile doesn't collide with the player, then it will call this if statement.

So I changed this to if (!(tileCollision.Any(c => collisionRect.Intersects(c)))) and it works now.

This code translated to English:

If none of the collisionboxes from the tile collide with the player, then call this statement.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.