我正在用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;
}
}
}
}
}
最佳答案
出现此问题的最可能原因是球在框架之间移动的距离。如果您的球每帧以足够高的速度运动,则很可能只有在球完全位于另一个物体内部时才能检测到碰撞。
如果您的球以每秒100像素的速度移动,并且每秒绘制10帧,则该球将一次跳跃10像素。如果左壁在0
,并且球的前一个X
在5
,则下一帧的球将在-5
。在足够高的速度和足够低的帧速率下,对象甚至有可能彼此正确通过而不会发生碰撞。
解决这个问题很棘手,它涉及一些复杂的数学运算来计算最后一帧与当前帧之间的准确碰撞点。如果您有很多对象,则计算起来可能会很昂贵,并且会降低游戏速度。许多游戏将使用边界框进行简单的碰撞检测,以触发更昂贵的计算作为优化。
不幸的是,我所在的位置有一个过滤器,阻止我查找与游戏相关的网站,(咳嗽)工作(咳嗽),但是这种碰撞检测通常用于子弹之类的东西。通过搜索这些类型的术语,您应该能够在互联网上找到一些东西。一旦开放互联网,我将更新此答案。
更新资料
我实际上无法从当前位置验证this link,但这应该包含准确进行帧间冲突检测所需的数学和理论。
this question的答案也可能会有所帮助。
关于c# - 球在桨/壁上无法正确弹跳,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50815785/