C# 如何在运行时移动游戏块(控件)?
我正在做一个简单的C#程序的游戏骑士巡回赛在C#艰难的方式学习所有我能的C#。我有一个棋盘和一个骑士棋子,骑士是一个定制面板,上面有骑士的照片 我试图做的是允许用户在运行时单击并拖动knight piece控件(与您在设计时移动控件放置控件的方式完全相同),但无论出于何种原因,我都会得到一些非常不希望的结果C# 如何在运行时移动游戏块(控件)?,c#,C#,我正在做一个简单的C#程序的游戏骑士巡回赛在C#艰难的方式学习所有我能的C#。我有一个棋盘和一个骑士棋子,骑士是一个定制面板,上面有骑士的照片 我试图做的是允许用户在运行时单击并拖动knight piece控件(与您在设计时移动控件放置控件的方式完全相同),但无论出于何种原因,我都会得到一些非常不希望的结果 private void KTmain_Load(object sender, EventArgs e) { boolKnightmoves = false;
private void KTmain_Load(object sender, EventArgs e)
{
boolKnightmoves = false;
}
private void kpcKnight_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left:
boolKnightmoves = true;
intCurMouseX = e.X;
intCurMouseY = e.Y;
break;
case MouseButtons.Right:
case MouseButtons.Middle:
case MouseButtons.XButton1:
case MouseButtons.XButton2:
case MouseButtons.None:
default:
boolKnightmoves = false;
break;
}
}
private void kpcKnight_MouseUp(object sender, MouseEventArgs e)
{
switch (e.Button)
{
case MouseButtons.Left:
boolKnightmoves = false;
break;
case MouseButtons.Right:
case MouseButtons.Middle:
case MouseButtons.XButton1:
case MouseButtons.XButton2:
case MouseButtons.None:
default:
boolKnightmoves = false;
break;
}
}
private void kpcKnight_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (boolKnightmoves)
{
txtTest.Text = e.X + ", " + e.Y;
txtTest.Text += Environment.NewLine + kpcKnight.Location;
int i = e.X == intCurMouseX ? 0 : e.X > intCurMouseX ? 1 : -1;
int j = e.Y == intCurMouseY ? 0 : e.Y > intCurMouseY ? 1 : -1;
txtTest.Text += Environment.NewLine + i.ToString() + ", " + j.ToString();
kpcKnight.Location = new Point(
kpcKnight.Location.X + i,
kpcKnight.Location.Y + j);//e.Y == intCurMouseY ? 0 : e.Y > intCurMouseY ? 1 : -1);
//e.X == intCurMouseX ? 0 : e.X > intCurMouseX ? 1 : -1,
intCurMouseX = e.X;
intCurMouseY = e.Y;
}
}
private void kpcKnight_MouseLeave(object sender, EventArgs e)
{
boolKnightmoves = false;
}
private void kpcKnight_LocationChanged(object sender, EventArgs e)
{
kpcKnight.Refresh();
}
我看不出这段代码不做同样事情的真正原因,但我显然遗漏了一些东西。当我点击骑士并移动它时,它的移动速度与鼠标的移动速度不同,它的移动速度要慢得多。当移动到你看不见的地方时,它也会褪色
我如何使骑士棋子以与窗体设计器中相同的方式移动,使棋子在棋盘上移动更有意义
任何协助都将不胜感激
我对代码进行了一点更新,看起来确实有所帮助,但动画方面仍然很不稳定,面板在移动和放置时会拾取一些背景 它是如何在表单设计器中如此顺利地完成的
private void kpcKnight_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (boolKnightmoves)
{
txtTest.Text = e.X + ", " + e.Y;
txtTest.Text += Environment.NewLine + kpcKnight.Location;
int x = kpcKnight.Location.X + e.X - intCurMouseX;
int y = kpcKnight.Location.Y + e.Y - intCurMouseY;
kpcKnight.Location = new Point(x, y);
kpcKnight.Refresh();
/*
int i = e.X == intCurMouseX ? 0 : e.X > intCurMouseX ? 1 : -1;
int j = e.Y == intCurMouseY ? 0 : e.Y > intCurMouseY ? 1 : -1;
txtTest.Text += Environment.NewLine + i.ToString() + ", " + j.ToString();
kpcKnight.Location = new Point(
kpcKnight.Location.X + i,
kpcKnight.Location.Y + j);//e.Y == intCurMouseY ? 0 : e.Y > intCurMouseY ? 1 : -1);
//e.X == intCurMouseX ? 0 : e.X > intCurMouseX ? 1 : -1,
intCurMouseX = e.X;
intCurMouseY = e.Y;*/
}
}
你为什么不把骑士的位置设置为鼠标移动法中的鼠标位置呢 比如:
kpcKnight.Location = new Point(e.X, e.Y)
显然,你可以通过知道骑士最初被点击的位置来让它移动得更好,并根据这个增量平滑地移动,而不会有最初的抖动 你为什么不把骑士的位置设置为鼠标移动法中的鼠标位置 比如:
kpcKnight.Location = new Point(e.X, e.Y)
显然,你可以通过知道骑士最初被点击的位置来让它移动得更好,并根据这个增量平滑地移动,而不会有最初的抖动 它的绘制速度非常慢,因为每次鼠标移动都会移动面板。这意味着表单本身需要多次重画,而一个完整的表单重画代价高昂 基本的解决方案是——不要经常改变面板的位置 我看到两种方法
我还有最后一个建议。除了制作任何动画外,还可以使用此选项。在功能上,它本身就满足了您的需求,但它可能不是您想要的。跟踪鼠标,并修改鼠标悬停在任何面板上的背景图像。在这种情况下,您需要查看
ImageList
,以及控件BackgroundImage
等简单属性。这可能很好,即使你有一个更好的动画工作。你可以很容易地用它来显示“骑士不能在这里移动”或“骑士已经在这里移动了”。因为它改变了你的组件而不是移动你的组件,这样做非常便宜,并且可以很容易地跟上你的鼠标移动。这可能足以暗示您想要的移动,并且它将教会您winforms的一些方面,这些方面比动画和GDI+渲染更重要和更常用。它的绘制速度非常慢,因为每次鼠标移动都会移动面板。这意味着表单本身需要多次重画,而一个完整的表单重画代价高昂
基本的解决方案是——不要经常改变面板的位置
我看到两种方法
private void Form1_Load(object sender, EventArgs e)
{
// perform this for all your PictureBox pieces:
this.ClipPictureBoxPiece(this.kpcKnight);
// ...
// ...
}
private void ClipPictureBoxPiece(PictureBox pb)
{
if (pb != null && pb.Image != null)
{
System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
using (Bitmap bmp = new Bitmap(pb.Image))
{
Color mask = bmp.GetPixel(0, 0);
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
if (!bmp.GetPixel(x, y).Equals(mask))
{
gp.AddRectangle(new Rectangle(x, y, 1, 1));
}
}
}
}
pb.Region = new Region(gp);
}
}