Problem beim zeichnen von Frames

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Excresco.

    Problem beim zeichnen von Frames

    Hallo, ich bin neu hier und noch ein ziemlicher Noob, trotzdem versuche ich ein kleines "Spiel" in VB zu programmieren, nur um mal zu sehen wie weit ich komme ^^

    Bisher bin ich so weit, dass ich ein "Bild" aus einzelnen Segmenten in eine PictureBox zeichnen und dieses "Bild" auch bewegen kann.
    Ich erzeuge mit Hilfe eines 40ms Timers 25 Frames in der Sekunde und die Einzelnen Teile des Bildes Lade ich in ein Array.

    Ich weis leider nicht wie ich mein Problem am besten erklären kann, weshalb ich auch bei google nicht fündig geworden bin, darum hier ein Screenshot:


    Dazu ein Auszug aus dem Code:

    VB.NET-Quellcode

    1. Public Sub Zeichnen()
    2. For Z = 1 To MAP(0, 0) 'MAP ist ein Array in dem ich die Positionen der Bildsegmente abspeichere
    3. Dim i As Image = ImageContainer(Z)
    4. Dim g As Graphics = Graphics.FromImage(SCREEN_IMAGE)
    5. g.DrawImage(i, MAP(Z, 0) + ANKER.X, MAP(Z, 1) + ANKER.Y, 100, 100)
    6. g.Dispose()
    7. Next
    8. SCREEN_IMAGE = Nothing
    9. Me.SCREEN.Image = BLANK_SCREEN 'BLANK_SCREEN ist einfach ein schwarzes Bild
    10. Me.SCREEN.Image = Nothing
    11. SCREEN_IMAGE = BLANK_SCREEN
    12. Me.SCREEN.Image = SCREEN_IMAGE
    13. Me.SCREEN.Refresh()
    14. End Sub


    Wie schaffe ich es, dass vor Jedem neuen Frame "der Vorherige gelöscht wird"?

    Ich hoffe ich konnte mein Problem verständlich Darstellen und würde mich über hilfreiche Tipps freuen

    Gruß Excresco

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Excresco“ ()

    Jedes Control (also auch eine Form) hat ein Paint-Event, in dem du ein Graphics-Objekt zu Verfügung gestellt bekommst. Alles, was du darauf zeichnest, landet dann direkt auf dem jeweiligen Control.
    Das würde dir insofern helfen, da der DeviceContext eines Controls bei jedem Invalidieren gelöscht wird, sodass du immer mit einer leeren Fläche beginnst, vorherige Zeichnungen bleiben nicht erhalten.
    Danke für den Hinweis, das hat mich schon mal einen Schritt weiter gebracht:

    VB.NET-Quellcode

    1. Private Sub BOX_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    2. For Z = 1 To MAP(0, 0)
    3. Dim i As Image = ImageContainer(Z)
    4. Dim g As Graphics = e.Graphics
    5. g.DrawImage(i, MAP(Z, 0) + ANKER.X, MAP(Z, 1) + ANKER.Y, 100, 100) 'Die eigentliche Grafik (funktioniert nicht)
    6. g.Dispose()
    7. Next
    8. 'Dim g As Graphics = e.Graphics
    9. 'Dim rec As New Rectangle(ANKER.X, ANKER.Y, 100, 100) 'Testweise ein Rechteck (funktioniert)
    10. 'g.FillRectangle(Brushes.Black, rec)
    11. End Sub


    nur leider funktioniert das nicht mit meiner aus Segmenten zusammen gesetzten Grafik,
    was mache ich falsch?
    Das ist nicht sehr vorteilhaft. Arrays haben eine Length-Eigenschaft, die Anzahl brauchst du also überhaupt nicht zu speichern, und um Koordinaten zu speichern solltest du die Point-Struktur verwenden, dann kommst du mit nem eindimensionalen Array aus.
    sooo, ich habe es jetzt geschafft, dass es fast so funktioniert wie es soll:

    VB.NET-Quellcode

    1. Private Sub BOX_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    2. For Z = 1 To MAP(0).X
    3. Dim i As Image = ImageContainer(Z)
    4. Dim g As Graphics = Graphics.FromImage(SCREEN_IMAGE)
    5. g.DrawImage(i, MAP(Z).X, MAP(Z).Y, 1000, 1000)
    6. g.Dispose()
    7. Next
    8. Dim iI As Image = SCREEN_IMAGE
    9. Dim gG As Graphics = e.Graphics
    10. gG.DrawImage(iI, ANKER.X, ANKER.Y, SCREEN_IMAGE.Width, SCREEN_IMAGE.Height)
    11. gG.Dispose()
    12. End Sub

    Paint wird durch Me.Invalidate() in einem 40ms Timer ausgelöst


    Es wird nichts mehr "doppelt" gezeichnet so wie zuvor, nur leider flackert das Bild jetzt.
    Sollte ich das Paint-Event evtl. anders auslösen? Allerdings ist es wichtig, dass mindestens 24 fps erzeugt werden, da sich später Spielfiguren in "Echtzeit" auf meinem Spielfeld bewegen sollen

    sonne75 schrieb:

    Warum erzeugst du jedes Mal eine neue Instanz in der Schleife, wenn sie immer die gleiche ist?


    Das hat keinen bestimmten Grund, sondern liegt daran, dass irgendjemand (also ICH) das einfach schlecht programmiert hat :thumbsup:

    Das scheint auch der Grund dafür zu sein warum das direkte Zeichnen auf die Form zuerst nicht funktioniert hat.

    So funktioniert jetzt aber alles wunderbar:

    VB.NET-Quellcode

    1. Private Sub BOX_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    2. Dim g As Graphics = e.Graphics
    3. For Z = 1 To MAP.Length - 1
    4. Dim i As Image = ImageContainer(Z)
    5. g.DrawImage(i, MAP(Z).X + ANKER.X, MAP(Z).Y + ANKER.Y, 100, 100)
    6. Next
    7. End Sub


    Das Problem ist also gelöst :)

    Vielen Dank an Artentus und sonne75