Jump & Run

  • VB.NET

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von Thorstian.

    Hallo,
    ich wollte ein Jumpen Run spiel programmieren. Alles fertig außer eine Funktion. Die 2D Map soll nicht im Spiel eingebaut werden sondern von einer Datei ausgelesen werden! Wie Teeworlds oder sowas, denn es ist ein MultiPlayer System eingebaut und man kann sein eigenen Maps erstellen.
    Wie soll das gehen?


    mfG
    GirlOnFire

    *Topic verschoben*

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Eine Möglichkeit wäre z.B. folgender Aufbau einer 5x3-Felder-Level-Datei:

    00012
    01401
    03301

    Wobei die Zahlen immer angeben, was das ist, was in diesem Raster ist. 1 könnte z.B. eine Wand sein. Dann könnte man einen Steinblock so darstellen

    00000
    01110
    01110

    Wenn die Startposition des Helden mit 2 bezeichnet würde und er auf dem Steinblock stehen soll, kann man

    02000
    01110
    01110

    in die Datei schreiben.

    Du musst das ganze dann nur mit dem Programm schreiben und lesen können.
    Ich würde das ganz anders machen.
    Zunächst mal solltest du das ganze binär speichern. Die ersten Bytes in der Datei sind die, die immer vorhanden sein müssen und somit immer den gleichen Platz beanspruchen. Das wären z.B. Mapgröße, Startposition, etc., den Rest der Datei bilden dann Byteblöcke, die immer gleich aufgebaut sind. Das könnte z.B. Block-XPos | Block-YPos | Block-ID sein (da kannst du natürlich auch noch weitere Metadaten hinzufügen, wenn du diese brauchst).

    "ich wiederhole"

    ich weis es auch nicht und hatte das gleiche Problem. Google hatte nichts ausgespuckt deshalb hab ich an dem Projekt nicht weitergemacht (schade da es gut war) aber oftmals finde ich werfen die Antwortgeber mehr Fragen auf als zu lösen

    Totorials oder Codebeispiele wären sinnvoll

    Thorstian schrieb:

    Totorials oder Codebeispiele wären sinnvoll


    Genauso wäre auch Rechtschreibung sinnvoll. Die Fragen werden von den Antwortgebern gestellt, weil meist die Frage des Threaderstellers nicht richtig oder eindeutig gestellt ist.

    Wenn ich Zeit habe mach ich da mal was zu, da das ja in letzter Zeit wirklich oft nachgefragt wird. Im Moment bin ich aber beschäftigt mit GameUtils (@Thorstian: da kannst du übrigens mal reinschauen, wenn du schon die ganze Zeit nen Quellcode für Spieleprogrammierung suchst).
    Es wurde doch schon einiges gesagt wie man an die sache rangeht.
    Ihr werdet nicht zu jeden Teil eines Spiels Copy & Paste Code finden*.
    Ihr müsst anfangen, selber Klassen zu schreiben.
    Von nichts kommt nichts!

    Wenn ihr noch Fragen zu dem Thema habt versucht diese zu konkretisieren/näher zu bestimmen.
    Zu kleineren Teilgebieten eines Problems schreibt man auch gerne mal einen fertigen Quellcode, um zu zeigen
    wie man das ganze machen kann.

    Nur: "Maps, erstellen, speichern und laden! Wie geht das? Tutorial oder Code!?" geht nicht.
    Es hat keiner Lust euch das gesamte Spiel vor zu schreiben, damit ihr nur noch kopieren & einfügen,
    sowie euren Namen drunter setzen müsst.


    * Obwohl eig. schon, solange einem die Sprache egal ist.
    Zu bedenken ist aber das man das Zeug nicht einfach zusammen kopieren kann.

    GirlOnFire schrieb:

    Rechtschreibung ist doch egal...


    Finde ich nicht, war ja auch nicht auf dich bezogen. Mir hat einfach nicht die "Tonart", gefallen mit der Thorstian hier redet.

    Artentus schrieb:

    Wenn ich Zeit habe mach ich da mal was zu


    Wäre echt super, sowas kann jeder mal gebrauchen. Ich hatte mal ein Programm in C# XNA gesehen, in denen die Farbe in einer Datei ausgelesen wurde und jeder Farbe ein Block zugewiesen war. Wäre das viel schwerer in der Umsetzung? Wäre bei editieren viel leichter, da man im Prinzip nur zeichnen müsste und schon hätte man ein Level.

    //EDIT:

    Ich hatte eine Idee zum Map erstellen, ist wohl etwas umständlich:

    Hier eine Klasse GameObject

    VB.NET-Quellcode

    1. Option Strict On
    2. Public Class GameObject
    3. Public Enum ObjectTyp
    4. Wall
    5. Air
    6. End Enum
    7. Private _point As Point
    8. Private _size As Size
    9. Private _typ As ObjectTyp
    10. Public Sub New(p As Point, s As Size, ByVal typ As ObjectTyp)
    11. _point = p
    12. _size = s
    13. _typ = typ
    14. End Sub
    15. Public Property Pos As Point
    16. Get
    17. Return _point
    18. End Get
    19. Set(value As Point)
    20. _point = value
    21. End Set
    22. End Property
    23. Public ReadOnly Property Size As Size
    24. Get
    25. Return _size
    26. End Get
    27. End Property
    28. Public ReadOnly Property Typ As ObjectTyp
    29. Get
    30. Return _typ
    31. End Get
    32. End Property
    33. Public ReadOnly Property Collision As Boolean
    34. Get
    35. Select Case _typ
    36. Case ObjectTyp.Air
    37. Return False
    38. Case ObjectTyp.Wall
    39. Return True
    40. Case Else
    41. Return False
    42. End Select
    43. End Get
    44. End Property
    45. End Class


    Ich wollte dann eine Klasse Map mit einer List(of GameObject) schreiben:

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Public Class Map
    4. Private _map As New List(Of GameObject)
    5. Private _path As String
    6. Public Sub New(ByVal path As String)
    7. _path = path
    8. End Sub
    9. Public ReadOnly Property Path As String
    10. Get
    11. Return _path
    12. End Get
    13. End Property
    14. Public Function LoadMap() As Boolean
    15. Try
    16. Using streamr As New StreamReader(_path)
    17. End Using
    18. Return True
    19. Catch
    20. Return False
    21. End Try
    22. End Function
    23. End Class


    Und in dem Using-Block hänge ich jetzt ^^

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

    @Artentus
    Ich versuch mal was, korrigier mich bitte, falls ich falsch liege ;)

    @GirlOnFire
    @Thorstian
    Grundsätzlich muss man schonmal vorneweg sagen, dass es zwei Methoden gibt, eine solche Map zu speichern:
    Indem man einfach den "Inhalt" eines jeden Blockes speichert, das Ergebnis sieht beispielsweise so aus:

    Quellcode

    1. 0 0 1 1 1 1 1 0 0
    2. 0 0 1 0 0 0 1 0 0
    3. 0 0 1 0 0 0 1 0 0
    4. 0 0 1 0 0 0 1 0 0
    5. 0 0 1 1 1 1 1 0 0

    Bei der zweiten sieht das Ergebnis eher so aus:

    XML-Quellcode

    1. <object id="1" location="3, 1"/>
    2. <object id="1" location="4, 1"/>
    3. <object id="1" location="5, 1"/>
    4. <object id="1" location="6, 1"/>
    5. <object id="1" location="7, 1"/>
    6. <object id="1" location="3, 2"/>
    7. <object id="1" location="7, 2"/>
    8. <object id="1" location="3, 3"/>
    9. <object id="1" location="7, 3"/>
    10. <object id="1" location="3, 4"/>
    11. <object id="1" location="7, 4"/>
    12. <object id="1" location="3, 5"/>
    13. <object id="1" location="4, 5"/>
    14. <object id="1" location="5, 5"/>
    15. <object id="1" location="6, 5"/>
    16. <object id="1" location="7, 5"/>

    Diese beiden Maps stellen das gleiche dar, eine Map, welche folgendermaßen aussieht:
    ▒▒█████▒▒
    ▒▒█▒▒▒█▒▒
    ▒▒█▒▒▒█▒▒
    ▒▒█▒▒▒█▒▒
    ▒▒█████▒▒
    Ne kleine Anmerkung am Rande: Natürlich würde man die Maps kompakter speichern, das Prinzip wäre aber dasselbe.

    Aber was haben wir eigetlich für Prinzipien hier vor uns stehen bzw. was ist der Unterschied?
    Nummer 1 speichert einfach die ID eines jeden "Feldes", sie ist zwar oft kompakter aber nicht fähig, über die Kästchenstruktur hinaus Daten zu speichern.
    Nummer 2 hingegen speichert einen Eintrag, beispielsweise vom Typ "Objekt" und gibt dem Objekt gewisse Eigenschaften mit, etwa die ID und wo das Objekt sich befindet. Diese Informationen sind allerdings erweiterbar, es lassen sich beliebig viele Informationen hinzufügen. Außerdem können sich auch mehrere Objekte an derselben Position befinden. Dadurch hat Variante 2 einen großen Vorteil gegenüber Variante 1, sie lässt sich einfach erweitern. Außerdem schleppt Variante 1 noch zusätzlich die unnötigen Informationen der leeren Felder mit.

    Das musst du jetzt noch mit deinem schon vorhandenen System veknüpfen und fertig :).
    Hi ( : !

    Auf der Suche nach Hilfesuchenden, hab ich diesen Thread entdeckt.

    Und BUMM hab ich mich hier , im wundervollen Forum registriert, um Ihm bzw. auch den Anderen, die Hilfe zu geben:

    Der nachfolgende Code ist, meiner Meinung nach, übersichtlich und leicht zu verstehen!

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Dim path As String = "tile.txt"
    4. Dim read As New StreamReader(Path)
    5. Dim Y_ As String
    6. Dim PosX, PosY As Integer
    7. Dim s As String() = File.ReadAllLines(path)
    8. Dim Buffer As String
    9. '---Read_tile---
    10. Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    11. Try
    12. For y = 0 To Buffer.Length
    13. Y_ = s(y)
    14. For x = 0 To Y_.Length / 2
    15. Dim SplitSpace As String() = Y_.Split(" "c)
    16. Select Case SplitSpace(CInt(x))
    17. Case "0"
    18. Exit Select
    19. Case "1"
    20. PosX = Convert.ToInt32(x * 50)
    21. PosY = y * 50
    22. e.Graphics.FillRectangle(Brushes.Red, New Rectangle(PosX, PosY, 30, 30))
    23. End Select
    24. Next
    25. Next
    26. Catch
    27. End Try
    28. End Sub
    29. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    30. Buffer = read.ReadToEnd()
    31. End Sub
    32. End Class


    Nun zur Erklärung:

    VB.NET-Quellcode

    1. Dim path As String = "tile.txt"
    2. Dim read As New StreamReader(Path)


    Eine neue Instanz des StreamReaders wird deklariert.
    Nachfolgend wird der Pfad dem Reader beschickt.
    Das heißt, die im "path" angegebene Datei wird gelesen.

    VB.NET-Quellcode

    1. Dim Y_ As String
    2. Dim PosX, PosY As Integer
    3. Dim s As String() = File.ReadAllLines("tile.txt")


    "Y_" wird später gebraucht.
    In diesem wird, die in der Zeile
    enthaltene Zeichen, dem Y_-String zugefügt.

    PosX,PosY ist selbsterklärend.
    File.ReadAllLines bietet sich hierfür perfekt.
    Denn diesem kann ich die Zeile angeben (0 ist Zeile 1, 1 ist Zeile 2 etc.).
    Dieses spielt für die Y-Achse eine entscheidende Rolle.

    Nun zum Zeichnen des Tiles:

    VB.NET-Quellcode

    1. Try
    2. For y = 0 To read.ReadToEnd.Length
    3. Y_ = s(y)
    4. For x = 0 To Y_.Length / 2
    5. Dim SplitSpace As String() = Y_.Split(" "c)
    6. Select Case SplitSpace(CInt(x))
    7. Case "0"
    8. Exit Select
    9. Case "1"
    10. PosX = Convert.ToInt32(x * 50)
    11. PosY = y * 50
    12. e.Graphics.FillRectangle(Brushes.Red, New Rectangle(PosX, PosY, 30, 30))
    13. End Select
    14. Next
    15. Next
    16. Catch
    17. End Try

    Es wird die Menge der Zeichen in der Datei aufgelistet.
    Das ist gleichermaßen auch die Arraymaximum-Size.
    Nun, wie oben beschrieben, wird pro Zeile dem Y_-String, die Zeichen der Zeile zugefügt.
    Dann wird auf .Split(" "c) geprüft und gesplittet, und die X bzw. Y -Werte *50 multipliziert, um es in Echtzeit nicht überlappend zu sehen.

    Die Formation muss so aussehen:

    Quellcode

    1. 1 0 0 0 0 0 1
    2. 1 0 0 0 0 0 1
    3. 1 0 0 0 0 0 1
    4. 1 1 1 1 1 1 1


    Grüße, CProgramming .

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „CProgramming“ ()

    @CProgramming
    Schonmal nicht schlecht, jedoch ist diese Methode, wie ich oben schon beschrieben hab, nicht so gut geeignet wie die andere beschriebene, außerdem fehlt dem Code etwas die Abstraktion.
    Aber dazu wird Artentus eh bald mit einem super Tutorial kommen, das alles andere in den Schatten stellt :D.

    Btw. Willkommen im Forum :thumbsup: