我有两个不同的形状。一个矩形,使用键向上,向下,向右,向左移动和一个圆,在一个固定的位置(向上和向下的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();
}
}
}
对不起,但从你的代码来看,我觉得没什么意义。一个递归的碰撞函数,从来没有返回一个实际的值。这背后的想法是什么?它甚至可以编译吗?
说了这么多,你想要的具体碰撞检测并不复杂。下面是一般的方法。
如果你从矩形中知道四个角的坐标,从圆中知道中心的坐标和半径的长度。你所要做的就是计算从每个矩形角到圆心的距离(用pythagoras公式)。如果其中一个或多个距离小于圆的半径,你就会发生碰撞。
更新
在对这个问题进行了更多的思考之后,我现在发现有一些情况下,当矩形和圆相撞时,我的方法并没有涵盖这些情况。不过我还是认为我的方法是一个好的开始。