0
votes

I am making a simple game. I managed to make my character move with arrow keys and fire. I added some walls to the map which are pictureboxes. I managed to detect the collision like this:

private void timer6_Tick(object sender, EventArgs e){
    foreach (PictureBox pic in brick){
        if (pic.Bounds.IntersectsWith(pb_sprite.Bounds)){
            Console.WriteLine("Colision!");
            switch (rotation){
                case "up":
                    canup = false;
                    candown = true;
                    canleft = true;
                    canright = true;
                    break;
                case "down":
                    canup = true;
                    candown = false;
                    canleft = true;
                    canright = true;
                    break;
                case "left":
                    candown = true;
                    canup = true;
                    canleft = false;
                    canright = true;
                    break;
                case "right":
                    candown = true;
                    canup = true;
                    canleft = true;
                    canright = false;
                    break;
             }
        }
        else
        {
            Console.WriteLine("No colision?!");
        }
    }
}

It works as expected but soon as I hit the object (wall) I get "Colision!" echo which is ok, this also stops movement in the direction which the character was facing when the collision occurred. The thing is when I exit the collision one of these bools stays false which prevents my character to move again in the same direction. I tried setting all of these bools to true in else branch but since there are five walls even if there is collision else branch gets executed 4 times out of 5. I need some kind of "any" function to check if NO or ANY walls are being hit at one moment.

3
You can check collision on your movement function -assuming you have one- rather than inside your Timer and if you detect a collision, you do not allow that movement.uTeisT
Consider a different approach: the user enters a command. You then evaluate the command in the context of the game, and the command is either approved or denied. If approved, then the character moves in the indicated direction; if denied, nothing happens. I think if you structure your game using this pattern, a lot of your problems will go away.Eric Lippert

3 Answers

1
votes

I'm not 100% sure what you are getting at but I think this might help:

canup = true;
candown = true;
canleft = true;
canright = true;
foreach (PictureBox pic in brick)
{
    if (pic.Bounds.IntersectsWith(pb_sprite.Bounds))
    {
        Console.WriteLine("Colision!");
        switch (rotation)
        {
            case "up":
                canup = false;
                break;
            case "down":
                candown = false;
                break;
            case "left":
                canleft = false;
                break;
            case "right":
                canright = false;
                break;
        }
    }
    else
    {
        Console.WriteLine("No colision?!");
    }
    ...

This would set all the bools to true at the start, and only set the individual bools as false inside the loop.

1
votes

Is it possible, that you only stop your character, but do not resolve the collision? The brick and the character are inside each other, after all, to trigger a collision. They need to be moved outside of each other to be collision-free again.

Common methods for this are setting the character's position back by a frame, or if you want to be more exact, find out how deep the character penetrated ( ͡° ͜ʖ ͡°) the brick and move it back along the direction where it came from by that amount.

0
votes

Well, there is an Any function actually (https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx).

You could use it something like this:

bool collision = brick.Any(pic => pic.Bounds.IntersectsWith(pb_sprite.Bounds));
switch(rotation)
{
    case "up": 
        canup = !collision;
        break;
    ...
}