Lidor Cohen
Lidor Cohen

Reputation: 63

C# - Preventing a picturebox from leaving a boundary

I have a picturebox named player and 4 pictureboxes that act as boundaries at the start of the games. I have this code that gets executed if a key is pressed:

private void HorrorForm_KeyDown(object sender, KeyEventArgs e)
        {
            int x = player.Location.X;
            int y = player.Location.Y;

            if (e.KeyCode == Keys.D)
                x += 7;
            if (e.KeyCode == Keys.A)
                x -= 7;
            if (e.KeyCode == Keys.S)
                y += 7;
            if (e.KeyCode == Keys.W)
                y -= 7;

            if (player.Bounds.IntersectsWith(openspot1.Bounds) || player.Bounds.IntersectsWith(openspot2.Bounds) || player.Bounds.IntersectsWith(openspot3.Bounds) || player.Bounds.IntersectsWith(openspot4.Bounds))
            {
                player.Location = new Point(player.Location.X - 1, player.Location.Y - 1);
            }

            player.Location = new Point(x, y);
        }

How do I move the player but prevent him from leaving the boundaries?

a

Upvotes: 1

Views: 410

Answers (1)

soulflyman
soulflyman

Reputation: 520

There are a view things that are not correct with your code, at least i think so.

  1. you always move the player to his new position. You do check if he touches the boundaries. If he touches the boundaries you move him one pixel up and one pixel to the left only to move him then 7 pixel into the chosen direktion. So inside the if where you check if he touches a boundary you have to interupt and do not execute the rest of the code that sets the new position. A simple return; will do the job.

  2. If a key is pressed you perfome the boundary check if the player does not touch a boundaries you will move the player. This is the wrong order. You have to check if the player will touch the boundarie after the move and only if he will not touch the boundary move him. Otherwise you will move him into the boundary and never get him out again.

So here is your code with some corrections:

private void HorrorForm_KeyDown(object sender, KeyEventArgs e)
{
    int x = player.Location.X;
    int y = player.Location.Y;

    if (e.KeyCode == Keys.D)
        x += 7;
    if (e.KeyCode == Keys.A)
        x -= 7;
    if (e.KeyCode == Keys.S)
        y += 7;
    if (e.KeyCode == Keys.W)
        y -= 7;

    var tempPlayerPosition= player.Bounds; // get the players position and remember it temporary
    tempPlayerPosition.X = x; // change the players temporary pisition to the new one that it will have after the move
    tempPlayerPosition.Y = y;

    //check if the play would touch the boundyries if we use the new temporary pisition
    if (tempPlayerPosition.IntersectsWith(openspot1.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot2.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot3.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot4.Bounds))
    {
        return; //if he would touch the boundary, then do nothing
    }

    player.Location = new Point(x, y); //if he would not touch the boundary, move him to his new location
}

But maybee you also want to

  • prevent that your code is executed (even if he does not chang any values) if a key is pressed that is not W, S, A or D.
  • use switch instead of if this makes it even more readable.
  • instead of writing every time the number 7, use a local variable, so you have to change only one value if this will be changed in the future.

So my recomendation would look like this:

private void HorrorForm_KeyDown(object sender, KeyEventArgs e)
{    
    var oneStep = 7; // define the amount of pixel the player will be moved
    var tempPlayerPosition = player.Bounds;// get the players position and remember it temporary

    switch (e.KeyCode) // check which key was presses
    {
        case Keys.D:
            tempPlayerPosition.X += oneStep; // move right
            break;
        case Keys.A:
            tempPlayerPosition.X -= oneStep; // move left
            break;
        case Keys.S:
            tempPlayerPosition.Y += oneStep; // move down
            break;
        case Keys.W:
            tempPlayerPosition.Y -= oneStep; // move up
            break;
         default: // you may wan't to do nothing if there any other key presses...
            return;
    }

    //check if the play would touch the boundyries if we use the new temporary pisition
    if (tempPlayerPosition.IntersectsWith(openspot1.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot2.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot3.Bounds) || 
        tempPlayerPosition.IntersectsWith(openspot4.Bounds))
    {
        return; //if he would touch the boundary, then do nothing
    }

    player.Location = new Point(tempPlayerPosition.X, tempPlayerPosition.Y);   //if he would not touch the boundary, move him to his new location
}

Does this help you?

Upvotes: 1

Related Questions