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;
取决于您使用的是什么:
- Windows 表格
- 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。
我是 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;
取决于您使用的是什么:
- Windows 表格
- 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。