我在C#中用Pong编写游戏,几行代码似乎有问题。这些线条在代码中,以确保球反弹回相反的方向。但它并没有真正起作用。它反弹,但它穿过桨的边缘。 除此之外,还有一个问题是我的球在向正确方向弹跳前一半左右进入右壁。
if (ball.Location.X > player1.Location.X
&& ball.Location.X + ball.width < player1.Location.X + player1.Width
&& ball.Location.Y + ball.Height > player1.Location.Y)
这应该确保球从桨叶反弹,但如前所述;它不会在整个桨上反弹。由于这句话中的错误编码,球会直接通过球拍的边缘,但我已经知道如何解决这个问题。它必须用正确的重叠代码做一些事情,球在球拍的整个长度上反弹。
if (ball.Location.X > player2.Location.X
&& ball.Location.X + ball.Width < player2.Location.X + player2.Width
&& ball.Location.Y < player2.Location.Y + player2.Height)
这句话完全相同。它穿过边缘,这意味着重叠有问题。应该由于某些X
和Y
(包括某些Width
和Height
某处)而导致什么。
最后但并非最不重要的是,有一点我的球在左墙的中途。但我不明白为什么这样的互动。
if (ball.Location.X + ball.Width > this.Width)
这应该是确保球的左侧位置(包括其Width
)不应超过玩游戏的屏幕的整个宽度...
非常感谢你阅读本文。希望有人能够帮助我解决这个问题。
这基本上是我的整个代码
namespace Pong_2
{
public partial class Form1 : Form
{
int playerSpeed = 7;
int p1Vel;
int p2Vel;
int bVelX = 1;
int bVelY = 1;
int scorePlayer1Int;
int scorePlayer2Int;
bool pause = false;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (!pause)
{
ball.Location = new Point(ball.Location.X + bVelX, ball.Location.Y + bVelY);
player1.Location = new Point(player1.Location.X + p1Vel, player1.Location.Y);
player2.Location = new Point(player2.Location.X + p2Vel, player2.Location.Y);
}
if (ball.Location.Y < 0)
{
scorePlayer1Int++;
ball.Location = new Point(this.Width / 2, this.Height / 2);
}
if (ball.Location.Y > this.Height)
{
scorePlayer2Int++;
ball.Location = new Point(this.Width / 2, this.Height / 2);
}
if (ball.Location.X > player1.Location.X && ball.Location.X + ball.Width < player1.Location.X + player1.Width && ball.Location.Y + ball.Height > player1.Location.Y)
{
bVelY *= -1;
}
if (ball.Location.X > player2.Location.X && ball.Location.X + ball.Width < player2.Location.X + player2.Width && ball.Location.Y < player2.Location.Y + player2.Height)
{
bVelY *= -1;
}
if (ball.Location.X < 0)
{
bVelX *= -1;
}
if (ball.Location.X + ball.Width > 984)
{
bVelX *= -1;
}
scorePlayer1.Text = scorePlayer1Int.ToString();
scorePlayer2.Text = scorePlayer2Int.ToString();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
p1Vel = 0;
}
else if (e.KeyCode == Keys.Left)
{
p1Vel = 0;
}
else if (e.KeyCode == Keys.D)
{
p2Vel = 0;
}
else if (e.KeyCode == Keys.A)
{
p2Vel = 0;
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Right)
{
p1Vel = playerSpeed;
}
else if (e.KeyCode == Keys.Left)
{
p1Vel = -playerSpeed;
}
else if (e.KeyCode == Keys.D)
{
p2Vel = playerSpeed;
}
else if (e.KeyCode == Keys.A)
{
p2Vel = -playerSpeed;
}
else if (e.KeyCode == Keys.P)
{
if (!pause)
{
pause = true;
}
else if (pause)
{
pause = false;
}
}
}
}
}
答案 0 :(得分:1)
此问题的最可能原因是球在帧之间移动的距离。如果你的球每帧都以足够高的速度移动,那么只有当球完全进入另一个物体时才能检测到碰撞。
如果您的球以每秒100像素的速度移动,并且您每秒绘制10帧,则球将一次跳过10个像素。如果左侧墙位于0
并且球的前一个X
位于5
,则下一帧的球将位于-5
。在足够高的速度和足够低的帧速率下,物体甚至可以直接穿过彼此而不会发生碰撞。
解决这个问题很棘手,它涉及一些复杂的数学运算来计算最后一帧和当前帧之间的确切碰撞点。如果你有很多物体,计算成本会很高,并且会减慢游戏速度。许多游戏将使用简单的碰撞检测,使用边界框来触发更昂贵的计算作为优化。
不幸的是,我在一个有过滤器的位置阻止我查找与游戏相关的网站(咳嗽)工作(咳嗽),但是这种类型的碰撞检测通常用于子弹之类的东西。您应该能够通过搜索这些类型的术语在互联网上找到一些东西。一旦我到了开放式互联网的某个地方,我就会更新这个答案。
更新
我实际上无法从我目前的位置验证this link,但这应该包含准确的帧间碰撞检测所需的数学和理论。
this question的答案也可能有所帮助。