我必须在2条(图像)之间绘制一个移动的箭头图像(使用C#代码VS2008) . 我尝试了两种方法:
-
通过连接点绘制箭头图 . 然后不断改变x,y坐标 .
-
制作箭头图像,然后不断改变其位置 .
问题是闪烁 . 每当我移动箭头图像(或重绘点)附近的图像(实际上很少有其他图像作为条形图)闪烁 . 我试图调用invalidate(rect),认为它只会重绘给定的矩形,但是一旦箭头图像越过这些条形图,一切都会闪烁 . 这看起来不太好 . 如何以平滑的方式移动此箭头图像 . PLS . 建议 . 或者我应该采用另一种方法?
//代码:**
public partial class Form1:Form {private Bitmap bitmapAntenna; private Bitmap bitmapArrow;
public Form1()
{
bitmapAntenna = new Bitmap("D:\\AntennaBar.JPG");
bitmapArrow = new Bitmap("D:\\Arrow.JPG");
}
private void DrawAntennaImages(int antennaNo)
{
Graphics grph = this.CreateGraphics();
if (1 == antennaNo)
{
grph.DrawImage(bitmapAntenna, new RectangleF(350, 300, bitmapAntenna.Width*(1.00F), bitmapAntenna.Height*(1.00F))) ;
}
else
grph.DrawImage(AntennaImage, new Point(550, 300));
}
private void DrawArrowImages(int X)
{
Graphics grph = this.CreateGraphics();
grph.DrawImage(bitmapArrow, new Point(380 + X, 350));
}
private void PaintHandler(Object sender, System.Windows.Forms.PaintEventArgs e)
{
DrawAntennaImages(1);
DrawAntennaImages(2);
}
private void button_Click(object sender, EventArgs e)
{
for (int i = 1; i < 40; i++)
{
// Note: first draw antenna 1 image, arrow image then antenna 2 image so that arrow will overlap
// only antenna 1 image only.
DrawAntennaImages(1); // Draw Antenn 1 image
DrawArrowImages(i * 2); // Draw Arrow image
DrawAntennaImages(2); // Draw Antenn 2 image
System.Threading.Thread.Sleep(25); // Sleep before drawing next time ..
}
this.Invalidate(); // If I don't call this, arrow image does not elope after last draw
}
}
//在设计师
this.Paint = new System.Windows.Forms.PaintEventHandler(this.PaintHandler);
//代码*
谢谢RPS
4 回答
只需为表单启用双缓冲即可
或者你画的控件 .
Here is some more information关于Windows窗体和GDI中的双缓冲 .
哦,顺便说一下:WPF中不存在这类问题 . 在图形质量和易用性方面(对于像你正在做的那样直截了当的事情),WPF远远优于Windows窗体和GDI .
这是你如何在WPF / XAML中绘制移动的恐怖:
我在这里假设WinForms:
你尝试过使用double buffering吗?
你可以尝试implement your own double buffering .
不要指望奇迹在这里; WinForms从来没有打算做过这样的事情 .
如果您有
PictureBox
尝试设置DoubleBuffering = true
. 如果此闪烁仍然存在,请在屏幕上绘制Bitmap
之前将所有内容绘制到Bitmap
上 .我们在WinForms中做动画,并且不会因为我们的技术而出现任何闪烁,这是这样的:
创建System.Windows.Forms.Timer对象 . 设置每秒25帧的间隔:
timer.Interval = 1000/25;
向Tick事件添加回调方法:timer.Tick += new EventHandler(animateCallback)
animateCallback
应该更新Arrow实例的坐标并调用Invalidate()让.NET图形系统调用控件的Paint方法 .使用System.Windows.Forms.Timer类对于避免闪烁至关重要 . 此计时器在UI线程中运行 . 这意味着,您获得的回调位于UI线程中 . 因此,当您更新animateCallback方法中的箭头坐标时,系统将不会执行任何绘制 .