我想创建一个图形库,以便可以可视化一些代码(类似于对Java的处理)。更新绘制的图像会导致闪烁,而我找不到解决该问题的方法。 我正在使用Drawing类和WinForms进行绘图。 如果还有另一种/更好的方法可以通过使用其他方法(Unity除外)来实现,那么我愿意尝试一下。
我尝试了双重缓冲,但没有任何作用。无效和刷新使情况变得更糟。
编辑:已修复(请参阅评论)。我使用了发现here
的计时器以下是我的Form类。
Timer timer;
int i = 0;
Screen screen;
Rectangle canvas;
public Form1() {
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
DoubleBuffered = true;
screen = Screen.FromControl(this);
canvas = screen.WorkingArea;
timer = new Timer();
timer.Interval = 10;
timer.Tick += new EventHandler(draw);
timer.Enabled = true;
}
public void draw(object source, EventArgs e) {
Graphics g = CreateGraphics();
g.FillRectangle(new SolidBrush(Color.Black), canvas);
g.FillRectangle(new SolidBrush(Color.White), i, 0, 100, 100);
i++;
}
答案 0 :(得分:2)
请勿创建图形,请使用传递给OnPaint的图形。
在计时器上,只需计算坐标并调用Invalidate即可。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Flickering
{
public partial class Form1 : Form
{
Timer timer;
Rectangle rect = new Rectangle(0, 0, 100, 100);
Size speed = new Size(3, 1);
Size step = new Size(3, 1);
public Form1()
{
InitializeComponent();
this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
timer = new Timer();
timer.Interval = 20;
timer.Tick += new EventHandler(Tick);
timer.Enabled = true;
}
protected override void OnPaint(PaintEventArgs e)
{
//e.Graphics.FillRectangle(Brushes.DarkCyan, ClientRectangle);
e.Graphics.FillRectangle(Brushes.White, rect);
}
public void Tick(object source, EventArgs e)
{
var canvas = ClientRectangle;
step.Width = rect.Right >= canvas.Width ? -speed.Width : rect.Left < canvas.Left ? speed.Width : step.Width;
step.Height = rect.Bottom >= canvas.Height ? -speed.Height : rect.Top < canvas.Top ? speed.Height : step.Height;
rect.Location += step;
Invalidate();
}
}
}