4 Stimmen

Gibt es eine Möglichkeit, Rendering viele bewegte Objekte auf einem Canvas schneller zu machen (C# w / WPF)

Ich mache ein Partikel-Spiel mit (bisher nur Wasser), und die Draw()-Methode innerhalb eines Elements ist ziemlich langsam mit ein paar auf einmal. Ich nehme an, es ist, weil es so viel jede Sekunde berechnet, aber ich bin immer noch ziemlich unglücklich mit ihm, wenn man bedenkt, sie sind nur grundlegende 2D-Formen. Wie kann ich es effizienter machen?

Hier ist mein Code:

(Schleife) (Läuft alle 50 Millisekunden) (Hinweis: Ich habe nur Forms für den Timer eingefügt, ich verwende WPF).

    void TimeKeeper_Tick(object sender, EventArgs e)
    {
        foreach (Element ele in Elements)
        {
            ele.Draw();
        }
    }

Und Ziehverfahren. Pos ist ein "Vector2" (Klasse, die ich gemacht habe, um mir Zeit zu sparen):

    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);
    }

4voto

enverpex Punkte 1070

Übergeordnetes Recht Canvas.OnRender in einem Canvas-Abkömmling ist die beste Wahl für viele bewegliche Formen.

WPF ist für statische Formen optimiert. Wenn Sie alle diese statischen Formen bewegen, gehen Sie durch den gesamten Overhead dieser Optimierung, ohne davon zu profitieren (wie die Formen bewegen).

Der Code sieht in etwa so aus:

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);
    }
}

Sie verwenden dann diese Klasse anstelle von Canvas und weisen Sie einen Handler für die Render Veranstaltung. In diesem Fall zeichnen Sie Ihr gesamtes Bildmaterial neu, indem Sie explizite Aufrufe an die DrawingContext .

Es mag sich so anhören, als ob Sie auf diese Weise viel mehr Arbeit hätten, aber das ist tatsächlich viel effizienter, als alle beweglichen Objekte zu erstellen und sie dann zu verschieben. Vor allem, wenn diese Objekte sind Linien, deren Winkel / Länge ändert sich im Laufe der Zeit, wie WPF kann nicht pre-render sie und die vorgerenderte Form, wenn es bewegt.

1voto

Pavlo Glazkov Punkte 20178

Wenn Sie es wirklich schnell haben wollen, müssen Sie einige fortgeschrittene Techniken anwenden. Dies sind vor allem sogenannte prozedurale Animationen und Animationen mit beschreibbaren Bitmaps.

Hier ist ein hervorragender Blogbeitrag, der diese Techniken beschreibt (mit einem Beispiel für den Partikeleffekt): http://blogs.claritycon.com/blog/2011/03/30/advanced-animation-animating-15000-visuals-in-silverlight-2/ . Es geht um Silverlight, aber da Silverlight eine Untermenge von WPF ist, sind die Techniken die gleichen.

0voto

Emond Punkte 48911

Vieles hängt davon ab, was Sie unter "langsam" verstehen

Wenn Sie die Formen alle 50 ms bewegen, müssen Sie sie in jedem Intervall mehr bewegen, damit sie schneller laufen.

Aber das Hinzufügen eines Timers, wie Sie getan haben, ist nicht der beste Weg, um Animationen in WPF zu erstellen.

Es gibt mehrere Möglichkeiten:

  1. eine Geschwindigkeit für jede Form angeben (etwa: 10 Einheiten pro Sekunde), dann bei jeder Aktualisierung des Bildschirms die Formen entsprechend der Zeit, die seit der letzten Bewegung vergangen ist, und ihrer Geschwindigkeit bewegen. Sie müssen also auch die verstrichene Zeit festhalten.

  2. Erstellen Sie Storyboards, sie haben ihre eigenen Timer (Zeitleisten), so dass Sie nur noch die Start- und Endposition festlegen, die Dauer bestimmen und schließlich die Animation abspielen müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X