C# 面板移动碰撞

C# panel move with collision

我是 C# 和 Winforms 的新手,尝试制作一个移动面板。它应该向右移动直到我的 window 结束,然后向左移动。它应该从一侧弹到另一侧。但经过几个小时的尝试,唯一发生的事情是它向左移动并停止了。

使用此表单工具:

Timer = tmrMoveBox (interval: 50)
Panel = pnlBox
Label = lblXY (for showing the X and Y coordinates in the form)

这是我第一次最好的尝试:

private void tmrMoveBox(object sender, EventArgs e)
{
    if (pnlBox.Location.X <= 316)
    {
        for (int i = 0; i <= 316; i++)
        {
            pnlBox.Location = new Point(
                pnlBox.Location.X + 2, pnlBox.Location.Y);
            string BoxLocationToString = pnlBox.Location.ToString();
            lblXY.Text = BoxLocationToString;
        }
    }

    else if (pnlBox.Location.X >= 0)
    {
        for (int i = 0; i >= 316; i++)
        {
            pnlBox.Location = new Point(
                pnlBox.Location.X - 2, pnlBox.Location.Y);
            string BoxLocationToString = pnlBox.Location.ToString();
            lblXY.Text = BoxLocationToString;
        }
    }
}

第二个最好的尝试:

private void tmrMoveBox(object sender, EventArgs e)
{
    int runBox = 1;

    if(runBox == 1)
    {
        while (pnlBox.Location.X <= 316)
        {
            pnlBox.Location = new Point(
                pnlBox.Location.X + 2, pnlBox.Location.Y);
            string BoxLocationString = pnlBox.Location.ToString();
            lblXY.Text = BoxLocationString;
            runBox = 0;
        }
    }
    else
    {
        while(pnlBox.Location.X > 0)
        {
            pnlBox.Location = new Point(
            pnlBox.Location.X - 2, pnlBox.Location.Y);
            string BoxLocationString = pnlBox.Location.ToString();
            lblXY.Text = BoxLocationString;
            runBox = 1;
        }
    }
}

也尝试使用 while 循环,但随后面板就消失了。 我不是专家,只是将这个移动面板作为我自己的目标。希望有人能给我提示。

编辑:

Form1.Designer.cs

 this.timer1.Interval = 50;
 this.timer1.Tick += new System.EventHandler(this.tmrMoveBox);
 this.timer1.Start();
 this.timer1.Step = 2;

取决于您使用的是什么:

  1. Windows 表格
  2. WPF

创建一个 Timer 并订阅 Tick 事件。此外,您应该创建新的 int 属性 Step.

1. Windows 形式:

System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
int Step;

Form1 () 
{
     InitializeComponent()
    ....
     t.Interval = 15000; // specify interval time as you want
     t.Tick += new EventHandler(timer_Tick); 
     t.Start();

     this.Step = 2; 
}

并在 ticks 事件处理程序中放入您的逻辑,没有 while

void timer_Tick(object sender, EventArgs e)
{
        if (pnlBox.Location.X >= 316)
        {
            Step = -2;
        }
        if (pnlBox.Location.X <= 0) 
        {
            Step = 2;
        }

        pnlBox.Location = new Point(
        pnlBox.Location.X + Step , pnlBox.Location.Y);
        string BoxLocationString = pnlBox.Location.ToString();
        lblXY.Text = BoxLocationString;
}

所以你的盒子会在每一个计时器滴答声中移动一步。

1. WPF:

由于System.Windows.Forms.Timer不可用,您可以使用System.Windows.Threading.DispatcherTimer:

using System.Windows.Threading;

DispatcherTimer t = new DispatcherTimer();
t.Interval = new TimeSpan(0, 0, 15); // hours, minutes, seconds (there are more constructors)
t.Tick += Timer_Tick;
t.Start();

这是我使用的代码:

int d= 10;
private void timer1_Tick(object sender, EventArgs e)
{
    //Reverse the direction of move after a collision
    if(panel1.Left==0 || panel1.Right==this.ClientRectangle.Width)
        d = -d;

    //Move panel, also prevent it from going beyond the borders event a point.
    if(d>0)
        panel1.Left = Math.Min(panel1.Left + d, this.ClientRectangle.Width - panel1.Width);
    else
        panel1.Left = Math.Max(panel1.Left + d, 0);
}

注:

要检查碰撞你应该检查:

  • 与左侧碰撞:panel1.Left==0
  • 与右边的碰撞:panel1.Right==this.ClientRectangle.Width

你不应该让面板超出边界一点,所以:

  • 您面板左侧的最大允许值为 this.ClientRectangle.Width - panel1.Width

  • 您面板左侧允许的最小值是 0

此外,最好使用 this.ClientRectangle.Width 而不是使用硬编码 316。