Wie genau funktionieren Steigungen und Kanten in diesem Szenario?


7

Diese Art von Verhalten gibt es wahrscheinlich auch in anderen Spielen, aber bei den alten Kirby-Spielen - Kirby's Adventure und Kirby's Dreamland 2 - habe ich es bemerkt.

Wenn es sich also um normale Blockplattformen handelt, verhält sich Kirbys Hitbox wie erwartet wie ein einfaches Rechteck, was sich daran zeigt, dass Sie so stehen können:

Kirby stand über einer Kante und wurde nur von ein oder zwei Pixeln seines Fußes gestützt.

Auf der anderen Seite sieht das Stehen auf Hängen wie folgt aus:

Kirby steht am Hang, ein Fuß ist in den Hang eingebettet.

Wie Sie sehen können, wäre die rechteckige Hitbox, wenn wir sie noch verwenden würden, auf halber Höhe. Diese Art von Verhalten lässt sich leicht erklären. Kaufen Sie jedoch eine Hitbox in Form eines „Diamanten“ oder eines „Plus“. (Dies ist wahrscheinlich so, dass es nicht so aussieht, als ob Kirby beim Gehen auf Pisten in der Luft schwebt.)

Plattformen wie diese zeigen eine perfekte Übereinstimmung mit dem 'Diamond'-Hitbox-Modell:

Kirby schwebte am Rand einer geneigten Plattform.Kirby steht auf dem Gipfel zwischen zwei Hängen.

Doch natürlich die erste Screenshot zeigt , dass es für einen rautenförmigen hitbox nicht möglich ist , zu nutzen all die Zeit, oder würden Sie aus jeder Ecke zu ‚Dia‘ in der Lage sein , als ob es eine Steigung war da.

Kirby steht auf der Lippe zwischen einer flachen und geneigten Oberfläche.

Tatsächlich zeigen Formationen wie diese, dass sie nicht einmal auf bestimmten Kacheln basieren können, zumindest nicht auf "vollen" Kacheln. (16x16, Kirbys Größe) (Sonst könnte man nicht den ganzen Weg den Hang hinauf laufen)

Ein anderes Modell, das ich mir ausgedacht habe, ist, dass die Hitbox immer rechteckig ist, aber alle Hänge im Spiel tatsächlich tiefer versenkt sind, als die Kacheln glauben machen würden. Die steckförmigen Plattformen im dritten und vierten Screenshot machen dieses Modell jedoch ungültig, da Sie dann nicht mehr in der oberen Mitte stehen könnten, wie Sie es dort sehen.

Übrigens arbeiten die Hänge an der Decke symmetrisch, wie man an Wasserstufen erkennen kann.

Während es dem Spieler intuitiv erscheint, wie könnten wir ein ähnliches Kollisionssystem programmieren ?

NB Ich bitte nicht um Spekulationen über die internen Abläufe von Kirby (es sei denn, jemand hier hat tatsächlich das Kollisionssystem für diese Spiele entwickelt - unwahrscheinlich). Nur ein allgemeiner Ansatz.


6
Auf dieser Q & A-Site beantworten wir im Allgemeinen keine Fragen historischer Neugier. Diese Ressource soll Entwicklern helfen, Probleme in Spielen zu lösen, die sie gerade entwickeln. Wenn Ihre Frage lautet: "Wie kann ich mit Kollisionen von 2D-Plattformern umgehen?", Finden Sie viele vorhandene Antworten zu diesem Thema. Wie Kirby es gemacht hat, kann eine geeignete Lösung für das Spiel sein, das Sie machen, oder auch nicht. Es ist daher besser, nach dem Problem zu fragen als nach einer bestimmten früheren Lösung. Wenn Sie sich speziell für die historische Mechanik von Kirby interessieren, ist ein ROM-Hacking-Forum möglicherweise der bessere Ort, um nachzufragen.
DMGregory

2
Ich habe die Frage angepasst, um den von @DMGregory festgestellten Aspekt der "historischen Spekulation" zu vermeiden.
Ingenieur

Antworten:


1

Eine andere Möglichkeit, dies zu handhaben, besteht darin, zuerst in der Mitte der Basis des Charakters nach Kollisionen zu suchen und auf die benachbarte überlappende Kachel zurückzugreifen, wenn dort keine Kollision gefunden wird.

Unabhängig davon , welche Fliese wir finden Kollision am Ende in, wir berechnen immer die Bodenhöhe mit dem gleichen Punkt in der Mitte der Basis des Charakters, die hier ich rufe characterFootX& Yjeweils

Unter der Annahme ganzzahliger Pixelkoordinaten in einem 16x16-Kachelraster könnte dies folgendermaßen aussehen:

// Round the character's foot position into its corresponding tile indices.
int tileX = characterFootX >> 4;
int tileY = characterFootY >> 4;

// Fall back on an adjacent tile if this tile has no collision.
if(tiles[tileX, tileY] == EMPTY_TILE) {

    // Round the character's tile up or down to the closest neighbouring tile horizontally.
    // (+1 if we're in the right half of the tile, -1 in the left half)
    tileX += (characterFootX & 0x8) >> 2 - 1;

    // Check tile above, to handle cases where we're 
    // just off the bottom edge of a slope above us.
    if(tiles[tileX, tileY + 1] != EMPTY_TILE)
        tileY++;
}

int floorY = -1;
Tile tile = tiles[tileX, tileY];

if(tile == EMPTY_TILE) {
    // Falling
} else {
    // Get pixel offset from the center of the tile.
    int deltaX = characterFootX - 16 * tileX + 8;

    // Get base height of the tile.
    floorY = tileY * 16 + tile.baseHeight;

    // Adjust height based on slope.
    floorY += tile.slope * deltaX;
}

Ich denke, diese Richtlinie, bei Kollisionen immer die Mitte der Basis des Charakters zu verwenden und nur die einzige gültige Kollisionskachel zu betrachten, die dieser Mitte am nächsten liegt, kann alle in den Screenshots gezeigten Fälle berücksichtigen.


1

Für alte 2D-Spiele waren vollständige Vektorkollisionen zu CPU-schwer und es wurden Verknüpfungen verwendet. Wenn Sie das gleiche Gefühl und die damit verbundenen Kollisionsstörungen wiederherstellen möchten, müssen Sie dieselben Tricks anwenden.

Es gibt zwei verschiedene Arten von Kollisionen: die einfache und schnelle Vollblockkollision (in Blau) und die Sonderfälle (Steigungen in Gelb).

Der gelbe Kreis ist eine 1-Pixel-Kollision.

Bei der vollständigen Kollision (in Blau) wird nur nach vollständigen Blöcken gesucht, wobei spezielle Kacheln (gelb) vollständig ignoriert werden.

Dies ermöglicht das Betreten der Zellgrenzen des Abhangs.

Sobald die Fußpixelprüfung (gelb) feststellt, dass sie sich innerhalb eines Abhangs befindet, wird der Charakter nach Bedarf nach oben gedrückt und die vollständige Kollisionsprüfung deaktiviert, damit Sie den ganzen Weg den Hang hinaufgehen können. Wenn die vollständige Kollision (blau) in einer Hangzelle nicht deaktiviert wurde, stecken Sie auf halber Höhe des Abhangs fest, weil Sie auf die Seite der oberen vollen Zelle treffen.

Geben Sie hier die Bildbeschreibung ein

Optional gibt es eine ähnliche 1-Pixel-Kollision für die linke und rechte Seite in der Mitte, um den Fall einer Wand an einem Hang (in Grün) zu behandeln.

Dies könnte vermieden werden, wenn es nie eine Mauer am Hang gibt und einige Spiele dies taten. Wenn Sie nur zwischen 1 und 8 MHz hatten, haben Sie gespeichert, wo Sie konnten.

Und eine vierte Überprüfung auf dem Kopf auf Deckensteigungen.

Geben Sie hier die Bildbeschreibung ein

Um die Verarbeitung zu sparen, handelte es sich bei den Kollisionen im Sonderfall nicht um einen echten Diamanten, sondern um Schecks in Einzelpixelgröße. Dies funktionierte gut mit den begrenzten Hangformen und stellte sicher, dass die Karte entsprechend bearbeitet wurde, um die Möglichkeit zu vermeiden, den Charakter einzuklemmen.

Sofern Sie nicht auf einen ~ 8-MHz-Mikrocontroller abzielen oder die speziellen Probleme reproduzieren möchten, kann dieser Trick dazu führen, dass eine tatsächliche rautenförmige Kollision jetzt auf modernen Computern verwendet wird.


0

Sie können dies erreichen, indem Sie verschiedene Kollisionsbedingungen verwenden für:

  1. Anpassen der y-Position des Zeichens im "geerdeten" Zustand, um das Verhalten nach dem Gefälle zu erhalten
  2. Übergang vom "geerdeten" in den "fallenden" Zustand

Immer wenn sich der Spielercharakter im "geerdeten" Zustand befindet, machst du einen Raycast von einem Punkt zwischen den Füßen des Charakters gerade nach unten und gerade nach oben. Sehen Sie, wo Sie auf eine Plattformoberfläche treffen, und ändern Sie die y-Koordinate des Player-Sprites so, dass es auf dieser Plattform sitzt. Begrenzen Sie die Länge des Raycasts in beiden Richtungen auf weniger als 1 Kachel und tun Sie nichts, wenn kein Treffer erzielt wird. Dies soll das im 1. und 3. Screenshot gezeigte Verhalten beim Stehen auf Klippen nicht beeinträchtigen, wenn sich unter der Klippe Boden befindet.

Überprüfen Sie danach, ob der Charakter noch geerdet ist. Verwenden Sie einen Line-Cast von der unteren linken zur unteren rechten Ecke des Player-Sprites, um zu überprüfen, ob es noch Kontakt mit einer Plattform hat. Wenn dies nicht der Fall ist, ändern Sie den Status des Spielers von "geerdet" in "fallen".


Beachten Sie, dass Sie dies in einem "modernen" Spiel tun würden, in dem Sie die Möglichkeit haben, Gleitkomma-Arithmetik und geometrisch komplexe Kollider absichtlich zu verwenden. Das Spiel aus dem Beispiel stammt aus einer viel einfacheren Zeit. Die MOS 6502-CPU des NES hatte nicht einmal eine Gleitkommaeinheit, daher mussten sie alles mit ganzzahliger Mathematik tun. Dies bedeutete, dass ihr Code wahrscheinlich viel gröber war. Ich würde annehmen, dass sie eine spezielle Codierung für das Gehen auf den diagonalen Fliesen hatten. Etwas wie:

walkRight:
    x++;
    if (tile[x>>4, y>>4 + 1] == UP_SLOPE)
        y--;
    if (tile[x>>4, y>>4 + 1] == DOWN_SLOPE)
        y++;

0

Es gibt mehrere Möglichkeiten, Kollisionssysteme in 2D-Spielen auszuführen. Ich halte es für unwahrscheinlich, dass in diesem speziellen Spiel kein auf Kacheln basierendes System verwendet wurde. Sprites, die größer als ihre Hitboxen sind, sind ein häufiges Merkmal von auf Kacheln basierenden Plattformspielern, und pixelgenaue Kachelsysteme sind auch für moderne Spiele äußerst nützlich . Das einzig schwierige daran ist, mit Hängen und anderen Hindernissen wie Einbahnstraßen umzugehen. Dieser Artikel bietet eine anständige Erklärung für mehrere Kollisionssysteme, obwohl dies keineswegs die einzige Methode ist.

Ich werde den grundlegenden Algorithmus beschreiben, den der Artikel bietet, aber ich empfehle Ihnen, das Ganze zu lesen, um umfassendere Erklärungen / Einblicke in diese Systeme zu erhalten. Es gibt heutzutage sicherlich effizientere und intuitivere Möglichkeiten, 2D-Kollisionssysteme durchzuführen, aber das kann ich aus Ihrer spezifischen Frage entnehmen.


Das gesamte Level besteht aus einer Tilemap mit allen relevanten Informationen, die auf den Kacheln gespeichert sind (Geländetyp, Spielereffekte usw.), und die Charaktere haben ihre üblichen Kollisions- / Trefferfelder. Viele 2D-Kollisionssysteme, insbesondere für ältere Spiele, beinhalteten pixelgenaue Mathematik und dergleichen.

In jedem Frame bestimmen wir die Bewegung in X- und Y-Richtung. Wenn wir uns nach links bewegen, nehmen wir die äußerste linke Kante der Hitbox (ähnlich wie beim Bewegen nach rechts, oben und unten) und bestimmen, mit welchen Kacheln sich diese Kante schneidet. Gehen Sie durch diese Kacheln, um Hindernisse zu erkennen, die eine Bewegung verhindern würden, und bewegen Sie den Charakter um die Mindestentfernung, die er bewegen kann. Wiederholen Sie diesen Vorgang, bis Sie alle Bewegungen für den Rahmen berechnet haben.

Das war für Karten ohne Steigungen, und das Hinzufügen kann schwierig werden. Wenn Sie keine verrückten Berechnungen durchführen möchten, ist es am besten, die verwendeten Steigungen in einer einheitlichen Größe zu halten. So sollte beispielsweise eine Rampe, die 4 Kacheln lang ist und 1 Kachel nach oben geht, niemals mit Lücken platziert werden oder vorzeitig enden.

Wir müssen zuerst die X-Bewegungsrichtung überprüfen und bevor wir auf Kollisionen prüfen, zuerst prüfen, ob die Kachel, auf der wir uns befinden, eine Steigung ist, und die Kachel nur dann als Kollision registrieren, wenn wir die Steigung hinauffahren (in dieser Fall nach links bewegen). Wenn wir eine Hangkollision haben, müssen wir den Spieler in Y-Richtung nach oben bewegen.

Beispiel für eine Mega Man-Kachelkarte

Ein weiterer Fall, den wir berücksichtigen müssen, ist die Ober- und Unterseite des gesamten Abhangs (die Kachel mit dem blauen Punkt darauf). Um zu verhindern, dass der Charakter stecken bleibt, sollten wir das vollständige Hindernis unmittelbar vor und nach Abschluss der Steigung ignorieren. Der Artikel überprüft dazu, ob die Steigung am linken oder rechten Rand gefüllt ist, was bedeutet, dass wir uns am Ende der Kacheln der Steigung befinden.

Bei vertikalen Bewegungen wird normalerweise die Schwerkraft auf den Charakter angewendet. Überprüfen Sie daher erneut die Kollisionen der Hangplättchen und bewegen Sie den Spieler entsprechend nach unten.

Vieles davon ist pixelgenaue Mathematik und Kollisionen, die stark vom Koordinatensystem abhängen, das Sie für Ihre Tilemap verwenden.


0

Für die Bilder, die Sie gepostet haben, sieht es so aus, als hätte Kirby eine Punktkollision in der Mitte seiner Füße und die Kollisionsboxen der Szenerie erstrecken sich über die Klippenränder hinaus, so dass die Punktkollision Kirby nicht fallen lässt, bis er vollständig jenseits der ist Rand der Klippe.


0

Nun, du hast es selbst beantwortet. Wenn Kirby auf einem "normalen" Plättchen steht, ist der Begrenzungsrahmen rechteckig und wenn er einen Hang berührt, verwandelt er sich in einen Diamanten.


Die tatsächliche Implementierung ist wahrscheinlich das, was DMG vorgeschlagen hat. Modellmäßig ändert der Begrenzungsrahmen "die Form".
AturSams
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.