现在,我正在制作游戏和角色以移动玩家。我只是编程的初学者。
有8个按钮,每个按钮都朝着一个方向。例如,这是我的程序
private void btnUp_Click(object sender, EventArgs e)
{
//move up
y = y - 1;
MovePlayer();
UpdateLabelLocation();
}
public void MovePlayer()
{
picPlayer.Location = new Point(x, y);
}
public void UpdateLabelLocation()
{
lblLocation.Text = "Location: (" + x + ", " + y + ")";
}
我想在上下,向下,左或右键时使其移动。另外,如果可能的话,我想做到这一点,以便当我同时向右按下时,它会触发这一点:
private void btnRightUp_Click(object sender, EventArgs e)
{
//move player
y = y - 1;
x = x + 1;
MovePlayer();
UpdateLabelLocation();
}
我感谢帮助。
您本质上要做的是创建自己的简单游戏引擎。正如评论员所指出的那样,最好使用现有的游戏引擎(例如Unity)。
也就是说,如果您真的想继续这样做,我强烈建议您将Click
处理程序中的代码移至方法中。这减少了代码重复。即。
private void DownButton_Click(...)
{
MovePlayer(0, 1);
}
private void UpButton_Click(...)
{
MovePlayer(0, -1);
}
public void MovePlayer(float xStep, float yStep)
{
x += xStep;
y += yStep;
MovePlayer();
UpdateLabelLocation();
}
要向下移动并离开,您会致电MovePlayer(-1, 1);
要向上移动,您要致电MovePlayer(1, -1);
接下来,您需要响应按键事件。即。
public void Form_KeyPress(object sender, KeyPressEventArgs args)
{
switch (args.KeyChar) {
case 'a': // Left
args.Handled = true;
MovePlayer(-1, 0);
break;
case 'd': // Right
args.Handled = true;
MovePlayer(1, 0);
break;
case 'w': // Up
args.Handled = true;
MovePlayer(0, -1);
break;
case 's': // Down
args.Handled = true;
MovePlayer(0, 1);
break;
}
}
请注意,如果您有另一个接受键盘输入(例如TextBox
)的控件,它将截取键按。要解决这个问题,请使用键盘浏览迫使窗口首先预览输入。args.Handled = true
阻止了代码后从路由到子控制的事件。
不幸的是,Winforms并未同时记录多个键,因此仅使用按键不足以处理角移动。您可以通过连接到键盘和钥匙来解决这个问题,但这比价值还多。
。这是一个更强大的解决方案。请记住以下条件不是安全的,因此,如果您打算引入其他线程,则需要使用适当的锁定。
HashSet<KeyCode> state = new HashSet<KeyCode>();
float speed = 120; // 120 pixels/second.
private void Form_KeyDown(object sender, KeyEventArgs args)
{
var key = args.KeyCode;
state.Add(key);
// Fire pressed when a key was up.
if (!state.Contains(key)) {
state.Add(key);
OnKeyPressed(key);
}
}
private void Form_KeyUp(object sender, KeyEventArgs args)
{
var key = args.KeyCode;
state.Remove(key);
// Fire release when a key was down.
if (state.Contains(key)) {
state.Remove(key);
OnKeyReleased(key);
}
}
// Runs when key was up, but pressed just now.
private void OnKeyPressed(KeyCode key)
{
// Trigger key-based actions.
}
// Runs when key was down, but released just now.
private void OnReleased(KeyCode key)
{
// Trigger key-based actions, but on release instead of press.
}
private bool IsDown(KeyCode key)
{
return state.Contains(key);
}
// Trigger this periodically, at least 20 times a second(ideally 60).
// An option to get you started is to use a windows timer, but
// eventually you'll want to use high precision timing instead.
private void Update()
{
var deltaTime = // Calculate the seconds that have passed since the last update.
// Describing it is out of the scope of this answer, but see the links below.
// Determine horizontal direction. Holding both
// A & D down cancels movement on the x-axis.
var directionX = 0;
if (IsDown(KeyCode.A)) {
directionX--;
}
if (IsDown(KeyCode.D)) {
directionX++;
}
// Determine vertical direction. Holding both
// W & S down cancels movement on the y-axis.
var directionY = 0;
if (IsDown(KeyCode.W)) {
directionY--;
}
if (IsDown(KeyCode.S)) {
directionY++;
}
// directionX & directionY should be normalized, but
// I leave that as an exercise for the reader.
var movement = speed * deltaTime;
var offsetX = directionX * movement;
var offsetY = directionY * movement;
MovePlayer(offsetX, offsetY);
}
您可以看到,涉及很多。如果您想要更多细粒度的时机,请查看本文。最终,您需要过渡到游戏循环,但这是此答案范围的另一个话题。