Home > Software engineering >  Collision detection problems in my Tank Trouble like game in C#
Collision detection problems in my Tank Trouble like game in C#

Time:03-17

I am doing a Tank Trouble (aka. AZ) like game in c#, winforms application. I am drawing to a picturebox, the walls are stored in a list, each wall has a specified thickness, a starting and ending point and a boolean which tells if the wall is vertical (true), or if it is horizontal (the bool is false) My collision detector goes trough the list and checks if it collides with one of them, then sets the respective booleans if collision was detected in a direction (up, down, left, right) My problem is, that sometimes there are false positives, and false negatives too, there are cases, when it stucks while no walls are near, sometimes goes through the walls. Could somebody give some suggestions how to improve it? Is there a more optimal way to do it? Here is my code

public void MoveTank()
        {

            // Calculate velocity from angle and base speed
            Vx = (float)(moveSpeed * Math.Sin((angle * 0.0174532925)));
            Vy = (float)(moveSpeed * Math.Cos((angle * 0.0174532925)));

            CollisionDetector();

            if (up == true)
            {
                Vy = 0;
            }
            if (down == true)
            {
                Vy = 0;
            }
            if (left == true)
            {
                Vx = 0;
            }
            if (right == true)
            {
                Vx = 0;
            }
            up = false;
            down = false;
            left = false;
            right = false;

            if (tUp)    //if up key is pressed
            {
                tankCo.Y -= Vy;
                tankCo.X  = Vx;
            }
            if (tDown) //if down key is pressed
            {
                tankCo.Y  = Vy;
                tankCo.X -= Vx;
            }
            if (tLeft) //rotate left
            {
                angle -= angV;
                if (angle < 0)
                {
                    angle = 360   angle;
                }
                angle = angle % 360;
                img = RotateImage(OldImg, angle);
            }
            if (tRight) //rotate right
            {
                angle  = angV;
                angle = angle % 360;
                if (angle < 0)
                {
                    angle = 360   angle;
                }
                img = RotateImage(OldImg, angle);
            }
        }
        
        public void CollisionDetector()
        {
            foreach (Walls.Brick w in GameWindow.wall.allWalls)
            {
                if(w.vertical == true)
                {
                    if (this.tankCo.X > w.wallStart.X && this.tankCo.X   this.Vx < w.wallStart.X)
                    {
                        this.left = true;
                    }
                    else if (this.tankCo.X < w.wallStart.X && this.tankCo.X   this.Vx > w.wallStart.X)
                    {
                        this.right = true;
                    }
                    
                }
                else if(w.vertical == false)
                {
                    if (this.tankCo.Y > w.wallStart.Y && this.tankCo.Y   this.Vy < w.wallStart.Y) 
                    {
                        this.up = true;
                    }
                    else if (this.tankCo.Y < w.wallStart.Y && this.tankCo.Y   this.Vy > w.wallStart.Y)
                    {
                        this.down = true;
                    }
                }
            }
        }

if it isn't enough here is my entire repository

https://github.com/SorbanElod/CSharp/tree/main/SPANzer

CodePudding user response:

After some work here is what i came up with Thank you for your help

public void MoveTank()
    {
        
        if(tUp == tDown)
        {
            Vx = 0;
            Vy = 0;
        }
        else if (tUp)
        {
            // Calculate velocity from angle and base speed
            Vx = (float)(moveSpeed * Math.Sin((angle * 0.0174532925))); //that ugly number is PI/180
            Vy = -(float)(moveSpeed * Math.Cos((angle * 0.0174532925)));
        }
        else if (tDown)
        {
            // Calculate velocity from angle and base speed
            Vx = -(float)(moveSpeed * Math.Sin((angle * 0.0174532925)));
            Vy = (float)(moveSpeed * Math.Cos((angle * 0.0174532925)));
        }

        //If it collides then one component of the velocity will be removed (Vx or Vy)
        CollisionDetector();
        
        tankCo.X  = Vx;
        tankCo.Y  = Vy;
        

        if (tLeft)
        {
            angle -= angV;
            if (angle < 0)
            {
                angle = 360   angle;
            }
            angle = angle % 360;
            img = RotateImage(OldImg, angle);
        }
        if (tRight)
        {
            angle  = angV;
            angle = angle % 360;
            if (angle < 0)
            {
                angle = 360   angle;
            }
            img = RotateImage(OldImg, angle);
        }
    }
public void CollisionDetector()
    {
        foreach (Walls.Brick w in GameWindow.wall.allWalls)
        {
            if(w.vertical == false) // horizontal wall
            {
                //check if tank can collide with wall's side
                if (tankCo.X >= w.wallStart.X && tankCo.X <= w.wallEnd.X)
                {
                    //collision with tehe wall above
                    if (tankCo.Y > w.wallStart.Y && tankCo.Y   Vy < w.wallStart.Y)
                    {
                        Vy = 0;
                    }
                    //collision with the wall below
                    if (tankCo.Y   imgSize < w.wallStart.Y && tankCo.Y   imgSize   Vy > w.wallStart.Y)
                    {
                        Vy = 0;
                    }
                }
                //checks if tank can collide with the walls end
                if (tankCo.Y < w.wallStart.Y && tankCo.Y   imgSize > w.wallStart.Y)
                {
                    //collision with the right end
                    if (tankCo.X > w.wallEnd.X && tankCo.X   Vx < w.wallEnd.X)
                    {
                        Vx = 0;
                    }
                    //collision with the left end
                    if (tankCo.X   imgSize < w.wallStart.X && tankCo.X   imgSize   Vx > w.wallStart.X)
                    {
                        Vx = 0;
                    }
                }
            }
            else if(w.vertical == true) //vertical
            {
                //check if tank can collide with wall's side
                if (tankCo.Y >= w.wallStart.Y && tankCo.Y <= w.wallEnd.Y)
                {
                    //collision with the wall from right
                    if (tankCo.X > w.wallStart.X && tankCo.X   Vx < w.wallStart.X)
                    {
                        Vx = 0;
                    }
                    //collision with the wall from left
                    if (tankCo.X   imgSize < w.wallStart.X && tankCo.X    imgSize   Vx > w.wallStart.X)
                    {
                        Vx = 0;
                    }
                }
                //checks if tank can collide with the walls end
                if (tankCo.X < w.wallStart.X && tankCo.X   imgSize > w.wallStart.X)
                {
                    //collision with the bottom end
                    if (tankCo.Y > w.wallEnd.Y && tankCo.Y   Vy < w.wallEnd.Y)
                    {
                        Vy = 0;
                    }
                    //collision with top end
                    if (tankCo.Y   imgSize < w.wallStart.Y && tankCo.Y   imgSize   Vy > w.wallStart.Y)
                    {
                        Vy = 0;
                    }
                }
            }
        }
    }

It may be a bit complicated but it works for me

  • Related