我正在制作一个小程序,其中两个矩形围绕赛车跑道行驶。当我运行程序时,一切都按计划进行,我可以使用一个箭头键和另一个A,S,D,W移动轨道周围的矩形。问题是,如果我用箭头键移动一个,我试着按D同时向右移动另一个矩形,用箭头键移动的那个停止。目标是让他们能够同时移动。我该怎么办?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Race_Game
{
public partial class Form1 : Form
{
private int x1 = 24;
private int y1 = 16;
private int size1 = 115;
private int size2 = 50;
private Rectangle _rect1;
private int x2 = 24;
private int y2 = 74;
private int size3 = 115;
private int size4 = 50;
private Rectangle _rect2;
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Paint_1(object sender, PaintEventArgs e)
{
_rect1 = new Rectangle(x1, y1, size1, size2);
e.Graphics.FillRectangle(Brushes.Red, _rect1);
_rect2 = new Rectangle(x2, y2, size3, size4);
e.Graphics.FillRectangle(Brushes.Black, _rect2);
}
private void pictureBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
this.KeyPreview = true;
this.KeyDown += new KeyEventHandler(Form1_KeyDown);
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Right)
{
x1 += 15;
}
if (e.KeyData == Keys.Left)
{
x1 -= 15;
}
if (e.KeyData == Keys.Up)
{
y1 -= 15;
}
if (e.KeyData == Keys.Down)
{
y1 += 15;
}
if (e.KeyData == Keys.D)
{
x2 += 15;
}
if (e.KeyData == Keys.A)
{
x2 -= 15;
}
if (e.KeyData == Keys.W)
{
y2 -= 15;
}
if (e.KeyData == Keys.S)
{
y2 += 15;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Invalidate();
}
}
}
Visual Studio生成的设计代码:
namespace Race_Game
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// timer1
//
this.timer1.Enabled = true;
this.timer1.Interval = 1;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// pictureBox1
//
this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage")));
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(1944, 1066);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint_1);
this.pictureBox1.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.pictureBox1_PreviewKeyDown);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1916, 1053);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "Form1";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint_1);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.PictureBox pictureBox1;
}
}
答案 0 :(得分:3)
我决定做的是按下键来分配速度,然后按键上升到零速度。那并将x和y坐标组合成Point
和Size
个对象。
您可以独立且连续地移动框。
public partial class Form1 : Form
{
const int velocity = 15;
Point position_A = new Point(24, 16);
Point position_B = new Point(24, 74);
Size size_A = new Size(115, 50);
Size size_B = new Size(115, 50);
Size velocity_A = new Size(0, 0);
Size velocity_B = new Size(0, 0);
public Rectangle Shape_A
{
get
{
return new Rectangle(position_A, size_A);
}
}
public Rectangle Shape_B
{
get
{
return new Rectangle(position_B, size_B);
}
}
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Resize(object sender, EventArgs e)
{
pictureBox1.Refresh();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Red, Shape_A);
e.Graphics.FillRectangle(Brushes.Black, Shape_B);
}
private void timer1_Tick(object sender, EventArgs e)
{
this.position_A+=velocity_A;
this.position_B+=velocity_B;
pictureBox1.Refresh();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Debug.WriteLine($"KeyDown Code:{e.KeyCode}");
switch (e.KeyCode)
{
case Keys.Up:
this.velocity_A=new Size(velocity_A.Width, -velocity);
break;
case Keys.Down:
this.velocity_A=new Size(velocity_A.Width, +velocity);
break;
case Keys.Left:
this.velocity_A=new Size(-velocity, velocity_A.Height);
break;
case Keys.Right:
this.velocity_A=new Size(+velocity, velocity_A.Height);
break;
case Keys.W:
this.velocity_B=new Size(velocity_B.Width, -velocity);
break;
case Keys.S:
this.velocity_B=new Size(velocity_B.Width, +velocity);
break;
case Keys.A:
this.velocity_B=new Size(-velocity, velocity_B.Height);
break;
case Keys.D:
this.velocity_B=new Size(+velocity, velocity_B.Height);
break;
case Keys.Escape:
this.Close();
break;
}
pictureBox1.Invalidate();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
case Keys.Down:
this.velocity_A=new Size(velocity_A.Width, 0);
break;
case Keys.Right:
case Keys.Left:
this.velocity_A=new Size(0, velocity_A.Height);
break;
case Keys.W:
case Keys.S:
this.velocity_B=new Size(velocity_B.Width, 0);
break;
case Keys.A:
case Keys.D:
this.velocity_B=new Size(0, velocity_B.Height);
break;
}
}
}
答案 1 :(得分:1)
使用定时器通过WinAPI函数GetKeyState
定期轮询各个键的状态,而不是对按键事件做出反应。
对于以下示例设置,我使用具有两个NumericUpDown控件(“numericUpDownA”和“numericUpDownLeft”)和一个Timer“timerCheckKeyboard”的表单,间隔为100ms并设置为启用。 Timer具有OnClick事件处理程序“timerCheckKeyboard_Tick”。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("USER32.dll")]
static extern short GetKeyState(int nVirtKey);
private const int KEY_PRESSED = 0x8000;
private const int VK_W = (int)'W';
private const int VK_A = (int)'A';
private const int VK_S = (int)'S';
private const int VK_D = (int)'D';
private const int VK_LEFT = 0x25;
private const int VK_UP = 0x26;
private const int VK_RIGHT = 0x27;
private const int VK_DOWN = 0x28;
private bool IsKeyPressed(int key)
{
return (GetKeyState(key) & KEY_PRESSED) != 0;
}
private void timerCheckKeyboard_Tick(object sender, EventArgs e)
{
if (IsKeyPressed(VK_A))
{
numericUpDownA.Value++;
}
if (IsKeyPressed(VK_LEFT))
{
numericUpDownLeft.Value++;
}
}
}
按下A键时,NumericUpDownA控件中的值会增加。按下Cursor Left键时,NumericUpDownLeft控件中的值会增加。 您可以同时按“A”和“Cursor left”,并且NumericUpDown控件中的值都会增加。
请注意,当您的应用程序不是活动应用程序时按下键时,这甚至会起作用。因此,您可能希望在Timer-Tick-Event中首先测试它,或者在表单没有焦点时完全禁用计时器。 (表单的事件Activate
,Deactivate
)。