Home > Software design >  Set an object as "Solid" in C# windows Form when developing a stickman platform game
Set an object as "Solid" in C# windows Form when developing a stickman platform game

Time:11-25

For a school project I need to develop a platform style game purely in C# Windows forms and cannot use any other languages. I have a gravity and movement system sorted already but my character is still able to jump off the map or jump through picture boxes. How would I go about making these objects solid so that the character cannot run through them. Here is my code

What my game looks like:

Game interface

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    bool left;
    bool right;

    int gravity = 20;
    int force;
    bool jump;

    private void Timer(object sender, EventArgs e)
    {
        if (left == true)
        {
            Character.Left -= 15;
            if (Character.Image != Properties.Resources.LeftChar)
            {
                Character.Image = Properties.Resources.LeftChar;
            }
        }

        if (right == true)
        {
            Character.Left  = 15;
            if (Character.Image != Properties.Resources.RightChar)
            {
                Character.Image = Properties.Resources.RightChar;
            }
        }

        if (jump == true)
        {
            Character.Top -= force;
            force -= 1;
        }
  

        if (Character.Top   Character.Height >= GameBoundary.Height)
        {
            Character.Top = GameBoundary.Height - Character.Height;
            jump = false;
        }
        else
        {
            Character.Top  = 10; 
        }

    }
    private void keydown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.A)
            left = true;
        if (e.KeyCode == Keys.D)
            right = true;
        if (jump != true)
        {
            if (e.KeyCode == Keys.W)
            {
                jump = true;
                force = gravity;
            }
        }
    }

    private void keyup(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.A)
            left = false;
        if (e.KeyCode == Keys.D)
            right = false;
    }
}

Shows error

I created an invisible panel that was the same size of the game called "Gameboundary", this made it possible for the player to walk on the bottom of the window, but I am not sure how I would apply this to the rest of the code. If anybody has any suggestions it will be greatly welcome. Not too good at C# just yet!

CodePudding user response:

You need to implement collision detection. Draw an imaginary box around your person and any objects you don't want him to pass through. Check if any of the boxes overlap. If they do, move one or both of the objects back until the boxes no longer overlap.

CodePudding user response:

Here is a basic Collision Detection system:

public class CollisionDetection
    {
        public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects)
        {
            for (int i = 0; i < Object.Parent.Controls.Count; i  )
            {
                if (Object.Parent.Controls[i].Name != Object.Name)
                {
                    if (Object.Left   Object.Width   SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top   Object.Height   SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left   Object.Parent.Controls[i].Width   SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top   Object.Parent.Controls[i].Height   SpaceBetweenObjects)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static bool ObjectTouchingOthers(Control Object, int SpaceBetweenObjects,  Control[] ControlsToExclude )
        {
            for (int i = 0; i < Object.Parent.Controls.Count; i  )
            {
                if (ControlsToExclude.Contains(Object.Parent.Controls[i]) == false && Object.Parent.Controls[i].Name != Object.Name)
                {
                    if (Object.Left   Object.Width   SpaceBetweenObjects > Object.Parent.Controls[i].Left && Object.Top   Object.Height   SpaceBetweenObjects > Object.Parent.Controls[i].Top && Object.Left < Object.Parent.Controls[i].Left   Object.Parent.Controls[i].Width   SpaceBetweenObjects && Object.Top < Object.Parent.Controls[i].Top   Object.Parent.Controls[i].Height   SpaceBetweenObjects)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }

The first argument Object is the control you want collision detection for, and it will only detect other controls in the same container, so if you used it for a control in a panel, for example, it would only work with other controls in the panel, likewise with a Form or any other control. The second argument simply specifies how much distance you want between the controls when they are touching. If you're using the second overload, the third argument is an array of controls that you do not want collision detection for. This is how you would use the second overload:

private void btnMoveLeft_Click(object sender, EventArgs e)
    {
        btnPlayer.Left -= 1;
        if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1, new Control[] {button1, button2}) == true)
        { 
            btnPlayer.Left  = 1;
        }
    }

With this overload, it will continue right through the controls you specified in the array.

And just to wrap it up, here's a basic example of how to set up collision detection:

private void btnMoveLeft_Click(object sender, EventArgs e)
    {
        btnPlayer.Left -= 1;
        if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
        { 
            btnPlayer.Left  = 1;
        }
    }

    private void btnMoveRight_Click(object sender, EventArgs e)
    {
        btnPlayer.Left  = 1;
        if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
        {
            btnPlayer.Left -= 1;
        }
    }

    private void btnMoveUp_Click(object sender, EventArgs e)
    {
        btnPlayer.Top -= 1;
        if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
        {
            btnPlayer.Top  = 1;
        }
    }

    private void btnMoveDown_Click(object sender, EventArgs e)
    {
        btnPlayer.Top  = 1;
        if (CollisionDetection.ObjectTouchingOthers(btnPlayer, 1) == true)
        {
            btnPlayer.Top -= 1;
        }
    }

Just remember that you're going to have to change the names of the controls in the code I have here. And for reference, here is my test form:

enter image description here

  • Related