Problem mit Invalidate()

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von TheVBTutorialsVB.

    Problem mit Invalidate()

    Hallo Community,

    ich bin gerade dabei ein 2D-Game zu programmieren. Ich habe gerade damit angefangen den Spieler zu programmieren, und stoße beim Zeichnen gleich auf ein Problem. Da ich ja nur den Player neu zeichnen möchte, zeichne ich mit Invalidate() nur den Teil neu, wo die Position des Spielers ist. Das Problem ist jetzt, dass der Spieler an die neue Position gezeichnet wird, aber die Positionen, an denen er vorher war, immernoch gezeichnet sind.

    Klasse Player.vb:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Player
    3. Private _point As Point
    4. Private _size As Size
    5. Private _brush As Brush
    6. Public Enum Direction
    7. Top
    8. Bottom
    9. Left
    10. Right
    11. End Enum
    12. Public Sub New(ByVal point As Point, ByVal size As Size, ByVal brush As Brush)
    13. _point = point
    14. _size = size
    15. _brush = brush
    16. End Sub
    17. Public Property Location As Point
    18. Get
    19. Return _point
    20. End Get
    21. Set(value As Point)
    22. _point = value
    23. End Set
    24. End Property
    25. Public ReadOnly Property Size As Size
    26. Get
    27. Return _size
    28. End Get
    29. End Property
    30. Public Property Brush As Brush
    31. Get
    32. Return _brush
    33. End Get
    34. Set(value As Brush)
    35. _brush = value
    36. End Set
    37. End Property
    38. Public ReadOnly Property Rectangle As Rectangle
    39. Get
    40. Return New Rectangle(_point, _size)
    41. End Get
    42. End Property
    43. Public Sub DrawPlayer(ByVal e As PaintEventArgs)
    44. With e.Graphics
    45. .FillRectangle(_brush, New Rectangle(_point, _size))
    46. End With
    47. End Sub
    48. Public Sub DoStep(ByVal stepsize As Integer, ByVal direction As Direction)
    49. Select Case direction
    50. Case Player.Direction.Top
    51. _point = New Point(_point.X, _point.Y - stepsize)
    52. Case Player.Direction.Bottom
    53. _point = New Point(_point.X, _point.Y + stepsize)
    54. Case Player.Direction.Right
    55. _point = New Point(_point.X + stepsize, _point.Y)
    56. Case Player.Direction.Left
    57. _point = New Point(_point.X - stepsize, _point.Y)
    58. End Select
    59. End Sub
    60. End Class



    Klasse Form1.vb:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Private p As New Player(New Point(10, 10), New Size(50, 50), Brushes.Red)
    4. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    5. DoubleBuffered = True
    6. End Sub
    7. Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    8. Select Case e.KeyCode
    9. Case Keys.W
    10. p.DoStep(10, Player.Direction.Top)
    11. Invalidate(p.Rectangle)
    12. Case Keys.S
    13. p.DoStep(10, Player.Direction.Bottom)
    14. Invalidate(p.Rectangle)
    15. Case Keys.A
    16. p.DoStep(10, Player.Direction.Left)
    17. Invalidate(p.Rectangle)
    18. Case Keys.D
    19. p.DoStep(10, Player.Direction.Right)
    20. Invalidate(p.Rectangle)
    21. End Select
    22. End Sub
    23. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    24. p.DrawPlayer(e)
    25. End Sub
    26. End Class



    Mit Me.Invalidate() funktioniert es, aber ich möchte nicht mehr neu zeichnen als nötig, außerdem flackert es dann. Ich hoffe ihr könnt mir helfen.

    TheVBTutorialsVB

    Danke Artentus für die schnelle Hilfe, da hätte ich auch selbst drauf kommen können. Ich habe das jetzt einfach so gelöst:

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Form1
    3. Private p As New Player(New Point(10, 10), New Size(50, 50), Brushes.Red)
    4. Private lastPos As Rectangle
    5. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    6. DoubleBuffered = True
    7. lastPos = New Rectangle(p.Location, p.Size)
    8. End Sub
    9. Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    10. Select Case e.KeyCode
    11. Case Keys.W
    12. lastPos = New Rectangle(p.Location, p.Size)
    13. p.DoStep(10, Player.Direction.Top)
    14. Invalidate(lastPos)
    15. Invalidate(p.Rectangle)
    16. Case Keys.S
    17. lastPos = New Rectangle(p.Location, p.Size)
    18. p.DoStep(10, Player.Direction.Bottom)
    19. Invalidate(lastPos)
    20. Invalidate(p.Rectangle)
    21. Case Keys.A
    22. lastPos = New Rectangle(p.Location, p.Size)
    23. p.DoStep(10, Player.Direction.Left)
    24. Invalidate(lastPos)
    25. Invalidate(p.Rectangle)
    26. Case Keys.D
    27. lastPos = New Rectangle(p.Location, p.Size)
    28. p.DoStep(10, Player.Direction.Right)
    29. Invalidate(lastPos)
    30. Invalidate(p.Rectangle)
    31. End Select
    32. End Sub
    33. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    34. p.DrawPlayer(e)
    35. End Sub
    36. End Class

    guck mal, das geht auch viel kürzer:

    VB.NET-Quellcode

    1. Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    2. Dim oldRectangle As Rectangle = p.Rectangle
    3. Select Case e.KeyCode
    4. Case Keys.W
    5. p.DoStep(10, Player.Direction.Top)
    6. Case Keys.S
    7. p.DoStep(10, Player.Direction.Bottom)
    8. Case Keys.A
    9. p.DoStep(10, Player.Direction.Left)
    10. Case Keys.D
    11. p.DoStep(10, Player.Direction.Right)
    12. End Select
    13. Invalidate(oldRectangle)
    14. Invalidate(p.Rectangle)
    15. End Sub