Jump'n'Run mit SDL



  • Hallo zusammen,

    ich wollte mal mit dem SDL ein Jump'n'Run schreiben, hab auch eine grobe Vorstellung wie ich das mit dem Hintergrund und den Gegner mache,
    aber bisher noch keine gute Idee, wie ich checke, ob sich der Spieler auf einer Plattform oder sonstigen Erhöhung befindet.
    Da muss ja eine Kollisionserkennung stattfinden, oder? Muss ich also für jede Erhöhung im Level checken, ob der Spieler sich über ihr befindet und dann sozusagen auf ihr landet und nicht bis auf den Boden fällt?

    Weiß da jemand weiter?
    Generelle Ideens zur Erstellung eines Jump'n'Run sind auch mehr als willkommen 🙂



  • Joa ich denke du musst durch jede Erhöhung "loopen".



  • In Jump & Run Spielen wird meist ein Tile-Set für den "Vordergrund" verwendet (meist auch für den Hintergrund, aber um den geht's ja hier nicht).

    http://en.wikipedia.org/wiki/Tile-based_video_game
    http://en.wikipedia.org/wiki/Tile_engine

    D.h. du hast Kacheln mit fixen Abständen, z.B. 32x32 Pixel pro Kachel. Alle unbeweglichen Dinge mit denen man kollidieren kann, setzt man dann einfach in diesen Raster. Das beschneidet zwar etwas die Freiheiten des Level-Designers. Dafür beschleunigt es ungemein die Kollisionsabfrage mit dem statischen Teil des Levels.
    (Es gibt natürlich auch andere Verfahren mit denen man das ebenso schnell hinbekommt, ohne weitere Beschränkungen, aber die sind komplizierter zu verstehen und aufwendiger umzusetzen.)

    Und bewegliche Elemente gibt es meist so wenige, dass man sich leisten kann einfach alles zu testen was sich momentan am Schirm befindet.

    Viele Spiele frieren auch alle beweglichen Elemente ein, die gerade mehr als eine bestimmte Entfernung vom Spieler bzw. dem "Bildschirmrand" entfernt sind. Sollte aber auf einem PC (der verglichen mit einem Nintendo DS doch etwas mehr Rechenleistung hat) nicht notwendig sein.

    ----

    Und natürlich, wenn die Levels relativ klein bleiben, kann man sich den ganzen Tanz sparen, und einfach immer einen Kollisions-Test mit jedem "Boden-Element" machen. Und das für alle Figuren die rumlaufen.



  • Ich versuch mal grob und schnell zu erklären wie ich das in einem kleinen 2D Jump'n'Run machen würde. Du kannst das für fast alles verwendet, wenn du möchtest.

    Wie hustbaer schon sagte, erstellst du am besten ein Raster. Sagen wir dein Level besteht aus Kacheln ähnlich Super Mario. Die Höhe beträgt 20 und die Breite (bzw. dann die Länge des Levels) 100 Kachel. Du hättest also ein Array[20][100]. In diesem Array kannste jetzt Zeichen speichern, welche das Aussehen deines Levels definiert. Ein kleines Beispiel dazu:

    .............................
    ....~~~~......~~.........~~~.
    .................~~~~........
    .............................
    .............................
    ...xx?x.....xxxxx............
    .............................
    xxxxxxxxxxxxx..xxxxxxxxxxxxxx
    

    . = leer
    x = fester Block
    ? = Fragezeichen Block
    ~ = Wolke

    Deine Figur setzt du irgendwohin, wo du magst. Bei jedem Update überprüfst du nun, wo sich deine Figur befindet und wenn unter ihm ein 'x' ist, dann setzt du ihn auf isFalling. Solange isFalling gesetzt ist, bewegst du ihn runter.

    Du musst die x/y Werte auf die Höhe der Kacheln angleichen. Ein Beispiel:

    Kachel = 50x50 Pixel
    FigurX = 150
    FigurY = 900

    Deine Figur befindet sich im Array[150/50 - 1][900/50 - 1]. Um zu überprüfen ob was unter ihm ist addierst du einfach 1 auf die Höhe.

    Das ist nur sehr sehr grob. Die X- und Y-Werte einer Figur ist nur der Mittelpunkt. Du musst immer den linkesten/rechtesten/obersten/untersten Punkt der Figur für die Kollisionsberechnung nehmen. Wenn sich dann ein 'x' (oder '?') nebenan befindet, dann darf er sich nicht mehr in die Richtung befinden.

    PS: Du kannst das Array dann natürlich auch für das Zeichnen nehmen. Vorallem wenn es ein Objekt-Array ist.



  • Du musst immer den linkesten/rechtesten/obersten/untersten Punkt der Figur für die Kollisionsberechnung nehmen

    Naja, muss man nicht.
    Viele Jump & Run checken für die Spieler-Figur nur einen Punkt. Manche zwei: einen "unten" und einen "oben" - speziell wenn wie bei Mario die Grösse der Figur variieren kann.

    Also man kann es so machen dass man die Spieler-Figur wirklich als Rechteck behandelt zur Kollisionserkennung, muss aber nicht.

    Was Kollision mit Gegnern bzw. allgemein beweglichen Objekten angeht, so kann man auch mit nur einem Punkt auskommen. Nämlich indem man einfach die Kollisions-Regionen (Rechtecke, Kreise bieten sich an) der Gegner entsprechend grösser macht und ggf. verschiebt.



  • Klar, du hast Recht! Ich wollte es aber so simpel wie möglich halten. Wenn man mag, kann man statt einem Hitbox mehrere verteilen oder man nimmt gleich die kleinsten Werte, was ja die Pixel an sich wären.



  • NaaK schrieb:

    Klar, du hast Recht! Ich wollte es aber so simpel wie möglich halten. Wenn man mag, kann man statt einem Hitbox mehrere verteilen oder man nimmt gleich die kleinsten Werte, was ja die Pixel an sich wären.

    Ich finde es simpler nur einen Punkt zu prüfen als ein Rechteck 😕



  • hustbaer schrieb:

    NaaK schrieb:

    Klar, du hast Recht! Ich wollte es aber so simpel wie möglich halten. Wenn man mag, kann man statt einem Hitbox mehrere verteilen oder man nimmt gleich die kleinsten Werte, was ja die Pixel an sich wären.

    Ich finde es simpler nur einen Punkt zu prüfen als ein Rechteck 😕

    Und wie berechnest du die Kollision mit anderen Dingen? Wäre ja blöd, wenn meine Figur halb in der Wand stecken würde. Wieso sollte es simpler sein bei allen Gegnertypen umständlich die Hitboxes zu vergrößern/verschieben als ihre natürlichen Rechtecke zu nehmen? Bei Gegnern die etwas anders aussehen nimmt man mehrere.

    Wenn die Rechtecke dann etwas kleiner sind als die Figuren, dann ist das ganze noch viel besser.



  • Danke für die Tipps!

    Hab' in Ruby schon mal was mit "tile-based" gemacht.
    Hatte die Werte der einzelnen Kacheln damals mit Regulären Ausdrücken
    ausgelesen, aber dürfte sich ja auch in einem Array so prüfen lassen.

    Verstehe nur noch nicht genau, wie ich wirklich nur das überprüfe was sich gerade auf dem Bildschirm befindet (und nicht im ganzen Level)

    Sollte ich einen Array erstellen, in dem sich immer die aktuell zu prüfenden Gegner befinden und den dann durchlaufen bzw beim Laufen des Spielers aktualisieren?

    Kennt jemand ein Spiele-Tutorial in dem ein Jump'n'Run erklärt wird?



  • Barcellona schrieb:

    Verstehe nur noch nicht genau, wie ich wirklich nur das überprüfe was sich gerade auf dem Bildschirm befindet (und nicht im ganzen Level)

    Naja du hast ja dein X und Y aus dem Level von deiner Spielfigur. Ich meine damit nicht die Position auf dem Bildschirm, sondern immer wenn die Figur sich nach links/rechts/oben/unten bewegt, erhöhst/verringerst du diese Werte. Du kannst jetzt gleichzeitig den Bildausschnitt mitbewegen und weißt so, welche Werte aus dem Array berücksichtigt werden müssen. Bei Gegnern allerdings würde ich anders vorgehen. Wenn du es falsch machst, dann kann es sein, dass wenn du zurückläufst und wieder vor, derselbe Gegner immer wieder generiert wird. Es gibt viele Möglichkeiten um das besser zu machen. Zum Beispiel kannst du alle Gegner immer laufen lassen oder du machst neben dem LevelArray eine Gegnerliste die ab einer bestimmten X-Position die Figuren erzeugen lässt und dann nie wieder. Kommt immer drauf an in welchen Dimensionen sich das bewegt.

    Edit:

    Kleiner Tipp vielleicht noch beim bewegen des Bildausschnitts. Wenn du diesen immer mit der Spielfigur bewegst, dann bleibt die Figur immer an einer bestimmten Position des Bildes. Aber du kennst das bestimmt aus Jump'n'runs so, dass der Bildschirm sich erst ab ca. dem 2. Drittel mitläuft. Deswegen überprüfe diesen Wert gleich mit.


Anmelden zum Antworten