GDI-Objekt Tiefe einstellen?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    GDI-Objekt Tiefe einstellen?

    Hallo Ihr Lieben,

    schon wieder habe ich 2 Fragen:

    1. Gibt es irgendwelche Möglichkeiten, die GDI-Objekt höhe einzustellen? Die GDI-Objekt wird unter loop gezeichnet und jeder GDI-Objekt haben eine andere Höhewerte. Geht das eventuell mit Transform-Befehle von e.Graphics.*?
    Sagen wir mal, ich will die Z-Koordinat von GDI-Objekt ändern ohne dabei die Objekt sich zu vergrößern oder dieser "3D"-Look hat. Leider hat Google mir überhaupt nichts gebracht...

    2. Gäbe es hier eine Möglichkeit, die GDI-Objekten nur im Bildschirm zeichen/laden zu lassen? Ich habe hier locker über 7000+ GDI Objekte und es wird nicht gut ankommen. (Dieser Menge kommt in Level Editor vor, also nicht wundern :D )
    Ich habe das ganzer in Bitmap zeichen versucht... das lief auch gut... nur je größer der Raum/Bitmap ist, desto braucht der Bitmap mehr Arbeitsspeicher, und das kommt auch nicht bei große Level/Raum gut an.

    Die GDI-Objekten wird erst bei bewegen von Räumen sowie zoomen von Räumen neu gezeichnet.

    Auf Antworten bedanke ich natürlich ganz herzlich! <3

    Gruß, China
    Definiere

    Chinafreak schrieb:

    die GDI-Objekt höhe einzustellen
    Vielleicht malst Du dazu ein Bildchen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Erstmal herzlich dankeschön für deiner Antwort, @RodFromGermany !

    Ich mache einfach mal Screenshot, das sollte besser erklärt werden:

    Siehst du den da bei Häuser, das die Dächer unter die "Wände" sind?



    Ich will es aber, das dieser GDI-Dächer über die Wände stehen, sowie halt das hier:



    So, ich will dieser Höhe per sogenannte "Depth"-Werte ändern. Depth-Werte kann man auch als "Z"-Koordinat sagen


    Das ist dieser Code, die es bei GDI-Objekten gezeichnet wird:

    Spoiler anzeigen

    Quellcode

    1. If Not Room_Level_Instance_amount <= 0 Then
    2. For i As Integer = 0 To Room_Level_Instance_amount Step 1
    3. Dim x As Single = Room_Level_Instance_x(i)
    4. Dim y As Single = Room_Level_Instance_y(i)
    5. Dim sprite As Image
    6. If Room_Level_Instance_sprite(i) = "<undefined>" Or Room_Level_Instance_sprite(i) = "" Then
    7. sprite = My.Resources.noSprite
    8. Else
    9. sprite = Image.FromFile(Room_Level_Instance_sprite_file(i))
    10. End If
    11. .TranslateTransform(Panel1.Location.X + x * zoom_faktor_x, +Panel1.Location.Y + y * zoom_faktor_y)
    12. .RotateTransform(-Room_Level_Instance_rotation(i))
    13. .ScaleTransform(Room_Level_Instance_scaleX(i), Room_Level_Instance_scaleY(i))
    14. .DrawImage(sprite, -Room_Level_Instance_sprite_xorigin(i) * zoom_faktor_x, -Room_level_Instance_sprite_yorigin(i) * zoom_faktor_y, sprite.Width * zoom_faktor_x, sprite.Height * zoom_faktor_y)
    15. .ResetTransform()
    16. Next
    17. End If



    Wenn du es immer noch nicht verstanden hast, sag bitte bescheid, so das ich dann doch Zeichnen/Skizze werde.
    Ich denke, ich hab es

    Chinafreak schrieb:

    verstanden
    Du musst Deine Objekte nach z sortieren und dann zuerst das unterste und zuletzt das oberste zeichnen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wenn bei dir eine Architektur vorhanden ist, dann wirst du wohl irgend ne Klasse /irgend ein Interface als Basis für alle Objekte im Spiel haben. Da einfach ne Z-Eigenschaft hinzufügen und vor jedem Zeichenzyklus die Auflistung danach sortieren (bei ner Klasse einfach IComparable implementieren, beim Interface musst du die Comparison halt selbst definieren). Das lässt sich auch soweit optimieren, dass nur sortiert wird, wenn nötig, also nur wenn ein Objekt hinzugefügt wurde oder sich die Z-Position eines Objektes geändert hat, hier dann einfach mit Events arbeiten.
    Mach deinen Zeichenpuffer nur so groß wie den sichtbaren Bereich. Alles, was du außerhalb davon zeichnest, wird einfach verworfen und braucht damit auch keinen Speicher.
    Du musst halt dann alles in Abhängigkeit des sichtbaren Bereichs setzen, entweder indem du alle Koordinaten regelmäßig anpasst oder indem du ne Matrixtransformation anwendest.
    Unterteile deine Karte in Bereiche: siehe Quadtree

    natürlich sortiert nach Position. Dadurch hat man die Möglichkeit von der aktuellen ViewPosition die zu zeichnenden Quads zu finden und nur die Objekte in diesen zu zeichnen.

    Wichtig: Die Suche ist aufwändig, mach die Quads nicht zu klein, das zeichnen wird bei einer großen Map schneller gehen als bis ins kleinste zu suchen...
    Vorallem, ergibt ein Quad kleiner als Bildschirmgröße zusätzlich nochmal weniger Sinn, da man dann ewig Sucht für alle Subquads, obwohl alle im Bereich sind...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---