如何在c#中检测两个不同形状的碰撞?

问题描述 投票:0回答:1

我有两个不同的形状。一个矩形,使用键向上,向下,向右,向左移动和一个圆,在一个固定的位置(向上和向下的Y轴)移动。我试图检测的碰撞,如果我移动矩形到圆圈的碰撞是被检测到,游戏停止。我已经尝试了这个代码,但它不工作。

        public bool collision()
    {
        if (PlayerPositionX == EnemyPosX & PlayerPositionY == EnemyPosY )
        {
            _movementTimer.Stop();
        }

        if (collision()==true)
        {
            _movementTimer.Stop();
        }
        return collision();
    }

这是完整的代码. 有谁知道如何做到这一点?

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      using System.Timers;
      using System.Drawing.Imaging;
      using Timer = System.Windows.Forms.Timer;

     namespace prot_4
      {

public partial class Form1 : Form
{




    int PlayerPositionX = 40, PlayerPositionY = 200, width = 40, height = 40;   // player

    int EnemyWidth  = 40, EnemyHeight  = 40, EnemyPosX  = 100, EnemyPosY  = 0, EnemySpeedX  = 0, EnemySpeedY  = 20;   // enemy
    int EnemyWidth2 = 40, EnemyHeight2 = 40, EnemyPosX2 = 200, EnemyPosY2 = 400, EnemySpeedX2 = 0, EnemySpeedY2 = 20;   // enemy2
    int EnemyWidth3 = 40, EnemyHeight3 = 40, EnemyPosX3 = 300, EnemyPosY3 = 0, EnemySpeedX3 = 0, EnemySpeedY3 = 20;   // enemy3
    int EnemyWidth4 = 40, EnemyHeight4 = 40, EnemyPosX4 = 400, EnemyPosY4 = 400, EnemySpeedX4 = 0, EnemySpeedY4 = 20;   // enemy4
    int EnemyWidth5 = 40, EnemyHeight5 = 40, EnemyPosX5 = 500, EnemyPosY5 = 0, EnemySpeedX5 = 0, EnemySpeedY5 = 20;   // enemy5
    int EnemyWidth6 = 40, EnemyHeight6 = 40, EnemyPosX6 = 600, EnemyPosY6 = 400, EnemySpeedX6 = 0, EnemySpeedY6 = 20;   // enemy6







    private bool moveUp, moveDown, moveLeft, moveRight;



    private System.Windows.Forms.Timer _movementTimer = new Timer { Interval = 100 };



    public bool collision()
    {
        if (PlayerPositionX == EnemyPosX & PlayerPositionY == EnemyPosY )
        {
            _movementTimer.Stop();
        }

        if (collision()==true)
        {
            _movementTimer.Stop();
        }
        return collision();
    }



    public Form1()
    {
        InitializeComponent();
        _movementTimer.Tick += movementTimer_Tick;

    }
    private void movementTimer_Tick(object sender , EventArgs e)
    {
        playerControls();

    }
    //Form1_KeyDown

    private void playerControls()   // Player controls
    {

        if (moveRight)
        {
            PlayerPositionX += 5;
            if (PlayerPositionX >= 800 - width)
            {
                PlayerPositionX = 800 - width;
            }
        }
        if (moveLeft)
        {
            PlayerPositionX -= 5;
            if (PlayerPositionX <= -43 + width)
            {
                PlayerPositionX = -43 + width;
            }
        }
        if (moveUp)
        {
            PlayerPositionY -= 5;
            if (PlayerPositionY <= 0)
            {
                PlayerPositionY = 0;
            }
        }
        if (moveDown)
        {
            PlayerPositionY += 5;
            if (PlayerPositionY >= 410)
            {
                PlayerPositionY = 410;
            }
        }

    }




   public void Form1_KeyDown(object sender, KeyEventArgs e)
    {






        switch (e.KeyCode)
        {
            case Keys.Up:
                moveUp = true;
                break;
            case Keys.Down:
                moveDown = true;
                break;
            case Keys.Left:
                moveLeft = true;
                break;
            case Keys.Right:
                moveRight = true;
                break;
        }
        playerControls();
        _movementTimer.Start();



    }

    public void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Up:
                moveUp = false;
                break;
            case Keys.Down:
                moveDown = false;
                break;
            case Keys.Left:
                moveLeft = false;
                break;
            case Keys.Right:
                moveRight = false;
                break;
        }
        if (!(moveUp || moveDown || moveLeft || moveRight ))
        {
            _movementTimer.Stop();
        }





    }

    public void player(object sender, PaintEventArgs e)                                               // drawing the player 
    {
        e.Graphics.SmoothingMode =
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
        e.Graphics.Clear(this.BackColor);
        e.Graphics.FillRectangle((Brushes.Blue), PlayerPositionX, PlayerPositionY, width, height);
        e.Graphics.DrawRectangle(Pens.Black,
          PlayerPositionX, PlayerPositionY,
          width, height);

        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX, EnemyPosY,
            EnemyWidth, EnemyHeight);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX, EnemyPosY,
            EnemyWidth, EnemyHeight);


        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX2, EnemyPosY2,
            EnemyWidth2, EnemyHeight2);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX2, EnemyPosY2,
            EnemyWidth2, EnemyHeight2);



        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX3, EnemyPosY3,
            EnemyWidth3, EnemyHeight3);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX3, EnemyPosY3,
            EnemyWidth3, EnemyHeight3);

        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX4, EnemyPosY4,
            EnemyWidth, EnemyHeight);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX4, EnemyPosY4,
            EnemyWidth4, EnemyHeight4);

        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX5, EnemyPosY5,
            EnemyWidth5, EnemyHeight5);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX5, EnemyPosY5,
            EnemyWidth5, EnemyHeight5);

        e.Graphics.SmoothingMode =                                                                //drawing the enemy          
       System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


        e.Graphics.FillEllipse(Brushes.Red,
            EnemyPosX6, EnemyPosY6,
            EnemyWidth6, EnemyHeight6);

        e.Graphics.DrawEllipse(Pens.Black,
            EnemyPosX6, EnemyPosY6,
            EnemyWidth6, EnemyHeight6);
    }
    private void PlayerMoveTimer(object sender, EventArgs e )                      //  timer 2
    {

        Invalidate();
    }



    private void moveTimer(object sender, EventArgs e)   // timer
    {

        //update coorndinates
        EnemyPosX += EnemySpeedX;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX < 0 ||
                EnemyPosX + EnemyWidth > this.ClientSize.Width
                )
        {
            EnemySpeedX = -EnemySpeedX;
        }
        EnemyPosY -= EnemySpeedY;
        if (EnemyPosY < 0 ||
                EnemyPosY + EnemyHeight > this.ClientSize.Height
                )
        {
            EnemySpeedY = -EnemySpeedY;
        }



        EnemyPosX2 += EnemySpeedX2;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX2 < 0 ||
                EnemyPosX2 + EnemyWidth2 > this.ClientSize.Width
                )
        {
            EnemySpeedX2 = -EnemySpeedX2;
        }
        EnemyPosY2 += EnemySpeedY2;
        if (EnemyPosY2 < 0 ||
                EnemyPosY2 + EnemyHeight2 > this.ClientSize.Height
                )
        {
            EnemySpeedY2 = -EnemySpeedY2;
        }


        EnemyPosX3 += EnemySpeedX3;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX3 < 0 ||
                EnemyPosX3 + EnemyWidth3 > this.ClientSize.Width
                )
        {
            EnemySpeedX3 = -EnemySpeedX3;
        }
        EnemyPosY3 -= EnemySpeedY3;
        if (EnemyPosY3 < 0 ||
                EnemyPosY3 + EnemyHeight3 > this.ClientSize.Height
                )
        {
            EnemySpeedY3 = -EnemySpeedY3;
        }

        EnemyPosX4 += EnemySpeedX4;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX4 < 0 ||
                EnemyPosX4 + EnemyWidth4 > this.ClientSize.Width
                )
        {
            EnemySpeedX4 = -EnemySpeedX4;
        }
        EnemyPosY4 += EnemySpeedY4;
        if (EnemyPosY4 < 0 ||
                EnemyPosY4 + EnemyHeight4 > this.ClientSize.Height
                )
        {
            EnemySpeedY4 = -EnemySpeedY4;
        }

        EnemyPosX5 += EnemySpeedX5;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX5 < 0 ||
                EnemyPosX5 + EnemyWidth5 > this.ClientSize.Width
                )
        {
            EnemySpeedX = -EnemySpeedX;
        }
        EnemyPosY5 -= EnemySpeedY5;
        if (EnemyPosY5 < 0 ||
                EnemyPosY5 + EnemyHeight5 > this.ClientSize.Height
                )
        {
            EnemySpeedY5 = -EnemySpeedY5;
        }

        EnemyPosX6 += EnemySpeedX6;                                                          // how the enemy moves    //timer 1
        if (EnemyPosX6 < 0 ||
                EnemyPosX6 + EnemyWidth6 > this.ClientSize.Width
                )
        {
            EnemySpeedX6 = -EnemySpeedX6;
        }
        EnemyPosY6 += EnemySpeedY6;
        if (EnemyPosY6 < 0 ||
                EnemyPosY6 + EnemyHeight6 > this.ClientSize.Height
                )
        {
            EnemySpeedY6 = -EnemySpeedY6;
        }

        //refresh windows
        Invalidate();


    }



}

}

c# forms oop collision
1个回答
0
投票

对不起,但从你的代码来看,我觉得没什么意义。一个递归的碰撞函数,从来没有返回一个实际的值。这背后的想法是什么?它甚至可以编译吗?

说了这么多,你想要的具体碰撞检测并不复杂。下面是一般的方法。

如果你从矩形中知道四个角的坐标,从圆中知道中心的坐标和半径的长度。你所要做的就是计算从每个矩形角到圆心的距离(用pythagoras公式)。如果其中一个或多个距离小于圆的半径,你就会发生碰撞。

更新

在对这个问题进行了更多的思考之后,我现在发现有一些情况下,当矩形和圆相撞时,我的方法并没有涵盖这些情况。不过我还是认为我的方法是一个好的开始。

© www.soinside.com 2019 - 2024. All rights reserved.