Brettspiel mit GDI+

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Brettspiel mit GDI+

    Hi,
    ich dachte dass ich mich mal an einem Spiel versuche.
    Hauptsächlich soll es zur Übung ein "Mensch ärgere dich nicht" werden.

    Allerdings würde ich das Spiel gerne überwiegend im GDI Zeichnen da ich mich mit diesem Thema mehr befassen möchte.
    Also habe ich ein Feld und einen Spieler gezeichnet.
    Wie mache ich jetzt aber der Spielfigur klar, dass der auf das Feld soll?

    Mir fehlt absolut der Ansatz wie ich das bewerkstellige.
    Für die Felder und Spieler habe ich eine Klasse zum Zeichnen gemacht.

    Kann ich das feld irgendwie so gestalten, dass ich sagen kann:

    VB.NET-Quellcode

    1. SpielFigur ist auf Feld1
    2. Gewürfelte Zahl ist 3
    3. SpielFigur muss auf Feld1 + Gewürfelte Zahl 'Also Feld 4


    Habs zur veranschaulichung gepackt und angehängt.

    Hoffentlich verteht man wie ich das meine.
    DANKE
    Bilder
    • SpielerAufFeld.PNG

      4,66 kB, 351×158, 99 mal angesehen
    Dateien
    Braucht malwieder v.a. ein durchdachtes Datenmodell.

    ZB für die Felder brauchst du iwie eine Datenstruktur mit Ring-Logik. also was für Gelb das erste Feld ist, ist für Rot das sonstwievielte Feld, und so hat jeder Spieler einen eigenen Einsprungspunkt in die Ring-Liste der Felder.

    Neben Feldern und Spielern gibts auch die Spielfiguren (jeder Spieler hat 4 davon), und jede Spielfigur muss wissen, auf welchem Feld sie steht.
    Dabei kann man die Start-Häuschen und die Ziel-Häuschen auch als Felder auffassen, allerdings mit iwie besonderem Verhalten.

    Also es gibt 4 Spieler, zum Spieler gehört 1 Farbe, 1 StartHaus mit 4 Feldern, 1 ZielHaus mit 4 Feldern, ein EinsprungsPunkt-RingFeld
    Ausserdem gibts viele Ringfelder, ich glaub 40, oder 44, zähl mal nach.
    Auch gehört zum Spieler natürlich 4 Figuren, und jede Figur muss wissen, auf welchem Feld sie grad steht.

    Jo, im DrawEvent müssen erst alle Felder sich zeichnen, und dann alle SpielFiguren.
    Bewegt sich eine SpielFigur, so muss sie sich invalidieren, wo sie vorher war, und auch invalidieren, wo sie nun neu ist - dann wird der PositionsWechsel richtig dargestellt.
    Das gilt ebenso für geschlagene Figuren, aber bis dahin ist eh noch ein weiter weg.

    Mein OwnerDrawing - Tut kennste?

    ErfinderDesRades schrieb:

    Mein OwnerDrawing - Tut kennste?

    Nein kenne ich noch nicht, werds mir aber sofort anschauen.

    Ich sehe schon.... das wird nicht "nur mal üben" :/



    Nachtrag:

    Müsste ich Theoretisch alle felder einzeln im PaintEvent Zeichnen?

    So Zeichne ich im moment ein Feld:

    VB.NET-Quellcode

    1. Private Kreis1 As New cKreis(Color.Aqua, 15, 10)
    2. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    3. Kreis1.Zeichnen(e.Graphics)
    4. End Sub


    und das ist meine Klasse (cKreis):

    VB.NET-Quellcode

    1. Public Class cKreis
    2. Inherits Panel
    3. Private Pinsel As SolidBrush
    4. Private Stift As New Pen(Color.Black, 2)
    5. Private LocX As Integer
    6. Private LocY As Integer
    7. Private Schriftart As New Font("Arial", 8)
    8. Public Property Farbe As Color
    9. Public Sub New(f As Color, y As Integer, x As Integer)
    10. Farbe = f
    11. LocX = x
    12. LocY = y
    13. End Sub
    14. Public Sub Zeichnen(ByVal g As Graphics)
    15. Pinsel = New SolidBrush(Farbe)
    16. g.DrawEllipse(Stift, LocX, LocY, 50, 50)
    17. g.FillEllipse(Pinsel, LocX, LocY, 50, 50)
    18. g.DrawString("Feld1", Schriftart, Brushes.Black, LocX + 8, LocY + 55)
    19. End Sub
    20. End Class


    Ich hab so das doffe gefühl ich bin auf dem vollkommen falschen dampfer... :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „CFire“ () aus folgendem Grund: Nachtrag

    Sammel die Felder in einer Liste bzw. Array, undzwar als Rectangle.
    Danach kannst du einfach die Position von dem Rectangle nehmen und die Mitte berechnen. Dort zeichnest du dann die Figur hinein.


    EDIT://
    Nachdem du alle Rectangle für die Felder erzeugt hast (ich weiß ja nicht wie das Feld aussehen soll),
    kannst du das Ganze ja mit einer For-Each bzw. For i as Integer-Schleife durchlaufen, und ersparst dir somit das Einzeln zeichnen.
    D.h:

    VB.NET-Quellcode

    1. Public Class cKreis
    2. Inherits Panel
    3. Private Pinsel As SolidBrush
    4. Private Stift As New Pen(Color.Black, 2)
    5. Private _Rectangle as Rectangle
    6. Private Schriftart As New Font("Arial", 8)
    7. Public Property Farbe As Color
    8. Public Sub New(f As Color, y As Integer, x As Integer)
    9. Farbe = f
    10. _Rectangle = New Rectangle(x, y, 50,50)
    11. End Sub
    12. Public Sub Zeichnen(ByVal g As Graphics)
    13. Pinsel = New SolidBrush(Farbe)
    14. g.DrawEllipse(Stift, _Rectangle)
    15. g.FillEllipse(Pinsel, _Rectangle)
    16. g.DrawString("Feld1", Schriftart, Brushes.Black, LocX + 8, LocY + 55)
    17. End Sub
    18. End Class
    19. Private PositionPlayerOne as Integer = 3 'Beispiel
    20. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    21. For Each k as cKreis in CircleList 'Wobei du natürlich erst diese CircleList erstellen musst.
    22. k.Zeichnen(e.Graphics)
    23. Next
    24. 'Figurzeichnen, bsp. funktioniert nicht, ist eher für den Gedankenweg
    25. Dim CircleArray as cKreis() = CircleList.ToArray()
    26. Figur.Zeichnen(CircleArray(PositionPlayerOne)) 'Natürlich musst du dir dann den Punkt noch berechnen, ich übergebe hier lediglich das Feld-Rechteck in dem die Figur stehen sollte.
    27. End Sub



    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Gather“ ()

    Warum heisst die Klasse cKreis? Was stellt sie dar? Warum erbt sie von Panel?

    Nach meim OwnerDrawing-Tut ist geraten, sich ein Canvas-Control zu basteln - das sollte von Control erben, evtl. von Panel, wenn du mit AutoScrolling arbeiten musst -was ich bezweifel.

    Aber warum sollte ein Canvas "Kreis" heissen? Schon aufgrund des Namens blicke ich nicht mehr durch, was die Aufgabe dieses Controls sein soll.

    (Ich glaube übrigens, du blickst auch nicht durch, denn anderer Code in cKreis deutet darauf hin, dass es eine Figur-Klasse sein soll, aber Figur-Klassen sollen keinesfalls von Panel oder anderen Controls erben)

    Ah - ja - ich denke, es soll eher eine Figur sein.
    Also einfach zeile#2 löschen, dann kann man das so leidlich als Figur-Klasse, die einen Kreis darstellen soll, durchgehen lassen.
    Wird denn schoma was auffm Form gemalt? Das wär ja schon ein Erfolg.
    cKreis Zeichnet ein SpielFeld (von 40 oder 44) wo zum Schluss die Figur drauf steht.

    Ich glaube übrigens, du blickst auch nicht durch

    Ne... bin im moment total verwirrt, glaube das war zu viel input für heute.

    Werd mir mal alles in ruhe zu gemüte führen und von vorne alles neu bedenken.
    Ich habs mir ganz kurz angeschaut:
    cCircle

    VB.NET-Quellcode

    1. Public Class cCircle
    2. Private LocX As Integer
    3. Private LocY As Integer
    4. Private _Field As Rectangle
    5. Private _Text As String = "Feld1"
    6. Private _Font As Font = New Font("Arial", 8)
    7. Private _ForeColor As Color = Drawing.Color.Black
    8. Public Property Field As Rectangle
    9. Get
    10. Return _Field
    11. End Get
    12. Set(value As Rectangle)
    13. If _Field <> value Then
    14. _Field = value
    15. End If
    16. End Set
    17. End Property
    18. Private _Color As Color = Drawing.Color.Blue
    19. Public Property Color As Color
    20. Get
    21. Return _Color
    22. End Get
    23. Set(value As Color)
    24. If _Color <> value Then
    25. _Color = value
    26. End If
    27. End Set
    28. End Property
    29. Public Sub New(f As Color, y As Integer, x As Integer)
    30. _Color = f
    31. _Field = New Rectangle(x, y, 50, 50)
    32. End Sub
    33. Public Sub Draw(ByVal g As Graphics)
    34. g.FillEllipse(New SolidBrush(_Color), _Field)
    35. g.DrawEllipse(New Pen(Color.Black, 2), _Field)
    36. g.DrawString(_Text, _Font, New SolidBrush(_ForeColor), LocX + 8, LocY + 55)
    37. End Sub
    38. End Class

    Die Properties, sind hier eigentlich unnötig.

    Form

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim l As New List(Of cCircle) From {New cCircle(Color.Blue, 50, 50), New cCircle(Color.Red, 100, 50)}
    3. Private PlayerPos As Integer = 1
    4. Private Function GetPlayerRectangle(r As Rectangle, Optional s As Integer = 10) As Rectangle
    5. Dim p As New Point((r.X + CInt(r.Width / 2)) - CInt(s / 2), (r.Y + CInt(r.Height / 2)) - CInt(s / 2))
    6. Return New Rectangle(p, New Size(s, s))
    7. End Function
    8. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    9. Dim g As Graphics = e.Graphics
    10. g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
    11. Dim Arr As cCircle() = l.ToArray
    12. For i As Integer = 0 To Arr.Count - 1
    13. Arr(i).Draw(g)
    14. Next
    15. g.FillEllipse(Brushes.Black, GetPlayerRectangle(Arr(PlayerPos).Field))
    16. End Sub
    17. End Class


    Da kannst du ansetzen :)
    Mfg: Gather
    Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Gather“ ()

    @CFire: klingt eiglich nicht so schlecht.
    Aber sag nicht "zeichnet ein Spielfeld"
    Spielfeld ist in meiner Welt das gesamte Spiel. Dein Kreis zeichnet ein Feld, eines von 40 oder 44 (hast du immer noch nicht nachgezählt?).
    Und wenn das funzt, ist das schon ein wichtiger Schritt in die richtige Richtung.
    Demnächst muss dann eine List(Of Kreis) instanziert und befüllt werden, mit 44 Kreisen, und deren X, Y muss richtig eingestellt werden, dann hast du schonmal die Felder, wo die Spielfiguren herumlaufen.

    Aber ich würde ein Canvas-Control dafür machen, und darin das Paint-Event behandeln.
    Es wird noch sehr komplex, und wenn das alles im Form stattfinden soll, verliert man im Form-Code vollkommen den Überblick.

    Besser ein Canvas-Control basteln, kompilieren, aufs Form ziehen, und dann das Canvas weiter-entwickeln, und das Form damit in Ruhe lassen.

    Also strukturell ist das sehr an das erste Card-Sample aussm Tut angelehnt, nur deine Layout-Logik muss natürlich ganz anders als beim Card-Sample.
    Beim Card-Sample wird ja fortlaufend zeilenweise angeordnet, während deine Felder-Anordnung ja das typische Mensch-ÄrgereDichnicht-Layout ergeben muss - die Umriss-Linie eines griechischen Kreuzes, so ähnlich.