简体   繁体   English

如何检测 c# 中两种不同形状的碰撞

[英]how to detect collisions of two different shapes in c#

I have two different shapes.我有两种不同的形状。 A rectangle which moves by using the keys up,down,right,left and a circle that is moving in a fixed position ( Up and down the Y axis).使用向上、向下、向右、向左键移动的矩形和在固定 position(Y 轴上下)中移动的圆圈。 I'm trying the detect the collision that if I move the rectangle into the circle the collision is to be detected and the game to stop.我正在尝试检测碰撞,如果我将矩形移动到圆圈中,则会检测到碰撞并停止游戏。 I have tried this code but it doesn't work:我已经尝试过这段代码,但它不起作用:

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

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

this is the full code.这是完整的代码。 Does anyone have any idea how to do it?有谁知道该怎么做?

      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();


    }



}

} }

Sorry, but from a brief look at your code, it doesn't make much sense to me.抱歉,但是从简要看一下您的代码,这对我来说没有多大意义。 A recursive collision-function which never returns an actual value.一个从不返回实际值的递归碰撞函数。 What is the idea behind that?这背后的想法是什么? Does it even compile?它甚至可以编译吗?

Having said that, the specific collision detection you are after isn't that complicated.话虽如此,您所追求的特定碰撞检测并不复杂。 Here is the general way to do it.这是执行此操作的一般方法。

If you know from the rectangle the coordinates of the four corners and from the circle the coordinate of the center and the length of the radius.如果你从矩形知道四个角的坐标,从圆知道中心的坐标和半径的长度。 All you have to do is calculate the distance (with the pythagoras formula) from each rectangle-corner to the center of the circle.您所要做的就是计算从每个矩形角到圆心的距离(使用毕达哥拉斯公式)。 If one or more of these distances is less than the radius of the circle you have a collision.如果这些距离中的一个或多个小于圆的半径,则会发生碰撞。

UPDATE更新

after giving this problem some more thought I now see there are some cases when a rectangle and circle collide which are not covered by my method.在对这个问题进行了更多思考之后,我现在看到在某些情况下矩形和圆形发生碰撞,而我的方法没有涵盖这些情况。 However I still think my method is a good way to start.但是我仍然认为我的方法是一个很好的开始方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EmguCV C#:FindContours() 检测不同形状 - EmguCV C# : FindContours() to detect different shapes 如何在 Unity3D C# 中旋转脊柱时检测碰撞? - How to detect collisions while spine is rotating in Unity3D C#? 如何在统一C#中针对不同形状重用脚本 - How to reuse a script for different shapes in unity C# Unity 3D如何使具有不同对象的触发器/碰撞发生不同的事情? C# - Unity 3D how to make different things happen for triggers/collisions with different objects? C# 如何检测两个形状是否在 WPF 中发生碰撞 - How to detect if two shapes collide in WPF C#:当链接到两个不同的对象时,如何检测谁是上下文菜单菜单项的调用者? - C#: How to detect who is the caller of a context menu's menu item when linked to two different objects? 如何检测两个碰撞器/两个触发器是否发生碰撞 - Unity c# - How to detect if two colliders/two triggers are colliding - Unity c# 如何检测与实例化预制件的冲突 - How to detect for collisions with instantiated prefabs C#XNA精确碰撞? - C# XNA Precise Collisions? 如何使用自定义 hash function 检查 C# 字典中是否存在冲突? - How to check if there are collisions in C# Dictionary with custom hash function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM