În acest tutorial scurt, vom extinde platformerul platformerului nostru, astfel încât să se poată ocupa de platforme unidirecționale: blocuri pe care personajul să le poată trece și, de asemenea, să facă pasul. (Din punct de vedere tehnic, acestea sunt platforme bidirecționale, deoarece puteți sări prin ele din ambele direcții, dar să nu împărțim firele de păr!)
Puteți reda demonstrația Unity sau versiunea WebGL (100MB +), pentru a vedea rezultatul final în acțiune. Utilizare WASD pentru a muta caracterul, stânga-clic pe un loc pentru a găsi o cale pe care să o poți urma pentru a ajunge acolo, Click dreapta o celulă pentru a comuta la sol în acel moment și -Clic mijloc pentru a plasa o platformă unidirecțională.
Pentru a trata platformele cu sens unic, trebuie să adăugăm pe hartă un nou tip de plăci:
public enum TileType Gol, Blocare, OneWay
Căile de acces pe o singură cale au aceeași greutate pentru traseu ca și plăcile goale - adică, 1
. Acest lucru se datorează faptului că jucătorul poate trece mereu prin ele când sare în sus; îl opresc doar când cade, și asta nu afectează în nici un fel mișcarea personajului.
Avem, de asemenea, nevoie de o funcție care să ne permită să aflăm dacă placa dintr-o anumită poziție este în mod specific o platformă unidirecțională:
boolul public IsOneWayPlatform (int x, int y) if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) return false; retur (plăci [x, y] == TileType.OneWay);
În cele din urmă, trebuie să ne schimbăm Map.IsGround
a se intoarce Adevărat
dacă o piesă este fie un bloc solid sau o platformă unică:
boolul public IsGround (int x, int y) if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) return false; retur (plăci [x, y] == TileType.OneWay || dale [x, y] == TileType.Block);
Aceasta este partea de hartă a codului sortată; acum putem lucra la Pathfinderul însuși.
De asemenea, trebuie să adăugăm două noi condiții de filtrare a nodurilor pe lista noastră. Rețineți că, în prezent, lista noastră arată astfel:
3
).0
).Vrem să adăugăm aceste două condiții:
Primul punct: intotdeauna dorim sa includem un nod daca este pe o platforma cu sens unic:
dacă ((mClose.Count == 0) || (mMap.IsOneWayPlatform (fNode.x, fNode.y - 1)) ... mClose.Add (fNode);
Al doilea punct: trebuie să includem un nod dacă acesta este la sol și nodul anterior este pe o platformă cu sens unic:
dacă (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);
Iată o listă actualizată a condițiilor de filtrare a nodurilor; algoritmul va permite prin orice nod care îndeplinește oricare dintre următoarele cerințe:
3
).0
).Iată codul care verifică toate aceste condiții:
dacă (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) // marchează săriturile începe || (fNodeTmp.JumpLength == 0 && fPrevNodeTmp.JumpLength! = 0) // marchează debarcările || (fNode.y> mClose [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);
În sfârșit, iată un exemplu de filtrare cu platforme unidirecționale.
Cam despre asta e! Este un simplu plus, într-adevăr. În următorul tutorial din această serie, vom adăuga o extensie puțin mai complicată (dar totuși destul de simplă), permițând algoritmului de trasare a traseului să se ocupe de caracterele care sunt mai mari decât blocurile 1x1.