Player only colliding with last object in list

I have a list of Objects for the class Object.cs

And collision works for it:
foreach (Object o in Objects)
{
if (player.hitbox.isOnTop(o.hitbox))
{
player.cantmovedown = true;
}
else
{
player.cantmovedown = false;
}
if (player.hitbox.isOnLeft(o.hitbox))
{
player.cantmoveright = true;
}
else
{
player.cantmoveright = false;
}
if (player.hitbox.TouchRightOf(o.hitbox))
{
player.cantmoveleft = true;
}
else
{
player.cantmoveleft = false;
}
if (player.hitbox.isOnBottom(o.hitbox))
{
player.cantmoveup = true;
}
else
{
player.cantmoveup = false;
}
}

It only detects it for the LAST added objects. I tried adding

break;

to each of these blocks but it just made it worse.

(sorry but the “code quote” thing isn’t working for all the codes so it’s kinda hard to read)

are you using double `?

Try wrapping it all in triple `

```c#
code here
```

You have a lot of booleans that could possibly conflict.

Give this a read: State Machines

Well yeah, because the booleans get overwritten in every iteration so only the last one will matter. You can fix this by initializing the bools to false and dropping the else parts in the loop.

You are setting the values for every object in objects. That’s why only the last is taken in to account. Try this:

player.cantmoveup = false;
player.cantmovedown = false;
player.cantmoveright = false;
player.cantmoveleft = false;

foreach (Object o in Objects)
{
    if (player.hitbox.isOnTop(o.hitbox))
    {
        player.cantmovedown = true;
    }
    if (player.hitbox.isOnLeft(o.hitbox))
    {
        player.cantmoveright = true;
    }
    if (player.hitbox.TouchRightOf(o.hitbox))
    {
        player.cantmoveleft = true;
    }
    if (player.hitbox.isOnBottom(o.hitbox))
    {
        player.cantmoveup = true;
    }
}

This could also be optimized so that you would first check the boolean value, then doing the collision detection. Example:

foreach (Object o in Objects)
{
    if (!player.cantmovedown && player.hitbox.isOnTop(o.hitbox))
    {
        player.cantmovedown = true;
    }
    etc....
}

EDIT: @Jjagg already gave the correct answer :wink:

1 Like

Just to explain this further (if I am correct) to @James_Maslaki checking a boolean flag is nothing in performance costs, whereas a collision checking function may be a bit more costly and there is no point running it 4 times.

Putting the bool check first; if it returns false then it won’t bother checking the collision part. At least that is how I believe && works in C# .NET.

Jep, that’s true for most languages. VB is an exception though, its And operator checks both conditions, but it has an AndAlso operator that behaves like you would expect. I wonder why it’s done like that…

Something we learnt here at work is division is a tiny bit different between VB and C#. If of interest look here.