Kollisionsabfrage will nicht

  • VB.NET

Es gibt 33 Antworten in diesem Thema. Der letzte Beitrag () ist von Eistee.

    Kollisionsabfrage will nicht

    Moin,

    ich will ein kleines Spiel programmieren, bei dem man anfangs mit einem Spieler auf 'ner "Karte" rumrennt.



    Ich habe PictureBoxen erstellt, durch die der Spieler nicht durch soll (die dunkelgrün-grauen Dinger im Bild).

    Den Code hab ich mir aus der Nase gezogen:

    VB.NET-Quellcode

    1. Private Sub Spieler1_Move
    2. Dim a As New List(Of PictureBox)
    3. With a
    4. .Add(PictureBox1)
    5. .Add(PictureBox2)
    6. .Add(PictureBox3)
    7. .Add(PictureBox4)
    8. .Add(PictureBox5)
    9. .Add(PictureBox6)
    10. .Add(PictureBox7)
    11. End With
    12. For i As Integer = 0 To a.Count - 1
    13. If a(i).Bounds.IntersectsWith(Spieler1.Bounds) Then
    14. Me.Text = "Gut"
    15. Else
    16. Me.Text = "Schlecht"
    17. End If
    18. Next
    19. 'Me.Text = a.Count
    20. End Sub


    Durch den Code muss ich dann eben nämlich nicht für ALLE PictureBoxen die Kollision programmieren.
    Leider wird jetzt anscheinend nur PictureBox7 erkannt, bei den anderen passiert nichts. ?(

    Könnt Ihr mir helfen?

    MfG, JGF
    -.- wieso immer mit Controls?
    Arbeite dich in GDI+, SFML, DirectX, OpenGL, o.Ä. ein und nutze das. Controls sind dazu da, um ein UI zu erzeugen, kein Spiel zu machen.
    Für DirectX kann ich dir SharpDX (bzw. dessen Toolkit, ähnlich XNA) empfehlen.
    SFML ist ein einfacher OGL-Wrapper. Das Einfachste für dich wird vmtl. die GDI+ Implementierung sein. Dazu solltest du hier im Forum einiges finden.
    Danke sonne75.

    Ok Alive Devil,

    wenn du in der Lage bist mir ein GANZ simples kurzes Beispiel für das Bewegen einer mit GDI+ erstellten Grafik zeigst, und dazu noch eine ganz kleine Kollisionserkennung, und dieser Code dann noch kürzer ist, als der, den ich für die Controls benötige, wäre dein Angebot eine tolle Sache. Denn dazu hab ich im Internet noch nichts Brauchbares gefunden, leider.
    Der Code wird nicht kürzer sein, dafür dem eines Spieles gerecht.
    Die Länge eines Programmes spricht nicht immer für guten Stil.
    Wenn du mit Controls arbeiten willst, ist das deine Sache. Es funktioniert, ja, ist aber nicht im Sinne des Erfinders Controls als "Spielelement" zu missbrauchen.
    Du solltest dann schon die richtigen Methoden nutzen, um Grafik auf Windows zu nutzen.
    Zudem hast du dann einige Probleme, die du mit WinForms-Controls haben wirst, nicht.
    Das wäre jetzt ideal für OOP. Du erstellst dir eine Klasse Player und eine Klasse Wall oder GameObject. Die haben dann als Eigenschaft auch ein Rectangle, die die IntersectsWith-Funktion besitzen.
    Dann zeichnest du im Paint-Event deinen Spieler:

    VB.NET-Quellcode

    1. e.Graphics.FillRectangle(deine Parameter)
    2. 'oder
    3. e.Graphics.DrawImage(deine Parameter)

    Ok, ich bin einsichtig, ich hätte auch schon viel früher angefangen mit GDI+ zu arbeiten,
    wenn ich nicht immer enttäuscht gewesen wäre, als ich versucht habe ein einfaches Bild über die Form zu bewegen.

    Nächstes Problem:



    VB.NET-Quellcode

    1. Dim a As New List(Of PictureBox)
    2. With a
    3. .Add(PictureBox1)
    4. .Add(PictureBox2)
    5. .Add(PictureBox3)
    6. .Add(PictureBox4)
    7. .Add(PictureBox5)
    8. .Add(PictureBox6)
    9. .Add(PictureBox7)
    10. End With
    11. For i As Integer = 0 To a.Count - 1
    12. If a(i).Bounds.IntersectsWith(Spieler1.Bounds) Then
    13. If a(i).Location.X > Spieler1.Location.X And Spieler1.Location.Y +
    14. Spieler1.Height > a(i).Location.Y And Spieler1.Location.Y < a(i).Top +
    15. a(i).Height Then
    16. ReG = False
    17. Else
    18. ReG = True
    19. End If
    20. End If
    21. Next


    Wenn ReG = False ist, heißt das ich kann mich nicht mehr nach rechts bewegen.

    Das Problem ist, ich kann mich jetzt überhaupt nicht
    mehr nach rechts bewegen, sobald ich eine Wand von der linken Seite aus berühre.
    ReG springt dann wieder auf True, wenn ich von der rechten Seite aus in eine andere Mauer reingehe. Wieso?
    So einen Code würde ich niemals verwenden. Verwende statt And AndAlso, da werden nicht mehr beide Ausdrücke ausgewertet wenn der erste falsch ist. Ich habe dir doch ein Beispiel gegeben. Probiere das umzusetzten (siehe Klassen, GDI+). Wenn du das nicht verstehst kannst du ja fragen.

    Ok, danke.


    Ich werde dann jetzt eben doch versuchen, es mit GDI+ umzusetzen, wenn Ihr mir das so dringend empfiehlt .

    Aber ich weiß noch nicht einmal wie ich anfange, oder meinem Rechteck ein Bild verpasse, geschweige denn
    es zum Mauszeiger hinzudrehen (, was bei der PictureBox ziemlich gut geklappt hat).

    Also hab ich bei GDI+ nicht nur eine Frage, sondern bin ratlos.
    Ich geb dir jetzt mal eine "Inspiration" ^^
    Du hast eine Klasse Player, die könnte ganz grob so aussehen:

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class Player
    3. Public Property Position() As Point
    4. Public Property Size() As Size
    5. Public ReadOnly Property Rectangle() As Rectangle
    6. Get
    7. Return New Rectangle(Position, Size)
    8. End Get
    9. End Property
    10. Public Sub New(ByVal p As Point, ByVal s As Size)
    11. Position = p
    12. Size = s
    13. End Sub
    14. Public Sub New(ByVal r As Rectangle)
    15. Position = r.Location
    16. Size = r.Size
    17. End Sub
    18. End Class


    In deiner Form-Klasse erstellst du eine Instanz der Klasse Player. Das sähe dann so aus:

    VB.NET-Quellcode

    1. Private _player As New Player(New Point(dein x Wert, dein y Wert), New Size(dein width Wert, dein height Wert))


    Und dann musst du nur noch in der Form-Paint zeichnen:

    VB.NET-Quellcode

    1. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    2. e.Graphics.FillRectangle(Farbe, _player.Rectangle)
    3. 'oder wenn du ein Bild malen willst:
    4. e.Graphics.DrawImage(deinBild, _player.Position)
    5. End Sub


    Bei der DrawImage-Methode brauch dein Player die Property Size natürlich nicht mehr, vllt eher eine Property Image.
    Soweit verstanden? Und bitte nicht nur C&P, sondern bitte echt versuchen zu verstehen. :thumbsup:

    Ok, dankesehr.

    Ich hab den Code jetzt soweit, wie ich ihn verstehe, versucht umzuformen:

    VB.NET-Quellcode

    1. Public Position() As Point
    2. Public Size() As Size
    3. Public ReadOnly Property Rectangle() As Rectangle
    4. Get
    5. Return New Rectangle(Position, Size)
    6. End Get
    7. End Property


    Doch bei

    VB.NET-Quellcode

    1. Return New Rectangle(Position, Size)
    akzeptiert er nicht "Position, Size" als Eigenschaft von New Rectangle.
    Wieso?
    dann steht aber bei der Deklaration von Position() und Size(), dass eine Eigenschaft ohne "ReadOnly" oder "WriteOnly"-Bezeichner ein "Get" oder "Set" haben muss ?(

    Des Weiteren steht dann bei

    VB.NET-Quellcode

    1. Public ReadOnly Property Rectangle() As Rectangle
    , dass eine Anweisung nicht innerhalb eines Eigenschaftstexts verwendet werden kann. ?( ?(
    Also bei mir kommt kein Fehler. Kann das eventuell an der Konfiguration der IDE liegen?
    Der Name Size ist schon von System.Drawing.Size "belegt", da muss man sich wohl einen anderen Namen für die Property ausdenken.