C#面板碰撞移动

本文关键字:移动 碰撞 | 更新日期: 2023-09-27 18:24:54

我是C#和Winforms的新手,尝试制作一个移动面板。它应该向右移动,直到我的窗口尽头,然后向左返回。它应该从一边弹到另一边。但经过数小时的尝试,唯一发生的事情是它向左移动并停止。

使用此表单工具:

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;

C#面板碰撞移动

取决于您使用的内容:

  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。