In deze korte tutorial zullen we onze platformer-pathfinder uitbreiden zodat hij kan omgaan met eenrichtingsplatforms: blokken waar het personage doorheen kan springen en ook op kan stappen. (Technisch gezien zijn dit tweerichtingsplatforms, omdat je er vanuit beide richtingen doorheen kunt springen, maar laten we de haren niet splitsen!)
U kunt de Unity-demo of de WebGL-versie (100 MB +) spelen om het uiteindelijke resultaat in actie te zien. Gebruik WASD om het personage te verplaatsen, links klikken op een plek om een pad te vinden dat je kunt volgen om er te komen, klik met de rechtermuisknop een cel om de grond op dat punt te wisselen, en middelste muisknop om een eenrichtingsplatform te plaatsen.
Om de eenrichtingsplatforms te verwerken, moeten we een nieuw tegeltype toevoegen aan de kaart:
public enum TileType Empty, Block, OneWay
Eenrichtingsplatforms hebben hetzelfde padgewicht als lege tegels, dat wil zeggen, 1
. Dat komt omdat de speler ze altijd kan passeren bij het springen; ze stoppen hem alleen als hij valt, en dat beïnvloedt op geen enkele manier de beweging van het personage.
We hebben ook een functie nodig die ons laat weten of de tegel op een bepaalde positie specifiek een eenrichtingsplatform is:
public bool IsOneWayPlatform (int x, int y) if (x < 0 || x >= mWidth || Y < 0 || y >= mHeight) return false; return (tegels [x, y] == TileType.OneWay);
Eindelijk moeten we veranderen Map.IsGround
terugbrengen waar
als een tegel een massief blok is of een eenrichtingsplatform:
public bool IsGround (int x, int y) if (x < 0 || x >= mWidth || Y < 0 || y >= mHeight) return false; return (tegels [x, y] == TileType.OneWay || tiles [x, y] == TileType.Block);
Dat is het kaartgedeelte van de code gesorteerd; nu kunnen we aan de pathfinder zelf werken.
We moeten ook twee nieuwe voorwaarden voor het filteren van knooppunten aan onze lijst toevoegen. Vergeet niet dat onze lijst er momenteel zo uitziet:
3
).0
).We willen deze twee voorwaarden toevoegen:
Het eerste punt: we willen altijd een knooppunt opnemen als het op een eenrichtingsplatform is:
if ((mClose.Count == 0) || (mMap.IsOneWayPlatform (fNode.x, fNode.y - 1)) ... mClose.Add (fNode);
Het tweede punt: we moeten een knooppunt opnemen als het zich op de grond bevindt en het vorige knooppunt zich op een eenrichtingsplatform bevindt:
if ((mClose.Count == 0) || (mMap.IsOneWayPlatform (fNode.x, fNode.y - 1)) || (mGrid [fNode.x, fNode.y - 1] == 0 && mMap.IsOneWayPlatform (fPrevNode.x, fPrevNode.y - 1)) ... mClose.Add (fNode);
Hier is een vernieuwde lijst met knooppuntfiltercondities; het algoritme zal elk knooppunt doorlaten dat aan een van de volgende vereisten voldoet:
3
).0
).En hier is de code die al deze voorwaarden controleert:
if ((mClose.Count == 0) || (mMap.IsOneWayPlatform (fNode.x, fNode.y - 1)) || (mGrid [fNode.x, fNode.y - 1] == 0 && mMap.IsOneWayPlatform (fPrevNode.x, fPrevNode.y - 1)) || (fNodeTmp.JumpLength == 3) || (fNextNodeTmp.JumpLength! = 0 && fNodeTmp.JumpLength == 0) // mark sprongen start || (fNodeTmp.JumpLength == 0 && fPrevNodeTmp.JumpLength! = 0) // markeer landingen || (fNode.y> mSluit [mClose.Count - 1] .y && fNode.y> fNodeTmp.PY) || (fNode.y < mClose[mClose.Count - 1].y && fNode.y < fNodeTmp.PY) || ((mMap.IsGround(fNode.x - 1, fNode.y) || mMap.IsGround(fNode.x + 1, fNode.y)) && fNode.y != mClose[mClose.Count - 1].y && fNode.x != mClose[mClose.Count - 1].x)) mClose.Add(fNode);
Ten slotte is hier een voorbeeld van filteren met eenrichtingsplatforms.
Dat is alles wat er is! Het is echt een simpele toevoeging. In de volgende zelfstudie in deze serie voegen we een iets ingewikkelder (maar nog steeds redelijk eenvoudige) uitbreiding toe, waardoor het padvervalsalgoritme omgaat met tekens die groter zijn dan 1x1 blokken.