我的 Tank Trouble 中的碰撞检测问题,例如 C# 中的游戏

Collision detection problems in my Tank Trouble like game in C#

我正在用 c# 和 winforms 应用程序做 Tank Trouble(又名 AZ)之类的游戏。 我正在画一个图片框,墙壁存储在一个列表中,每面墙壁都有指定的厚度、起点和终点以及一个布尔值,它告诉墙壁是垂直的(真),还是水平的(布尔是错误的) 我的碰撞检测器遍历列表并检查它是否与其中之一发生碰撞,如果在一个方向(上、下、左、右)上检测到碰撞,则设置相应的布尔值 我的问题是,有时会有误报,也有误报,有些情况下,当它卡住而附近没有墙壁时,有时会穿过墙壁。 有人可以提出一些建议如何改进它吗? 有没有更好的方法来做到这一点? 这是我的代码

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;
                    }
                }
            }
        }

如果还不够,这里是我的整个存储库

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

经过一些工作,我想到了这里 感谢您的帮助

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;
                    }
                }
            }
        }
    }

可能有点复杂,但对我有用