problem detecting when rectangles do not intersect

collision detection works but when the player walks off a platform there is no way of detecting that there is no ground beneath its feet without breaking the collision detection, he has to move UP first so ColTop becomes false and gravity can take over. (i left out irrelevant code)

class CollisionManager
{
public int Update(ICollidableHero hero, ICollidable Grey)
{
if (hero.CollisionRectangle.Intersects(Grey.CollisionRectangle1))
{
return 1;
}
if (hero.CollisionRectangle.Intersects(Grey.CollisionRectangle2))
{
return 2;
}
if (hero.CollisionRectangle.Intersects(Grey.CollisionRectangle3))
{
return 3;
}
if (hero.CollisionRectangle.Intersects(Grey.CollisionRectangle4))
{
return 4;
}
else
{
return 0;
}
}
}
interface ICollidable
{
Rectangle CollisionRectangle1 { get; set; }
Rectangle CollisionRectangle2 { get; set; }
Rectangle CollisionRectangle3 { get; set; }
Rectangle CollisionRectangle4 { get; set; }
}
interface ICollidableHero
{
Rectangle CollisionRectangle { get; set; }
}

public class Hero : ICollidableHero
{

    public bool ColTop { get; set; }
    public bool ColBottom { get; set; }
    public bool ColLeft { get; set; }
    public bool ColRight { get; set; }

    private Rectangle _colRect;
    public Rectangle CollisionRectangle { get => _colRect; set => _colRect = value; }

    public void Update(GameTime gameTime)
    {
        if (_bediening.Left && !ColLeft)
        {
            ColRight = false;
            Positie -= VelocityX;
            Direction = 2;
        }
        if (_bediening.Right && !ColRight)
        {
            ColLeft = false;
            Positie += VelocityX;
            Direction = 1;
        }
        if (_bediening.Up && !ColBottom)
        {
            ColTop = false;
            Positie -= VelocitY;
            Direction = 3;
        }
        if (_bediening.Down && !ColTop)
        {
            ColBottom = false;
            Positie += VelocitY;
            Direction = 4;
        }
    }
}

case 1:
if (cm.Update(_hero, level1.blokArray[x, y]) == 1)
_hero.ColRight = true;
if (cm.Update(_hero, level1.blokArray[x, y]) == 2)
_hero.ColTop = true;
if (cm.Update(_hero, level1.blokArray[x, y]) == 3)
_hero.ColLeft = true;
if (cm.Update(_hero, level1.blokArray[x, y]) == 4)
_hero.ColBottom = true;

break;

/*if i were to add:

if (cm.Update(_hero, level1.blokArray[x, y]) == 0)
_hero.ColTop = false;

then collisoion detection breaks and the player can walk through walls, I need another way of detecting when there is no collision*/

Hard to read and i just glanced it over but…

Isn’t the Top Bottom reversed from the way left right is handled in the collision check?
Shouldn’t it be Up && Up then Down && Down

ColTop and ColBottom refers to the top and bottom of the blocks my game is made of, but that’s not the issue. the problem is that since the way of detecting when there is no collision does not work, i don’t know how i could make it work in another way. (Direction is used for the sprites)

You don’t have enough code shown to see what the problem is. Im not even sure what the problem is.
I think maybe the basic design you are following might be flawed are you doing this from a tutorial ?

These bottom two really make no sense to me though since they aren’t intuitive and i cant see the code.
if this !ColTop means no collision above and _bediening is your players desired direction to move?

Then you are saying if i want to move down, and there is no collision above me, move down?

    if (_bediening.Down && !ColTop)  // <<<<< if no collision up ?
    {
        ColBottom = false; // I also don't understand why you are setting collision bools were you haven't checked for a collision
        Positie += VelocitY;  // <<< move down
        Direction = 4;
    }

Also select all the code and hit the preformated text button > </>

if _bediening.Down is true that means the arrow-down button on the keyboard is pressed, my 2d game is completely build out of square blocks with each 4 rectangles for collision. if ColTop is true then the collision rectangle of the player is in collision with the top collision rectangle of the block. can i mail you the whole game? it’s a bit too big to paste on a forum

If you have a google account and who doesn’t now days a.k.a. (gmail you tube) then you already have a google drive. https://www.google.com/drive/ just zip the whole thing up upload it, get a sharable link and post it.

here’s wetransfer, couldn’t get it done with google drive. https://we.tl/t-wuAKqmbO0a

Im taking a look at your project right now. Ill have to clean it up first a quite a bit before i can see what is going on.

There is a few things that i see right off the bat. You are sort of trying to use interfaces and extend classes were they aren’t really needed. That has spegettified your code somewhat unnecessarily and made it hard to read.

For example your bedieng class is nothing more then your Heros update function that has been placed in a concrete class that has a abstract base. Anyways.

Can you clarify how you want each type of Block to interact with the player?

e.g. ladders which are pretty obvious, i see greyblocks which appear solid.
Spikes flags is the player suppose to fall thru these blue and red blocks im a little fuzzy on… ect.

the game is not finished yet, the idea is that when the player jumps for example on the red button then all red blocks become active and the player can walk through the other colors, grey blocks are always active. I’m gonna make it work first and then implement SOLID principles (those are some rules that “un-spaghettify” your code). the problem i’m asking help for is that when the player walks off a platform he doesn’t “fall” to the ground until the UP arrow is pressed the same for other directions and i can’t seem to fix this.

again the game isn’t at all finished yet, i’ve only implemented collision for the grey blocks until this problem is fixed. I also made the collision rectangles visible to debug easier.

I found your bug already but it took me rewriting half your code cut it size by like half already. You might as well check back in a couple of hours when im finished.

Im going to simplify your collision code entirely cause you are pretty far off track in the wilderness. Im going to make you a tile descriptor to that makes things clearer for adding functionality.

Thanks, can you share the project then? And clarity why rewriting half was nessecairy


On google drive the download button is the arrow on the top right.

Well it works now including jumping and gravity, the tile blocks can have interacting effects with your player. I made it so you can climb the ladder and walk thru non active walls but that is about all i did on that.

clarity why rewriting half was nessecairy

Sorry that was a figure of speech, to say i rewrote a lot of stuff and deleted stuff and renamed it. If you look at your game1 you’ll see its much smaller now.

The main idea i wanted to impart in the changes i made is that each class now is responsible for a much more specific thing. As well that each class now serves as a tool for the other classes.

Interfaces can be useful and i know a lot of people scream do this and do that but the way you were using them all over was actually screwing you over huge.
The rule of thumb is if you don’t need it, then you don’t.
You know you need it when you run into a problem were you need it.

Basically you were painting yourself into a corner the way you were doing movement with the directions. You need the up down and left right checks to be separated.
If you were earlier in i would of recommended you used a quad tree or spacial collision map to track collisions but you are so far into it i think a bit of encapsulation is about as good as can be done. Though i do recommend you read up on spacial collision mapping quadtrees and such so you get a idea about it.

I added some stuff as well to help you visually debug collisions so you can see what is actually colliding and what isn’t. This sort of thing is a huge help typically.

I added jumping and interactions with specific kinds of tiles differently.
All that is based off how i restructured the map data encapsulation.
Which is most of what i did just so i could fix up the player motion later.

But also because i removed all your old collision rectangles and replaced that with the tiles textures themselves to collide with.

This works as follows…

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Animatie_klas
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        Texture2D background;
        SpriteBatch spriteBatch;
        Texture2D heroTexture;
        CollisionManager collisionManager;
        Hero hero;
        CurrentLevel currentLevel;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = 1800;  // set this value to the desired width of your window
            graphics.PreferredBackBufferHeight = 960;   // set this value to the desired height of your window
            graphics.ApplyChanges();
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            Globals.SetMeUpInLoad(spriteBatch, GraphicsDevice); // --- shortcut added for testing can be comment out.... and everything that errors after that.... gets deleted with it.

            background = Content.Load<Texture2D>("background");

            var level1 = new Level1LoadingData(Content);
            currentLevel = new CurrentLevel(level1.tileMapDescriptorLoadingData);

            heroTexture = Content.Load<Texture2D>("man");
            hero = new Hero(heroTexture, new Vector2(200,610));

            collisionManager = new CollisionManager();
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            hero.Update(gameTime);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {            
            GraphicsDevice.Clear(Color.White);
            spriteBatch.Begin();

            spriteBatch.Draw(background, new Rectangle(0, 0, 1800, 960), Color.White);

            currentLevel.DrawWorld(spriteBatch);

            hero.Draw(spriteBatch);

            collisionManager.DrawDebugColliders(spriteBatch, hero, CurrentLevel.mapTiles);

            Globals.DrawString(hero.CollisionRectangle.Location.ToVector2(), CollisionManager.collistionDebugString.ToString(), Color.Red);

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

I made you a TileDescriptor class which is used per level.
A array of these objects are created in Level1LoadingData
If you look at the Level1LoadingData class you can see how it takes on the responsibility of not just describing what textures are used but what their intended behavior is.

They both hold the textures and load them and you input a bunch of bools that describe how a tile behaves. such as IsActive IsLadder IsTriggerable ect…

The loading data is passed to a CurrentLevel which makes your map from your int[,] map data which represents which texture and those Tile Descriptions. It creates the map as Tile objects these are nearly the same as the Tile Descriptors but the destination drawing rectangles are created from the descriptors and the map x y.

The collision class then uses this mapData and the hero to determine what sort of interactions are taking place per frame.
The hero class update method has its parts separated out into methods and the physical behavior of the character is more controllable.

The collisions class draw method is just for debugging.
So is the Globals mostly the deflate extension i did use in the hero update and collision checks.

.
.

I put in a lot that would be too much to explain without a tutorial but it should be straight forward other then the tile vs the tile descriptor and level interactions

The one concern is that map tile positional offset you are doing might bite you later on. but it seems to be ok. Anyways i just basically encapsulated the logic of what you were doing before.

In the Globals class i would keep the extensions there are about 4 or 5 of them the deflate is used in the hero class. The rest of the globals class is used mostly just for debuging and you can probably comment ou and everything that errors after it directly. line by line then delete or you can keep it for debugging. I added a timer class for animations but didn’t use it

I probably could of cleaned it up more.

wow, Thanks you really helped me out. I thought you did too much because I am supposed to make this university project on my own. although it’s never said that it is not allowed to ask for help on a forum. You said i was working myself in a corner so I reverse engineered the changes you made and I learned alot about game development, debugging interfece, collision detection and monogame in general. a big thanks to you. i’ve never had a person helping me out in such an intense level. you’ve really put some work into it.

Welcome it was a nice diversion from what i was working on.
And its far from well done.