[英]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.