C# 球在球拍/墙上弹得不好

C# 球在球拍/墙上弹得不好,c#,pong,C#,Pong,我正在用C#编写一个乒乓球游戏,几行代码似乎有问题。这些线在代码中,以确保球反弹回相反方向。但它并没有真正起作用。它会反弹,但会穿过桨的边缘。 除此之外,还有一个问题,我的球在反弹到正确方向之前,会进入右墙大约一半的地方 if (ball.Location.X > player1.Location.X && ball.Location.X + ball.width < player1.Location.X + player1.Width &

我正在用C#编写一个乒乓球游戏,几行代码似乎有问题。这些线在代码中,以确保球反弹回相反方向。但它并没有真正起作用。它会反弹,但会穿过桨的边缘。 除此之外,还有一个问题,我的球在反弹到正确方向之前,会进入右墙大约一半的地方

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)
这应该确保球的左侧位置(包括它的
宽度
)不应超过游戏所在屏幕的整个宽度

无论如何,谢谢你阅读这篇文章。希望有人能帮我解决这个问题

这基本上是我的全部代码

namespace Pong_2
{
公共部分类Form1:Form
{
int playerSpeed=7;
int p1Vel;
int p2Vel;
int bVelX=1;
int bVelY=1;
int记分员1分;
int scorePlayer2Int;
布尔暂停=假;
公共表格1()
{
初始化组件();
}
私有无效计时器1_刻度(对象发送方,事件参数e)
{
如果(!暂停)
{
ball.Location=新点(ball.Location.X+bVelX,ball.Location.Y+bVelY);
player1.Location=新点(player1.Location.X+p1Vel,player1.Location.Y);
player2.Location=新点(player2.Location.X+p2Vel,player2.Location.Y);
}
if(球位置Y<0)
{
scorePlayer1Int++;
ball.Location=新点(this.Width/2,this.Height/2);
}
如果(球位置Y>此高度)
{
scorePlayer2Int++;
ball.Location=新点(this.Width/2,this.Height/2);
}
if(ball.Location.X>player1.Location.X&&ball.Location.X+ball.Widthplayer1.Location.Y)
{
bVelY*=-1;
}
if(ball.Location.X>player2.Location.X&&ball.Location.X+ball.Width984)
{
bVelX*=-1;
}
scorePlayer1.Text=scorePlayer1Int.ToString();
scorePlayer2.Text=scorePlayer2Int.ToString();
}
私有void Form1\u KeyUp(对象发送方,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;
}
}
私有void Form1\u KeyDown(对象发送方,KeyEventArgs e)
{
if(e.KeyCode==Keys.Right)
{
p1Vel=玩家速度;
}
else if(e.KeyCode==Keys.Left)
{
p1Vel=-玩家速度;
}
else if(e.KeyCode==Keys.D)
{
p2Vel=球员速度;
}
else if(e.KeyCode==Keys.A)
{
p2Vel=-运动员速度;
}
else if(e.KeyCode==Keys.P)
{
如果(!暂停)
{
暂停=正确;
}
否则如果(暂停)
{
暂停=错误;
}
}
}
}
}

此问题最可能的原因是球在帧之间移动的距离。如果你的球在每一帧都以足够高的速度移动,那么很可能只有当球在另一个物体内部时,碰撞才会被检测到

如果球以每秒100像素的速度移动,并且每秒绘制10帧,则球将一次跳跃10像素。如果左墙位于
0
,而球的上一个
X
位于
5
,则下一帧将使球位于
-5
。在足够高的速度和足够低的帧速率下,对象甚至可以在不发生碰撞的情况下直接通过彼此

解决这个问题很棘手,需要一些复杂的数学来计算最后一帧和当前帧之间的精确碰撞点。如果你有很多对象,计算起来会很昂贵,并且会减慢你的游戏速度。许多游戏将使用简单的碰撞检测,使用边界框,以触发更昂贵的优化计算

不幸的是,我所在的位置有一个过滤器,阻止我查找与游戏相关的网站,(cough)work(cough),但这种类型的碰撞检测通常用于子弹之类的东西。通过搜索这些类型的术语,你应该能够在互联网上找到一些东西。一旦我找到一个开放互联网的地方,我会更新这个答案


更新

实际上,我无法从当前位置进行验证,但这应该包含精确帧间碰撞检测所需的数学和理论


这个问题的答案也可能有帮助。

球的“速度”是多少。(关于向量)?我想,你是这样更新球的:
void Update(){ball.Location.X+=50;}
还是类似的东西?你介意分享你的球的相关部分吗?请注意:你应该考虑使用<代码>矩形> /Cord>类型类来管理你的实体(球、桨等)的边界框。您可以使用一条简单的线,如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)
if (ball.Location.X + ball.Width > this.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;
                }
            }
        }
    }
}