GDI+ Ellipse mit der Maus bewegen.

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    GDI+ Ellipse mit der Maus bewegen.

    Hey Leute,

    ich bin gerade dabei mein erstes 2D Game in Visual Basic zu programmieren. Dafür verwende ich GDI+.
    Momentan hänge ich an einer Ellipse, deren Position meiner Maus zugewiesen werden soll.
    Mein folgener Code sieht so aus:

    VB.NET-Quellcode

    1. Private Sub Form2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    2. Dim mposX As Integer = Form1.MousePosition.X - 355
    3. Dim mposY As Integer = Form1.MousePosition.Y - 287
    4. Me.Text = New Point(mposX, mposY).ToString
    5. kreis = New Bitmap(20, 20)
    6. Using g = Graphics.FromImage(kreis)
    7. g.DrawEllipse(Pens.White, New Rectangle(mposX, mposY, 20, 20))
    8. g.Dispose()
    9. End Using
    10. End Sub


    Was mache ich falsch?

    MfG

    backtothetoast schrieb:

    Was mache ich falsch?
    Fast alles.
    1. Du greifst von Form2 aus über Form1.bla auf Form1-Properties. Lass Dir in Form1 nach Form2 ein Event senden mit den Koordinaten.
    2. Speichere die Koordinaten und invalidisiere die Form, der Rest passiert im Paint-Event der Form2, da bekommst Du das gültige Paint-Objekt im e-Parameter gleich mitgeliefert.
    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!
    [VB.NET] 5 Regeln für sinnvolles Fragen

    Wo liegt Dein Problem?


    PS: Ich vermute mal, dass die Bitmap leer bleibt.
    Das liegt daran, dass die Bitmap 20x20 Pixel groß ist, Du aber nicht bei 0;0 zeichnest, sondern irgendwo bei der Mausposition.
    Siehe das hier:

    Zeichne die Ellipse an Position 0;0 mit Größe 20;20 und zeichne die Bitmap an mposX;mposY.

    Wobei: Das ganze System scheint nicht sinnvoll zu sein. Wenn Du auf eine Form zeichnen willst, dann solltest Du das Control invalidieren und direkt auf das Graphics-Objekt zeichnen, das in der Paint-Methode verfügbar ist.


    Edit: RodFromGermany war schneller.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    VB.NET-Quellcode

    1. Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    2. Dim mposX As Integer = Form2.MousePosition.X
    3. Dim mposY As Integer = Form2.MousePosition.Y
    4. Me.Text = New Point(mposX, mposY).ToString
    5. With e.Graphics
    6. .DrawEllipse(Pens.Black, mposX, mposY, 20, 20)
    7. Me.Invalidate()
    8. Me.Update()
    9. End With
    10. End Sub

    So klappt nun, aber die Ellipse flackert wie verrückt.

    backtothetoast schrieb:

    aber die Ellipse flackert wie verrückt.
    Das Invalidate muss ins MouseMove oder dahin, wo Koordinaten und Parameter geändert werden.

    VB.NET-Quellcode

    1. Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    2. Dim mposX As Integer = Form2.MousePosition.X
    3. Dim mposY As Integer = Form2.MousePosition.Y
    4. Me.Text = New Point(mposX, mposY).ToString
    5. With e.Graphics
    6. .DrawEllipse(Pens.Black, mposX, mposY, 20, 20)
    7. End With
    8. End Sub
    9. Private Sub Form2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    10. ' Koordinaten ...
    11. Me.Invalidate()
    12. Me.Update()
    13. End Sub
    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!
    Cool klappt. Einen letzten Fehler gibt es noch:

    Genau beschreiben kann ich ihn nicht, aber wenn man von dem Menü auf Spielstarten klickt, wird eine leere Ellipse gezeichnet, die nach dem Bewegen der Maus verschwindet.

    Code:

    VB.NET-Quellcode

    1. Imports System.Drawing.Drawing2D
    2. Public Class Form2
    3. Private _bitmap As Bitmap
    4. Private kreis As Bitmap
    5. Private Sub Form2_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    6. Application.Exit()
    7. End Sub
    8. Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    9. _bitmap = New Bitmap(Me.Width, Me.Height)
    10. Using g = Graphics.FromImage(_bitmap)
    11. g.FillRectangle(New LinearGradientBrush(New Rectangle(0, 0, Me.Width, Me.Height), Color.White, Color.Gray, LinearGradientMode.Vertical), New Rectangle(0, 0, Me.Width, Me.Height))
    12. g.Dispose()
    13. SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint, True)
    14. End Using
    15. Me.BackgroundImage = _bitmap
    16. Cursor.Hide()
    17. End Sub
    18. Private Sub Form2_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
    19. Me.Invalidate()
    20. Me.Update()
    21. End Sub
    22. Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    23. Dim mposX As Integer = Form2.MousePosition.X - 364
    24. Dim mposY As Integer = Form2.MousePosition.Y - 294
    25. Me.Text = New Point(mposX, mposY).ToString
    26. With e.Graphics
    27. .SmoothingMode = Drawing2D.SmoothingMode.HighQuality
    28. .FillEllipse(Brushes.White, mposX, mposY, 40, 40)
    29. .DrawEllipse(Pens.Black, mposX, mposY, 40, 40)
    30. ' SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint, True)
    31. End With
    32. End Sub
    33. End Class
    Bilder
    • Unbenan2nt.png

      46,02 kB, 622×512, 122 mal angesehen
    Deklariere mal eine Variable (zB. bereit) als Boolean mit dem Startwert false.
    Im MouseMove-Ereignis setzt du die Variable dann auf true, und im Paint-Ereignis kommt das hier in die erste Zeile:

    VB.NET-Quellcode

    1. if not bereit then return


    Damit verhinderst du, dass die Ellipse gezeichnet wird, bevor du die Maus über die Form bewegst.
    Dabei wird der weiße Kreis erst gezeichnet, wenn ich die Maus bewege. Ist auch richtig so, aber die leere Ellipse ist trotzdem noch da. Ich werde mal die Form löschen & neu machen.

    EDIT: Nun klappt dies, warum die Ellipse vorher gezeichnet wurde ist mir trotzdem unklar.
    Danke!

    backtothetoast schrieb:

    warum die Ellipse vorher gezeichnet wurde ist mir trotzdem unklar.
    Weil es in der Paint-Routine so steht.
    Wenn etwas erst auf ein Signal hin gemalt werden soll, musst Du ein solches Signal generieren (Boolean-Flag) und dies in der Paint-Routine auswerten, wie @Kai Weigelt: es versucht hat zu beschreiben.
    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!