vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Schützen Sie Ihre Software vor Software-Piraterie - mit sevLock 1.0 DLL!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
WPF: 14000 Paths 
Autor: Maas
Datum: 04.10.11 12:59

Hallo,
Ich beschäftige mich z.Z. mit dem Strategie-Spiel Hearts of Iron III und will mir dafür einen Editor basteln.
Es gibt für mein Problem folgende Voraussetzungen:

Das Spiel ist sehr Modder-freundlich aufgebaut. Das heißt, dass es für die verschiedenen Provinzen der Spielkarte eine Bitmap, welche dann auch das Spiel selber benutzt. Die Karte sieht so aus (in echt ist sie gespiegelt und gedreht, aber das ist egal):



Das hier ist der Ausschnitt für den Nordseeteil. Die Provinzen erstrecken sich über die ganze Welt und insgesamt gibt es über 14000 davon. Die Karte hat 5616x2160 Pixel. Jede Provinz hat einen RGB-Farbcode, welcher auch in einer csv-Datei zu finden ist, zusammen mit der ID (Integer) der Provinz. Mit dieser ID ist dann eine ganze Menge möglich, u.a. das Bearbeiten der Provinz-Werte in einem Save Game.
Ich habe also schon folgendes geschafft:
-Einlesen der RGB-ID Kombinationen
-Einlesen der Karte
-Analysieren der Karte nach "ProvincePixelGroups" (es werden für jede Provinz die Pixelkoordinaten erfasst; ca. 1000-2000)
-Löschen der inneren Pixel einer ProvincePixelGroup (es bleiben nur die Umriss-Koordinaten; ca. 100-200)

Jetzt will ich die Karte also neu "Zeichnen", aber mit Objekten. Ich hatte zuerst nur die Bitmap geladen und bei MouseOver auf den Farbcode geprüft. Das hat soweit auch super funktioniert. Jetzt will ich es aber so gestalten, dass man die Karte in verschiedenen Sichten ansehen kann (politisch, Infrastruktur, Anzahl der stationierten Einheiten, etc.), es müssen also die Farben der Provinzen angepasst werden. Dass dann die Identifizierung über den Farbcode nicht mehr funktioniert, ist klar. Deswegen will ich mit (FrameworkElement-)Objekten arbeiten, da diese z.B. ein MouseEnter und MouseLeftButtonUp Event haben. Ich muss dann nur noch den sender auswerten und dazu den DataContext mit der ID.
Dazu benutze ich die Path und StreamGeometry-Klassen. Das funktioniert auch soweit, außer dass es verdammt langsam ist (nicht das Laden). Ich habe dann also in einem Canvas 14000 Paths und das scheint WPF irgendwie nicht zu mögen. Der GUI-Thread ist schon komplett ausgelastet, wenn ich nur mit der Maus über die Provinzen gleite. Eine ID-/Namens-Ausgabe per MouseEnter dauert so um die 1-2 Sekunden. Das macht ein vernünftiges Arbeiten natürlich so gut wie unmöglich.

Gibt es hier jetzt eine bessere Möglichkeit zu "zeichnen"? Ich will ja nicht wirklich zeichnen (also mit den Geometry-Klassen), denn dann hätte ich keinen DataContext und keine Events. (Außerdem könnt ich mir dann das alles sparen und einfach die Original-Bitmap laden). Vielleicht ist ein Canvas auch einfach nicht der beste Container für so viele Paths?!? Ich kann mir leider auch nicht erklären, warum die GUI-Thread Auslastung überhaupt bei 100% liegt. Wieso bezieht er, wenn ich z.B. mit der Maus über 4 Provinzen gleite, alle 14000 Paths mit ein? Was haben die mit dem kleinen Bereich zu tun, in dem ich mit der Maus arbeite?

Hier mal der Code zum Erstellen der Paths:
"ProvinceMapDefinition" ist eine Datenklasse für Farbcode, ID und Name einer Provinz.
"drawTable" ist das Canvas.
        Dim geos As New List(Of Path)
 
        Dim lstDefs As New List(Of ProvinceMapDefinition)( _
          GameData.MapDefinitions)
        Dim pathGeo As New PathGeometry
 
        For Each ppg As ProvincePixelGroup In mPixelGroups
            Dim myPath As New Path
            myPath.Stroke = New SolidColorBrush(Color.FromRgb(ppg.Color(2), _
              ppg.Color(1), ppg.Color(0)))
            myPath.StrokeThickness = 2
 
            Dim geo As New StreamGeometry
            geo.FillRule = FillRule.Nonzero
 
            Using ctx = geo.Open()
                ctx.BeginFigure(ppg.Positions(0), True, True)
                ctx.PolyLineTo(ppg.Positions, True, True)
            End Using
 
            geo.Freeze()
 
            myPath.Data = geo
 
            For Each prov In lstDefs
                If prov.Color.R = ppg.Color(2) And prov.Color.G = ppg.Color(1) _
                  And prov.Color.B = ppg.Color(0) Then
                    myPath.DataContext = prov
                    lstDefs.Remove(prov)
                    Exit For
                End If
            Next
            AddHandler myPath.MouseEnter, AddressOf Me.path_MouseEnter
            AddHandler myPath.MouseLeave, AddressOf Me.path_MouseLeave
 
            drawTable.Children.Add(myPath)
        Next
Schonmal Danke im Voraus

Maas
alle Nachrichten anzeigenGesamtübersicht  |  Zum Thema  |  Suchen

 ThemaViews  AutorDatum
WPF: 14000 Paths1.400Maas04.10.11 12:59
Re: WPF: 14000 Paths856Maas04.10.11 13:01

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel