我在VS Express 2010中使用C#窗口表单应用程序。为了学习,我正在玩一些代码。我有一个表单对象,我想通过按键不断向一个方向移动 - 它的原始代码工作正常。
在尝试通过将"移动"代码移动到函数中来整理它的过程中,代码不再像以前一样工作。现在,我的对象不再从当前位置沿所选方向移动,而是在每次按下某个键时重置其位置。我想知道为什么会发生这种情况,因为我所做的更改绝对是最小的。请参阅代码:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
当我将 while 循环移动到移动函数中时,变量 X 和 Y 在每次按键时都会重置为 0。 此代码如下所示:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
direction = 4;
}
if (e.KeyCode == Keys.Up)
{
direction = 2;
}
if (e.KeyCode == Keys.Right)
{
direction = 3;
}
if (e.KeyCode == Keys.Left)
{
direction = 1;
}
movement(X, Y, direction);
}
我觉得我在这里错过了一些明显的东西,但我不明白为什么它的行为不同。感谢您的任何帮助:)
编辑 1:移动函数的代码:
movement(int X, int Y, int direction)
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1)
{
X = X - 1;
}
else if (direction == 2)//up
{
Y = Y - 1;
}
else if (direction == 3)
{
X = X + 1;
}
else if (direction == 4)//down
{
Y = Y + 1;
}
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
我想您的movement
方法更改了作为参数提供的X
和Y
。但是,参数X
和Y
是"按值"传递的,而不是"按引用"传递的。
如果你想做到这一点,你要么必须使用类变量,并删除方法调用中的参数,要么使用ref
,我将演示:
movement(ref X, ref Y, direction);
和:
private void movement(ref int X, ref int Y, int direction)
{ }
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
可以重写:
private void SetDirection(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down) direction = 4;
else if (e.KeyCode == Keys.Up) direction = 2;
else if (e.KeyCode == Keys.Right) direction = 3;
else if (e.KeyCode == Keys.Left) direction = 1;
}
private void ApplyMovement()
{
while (direction != 0)
{
Application.DoEvents();
if (direction == 1) X--;
else if (direction == 2) Y--;
else if (direction == 3) X++;
else if (direction == 4) Y++;
Thread.Sleep(100);
label1.Location = new Point(X, Y);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
SetDirection(e);
ApplyMovement();
}
你必须明白变量X
、Y
和direction
是类成员,因此可以从类中的任何位置访问它们,当你调用movement(X, Y, direction)
时,movement
使用这些变量的副本,所以当你在movement
方法中执行X = X + 1
时,你实际上并没有改变类的X
值, 但仅限于它的副本。这意味着变量 X 和 Y(即.class成员)不会在每次按键时重置为 0。事实上,他们永远不会被设置为其他任何东西。
请注意,您也可以使用switch
语句而不是所有这些语句if
。
switch (direction)
{
case 1: X--; break; // left
case 2: Y--; break; // up
case 3: X++; break; // right
case 4: Y++; break; // down
}