我正在制作一个粒子游戏(到目前为止,只有水),并且元素内的 Draw() 方法非常慢,同时有几个。我认为这是因为它每秒计算太多,但考虑到它们只是基本的 2D 形状,我仍然对此很不满意。如何提高效率?
这是我的代码:
(循环)(每 50 毫秒运行一次)(注意,我只是包含了计时器的表单,我使用的是 WPF。)
void TimeKeeper_Tick(object sender, EventArgs e)
{
foreach (Element ele in Elements)
{
ele.Draw();
}
}
和绘制方法。 Pos 是一个“Vector2”(我为了节省时间而制作的类(class)):
public void Draw()
{
Pos.Add(3, 10);
if (Pos.Y > (int)canvas.ActualHeight)
{
Pos.Set(Pos.X, (int)shape.RenderSize.Width);
}
if (Pos.X+shape.RenderSize.Width > (int)canvas.ActualWidth)
{
Pos.Set(0, Pos.Y+(int)shape.RenderSize.Height);
}
shape.SetValue(Canvas.LeftProperty, (double)Pos.X);
shape.SetValue(Canvas.TopProperty, (double)Pos.Y);
if (canvas.Children.IndexOf(shape) != null)
{
canvas.Children.Remove(shape);
}
canvas.Children.Add(shape);
}
最佳答案
覆盖 Canvas 后代中的 Canvas.OnRender
是大量移动形状的最佳选择。
WPF 针对静态形状进行了优化。如果您四处移动所有这些静态形状,您将经历此优化的所有开销而不会从中受益(随着形状移动)。
代码看起来像这样:
public delegate void RenderEventHandler(CanvasRender sender, DrawingContext dc);
public class CanvasRender : Canvas
{
public event RenderEventHandler Render;
public CanvasRender()
{
}
protected override void OnRender(DrawingContext dc)
{
if (Render != null)
Render(this, dc);
base.OnRender(dc);
}
}
然后使用此类代替 Canvas
,并为 Render
事件分配一个处理程序。在这种情况下,您可以使用对 DrawingContext
的显式调用来重绘整个视觉对象。
这听起来好像您通过这种方式做了更多的工作,但实际上这比创建所有移动对象然后四处移动它们更有效。特别是如果这些对象是角度/长度随时间变化的线,因为 WPF 无法预渲染它们以及移动时预渲染的形状。
关于c# - 有什么方法可以更快地在 Canvas 上渲染大量移动对象(C# w/WPF),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5688627/