Pierwszym krokiem procedury konstruowania logiki funkcjonowania planszy jest podjęcie decyzji o tym, jak należy programowo przedstawiać pole planszy.
Aby zaprojektować sposób przedstawiania pola planszy, zastanów się, jak ty i gracz używacie pól planszy. Zwykle gra planszowa składa się z odrębnych obszarów, które są oddzielone od siebie i odróżniają się. Jest to sytuacja inna niż w przypadku przestrzeni świata UEFN.
W przestrzeni świata współrzędne są reprezentowane przez lokalizacje vector3, co oznacza, że współrzędne mogą być tak blisko siebie jak liczby zmiennopozycyjne, co sprawia, że współrzędne świata są bardziej ciągłe niż dyskretne. Ponadto istnieje wiele różnych lokalizacji vector3 i one wszystkie mogą znajdować się na tym samym polu planszy. Można z tego wyciągnąć kilka wniosków:
Pola planszy są odrębnymi polami, więc do przedstawiania lokalizacji można używać typu danych dyskretnych (dane dyskretne przyjmują zakres wartości, co odpowiada liczbom całkowitym), a to oznacza, że należy używać typu
intzamiast typufloat.Plansza jest dwuwymiarowa, więc wystarczy zapisywać lokalizację w dwóch wymiarach. Do przechowywania lokalizacji pola planszy nie jest potrzebna trójwymiarowa struktura danych.
Definiowanie typów danych planszy
Klasa tile_coordinate wskazuje, gdzie na planszy znajduje się pole. Aby utworzyć klasę tile_coordinate, utwórz nowy plik Verse o nazwie utilities.verse. W tym pliku utwórz nowy moduł o nazwie DataTypes.
DataTypes<public> := module:
Do tego modułu dodaj nową klasę TileCoordinate i zdefiniuj komponenty klasy.
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
W bitwie na współrzędne budujesz siatkę planszy 5 x 5. Oznacza to, że musisz zdefiniować granice planszy. W tym celu utwórz nową klasę bounds, która będzie definiować dolną i górną granicę wartości współrzędnych tile_coordinate Left (W lewo) lub Forward (Do przodu).
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
Potrzebujesz struktury danych, która będzie przechowywać granice pojedynczej planszy. W tym celu utwórz nową klasę board_bounds, która będzie definiować dolną i górną granicę dla każdego komponentu klasy tile_coordinate.
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
@editable
Left<public>:int = 0
@editable
Forward<public>:int = 0
Definiowanie planszy
Teraz masz struktury umożliwiające:
Definiowanie reprezentacji pola w przestrzeni planszy.
Definiowanie granic przestrzeni planszy.
Nadal brakuje bardzo ważnej rzeczy – samej planszy. Aby zdefiniować planszę, utwórz nowy plik Verse o nazwie board.verse i dodaj nowe urządzenie Verse o nazwie board.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
Plansza powinna uwzględniać kilka kwestii:
Gdzie znajduje się plansza w przestrzeni świata?
Jakie są granice planszy?
Jaki rozmiar ma pole planszy?
Pierwsza kwestia nie wymaga nowej zmiennej. Można użyć wbudowanego przekształcenia samego urządzenia. Przekształcenie (obiekt transform) urządzenia trybu kreatywnego można uzyskać za pomocą funkcji API GetTransform.
Drugą kwestię można rozwiązać poprzez zdefiniowanie zmiennej board_bounds.
Trzecią kwestię można rozwiązać poprzez zdefiniowanie zmiennej vector2 do śledzenia rozmiaru pola.
Ostatnie dwa są dodawane jako pola do urządzenia planszy.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
Konwertowanie przestrzeni planszy na przestrzeń świata
Następnie określ położenie pola w świecie jako wartość vector3 z użyciem lokalizacji na planszy określonej jako wartość tile_coordinate. Nadaj tej funkcji nazwę ToVector3. Należy to zrobić w obrębie planszy, aby wiedzieć, gdzie znajduje się środek planszy.
Jednak najpierw trzeba rozwiązać pewną szczególną niejednoznaczność. W przypadku podanej wartości tile_coordinate na tym samym polu istnieje wiele różnych lokalizacji vector3 w świecie. W języku matematycznym jest to funkcja jeden-do-wielu. Najlepiej byłoby wybrać pojedynczą lokalizację w świecie, aby wskazać, gdzie znajduje się pole w przestrzeni świata. Naturalnym wyborem jest środek pola.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
Ta funkcja wykonuje następujące czynności:
Uzyskuje przekształcenie planszy w przestrzeni świata.
Uzyskuje lokalizację planszy w przestrzeni świata z przekształcenia.
Oblicza przesunięcie pola wejściowego względem środka planszy.
Dodaje przesunięcie do środka lokalizacji na planszy, aby uzyskać lokalizację względem środka świata.
Konwertowanie przestrzeni świata na przestrzeń planszy
Jeśli masz lokalizację w przestrzeni świata podaną jako wartość vector3, musisz ją przekonwertować na wartość tile_coordinate.
Utwórz funkcję o nazwie ToTileCoordinate. Ta funkcja przyjmuje wartość vector3 jako argument i zwraca wartość tile_coordinate. Gdy lokalizacja w przestrzeni świata jest podana jako wartość vector3, określenie lokalizacji na planszy jako wartości tile_coordinate jest nieco bardziej skomplikowane.
Główną przyczyną komplikacji jest to, że plansza ma postać siatki dyskretnej, przez co w przestrzeni świata istnieje wiele lokalizacji, które nie są częścią planszy. W związku z tym, jeśli masz lokalizację w przestrzeni świata podaną jako wartość vector3, istnieje możliwość, że tej lokalizacji w ogóle nie ma na planszy. To sprawia, że funkcja ToTileCoordinate jest głównym kandydatem do posiadania specyfikatora efektu funkcji <decides>. Jest tak, ponieważ istnieje wiele lokalizacji w świecie gry, które nie występują w przypadku współrzędnych pola. W tym przypadku próba przekonwertowania jednej z nich kończy się niepowodzeniem. Ważne jest, aby wiedzieć, kiedy ta konwersja może zakończyć się powodzeniem. Najpierw funkcja ToTileCoordinate decyduje, czy lokalizacja jest jedną z lokalizacji na planszy, a jeśli tak jest, zwraca tę lokalizację tile_coordinate.
Inną przyczyną komplikacji jest to, że na jedno pole składa się wiele różnych lokalizacji w świecie. W matematyce oznacza to, że funkcja ToTileCoordinate jest funkcją wiele-do-jednego.
Aby wszystko było bardziej zrozumiałe, oddziel część funkcji ToTileCoordinate odpowiedzialną za niepowodzenia, zdefiniuj osobno funkcję IsTileCoordinateOnBoard i wywołuj ją w funkcji ToTileCoordinate.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
Funkcja IsTileCoordinateOnBoard wykonuje następujące czynności:
Określa, czy komponent W lewo współrzędnych pola wejściowego znajduje się między granicami planszy.
Określa, czy komponent Do przodu współrzędnych pola wejściowego znajduje się między granicami planszy.
Działanie funkcji IsTileCoordinateOnBoard kończy się powodzeniem, jeśli współrzędne pola wejściowego znajdują się w granicach planszy. W przeciwnym razie kończy się niepowodzeniem.
Funkcja ToTileCoordinate wykonuje następujące czynności:
Uzyskuje przekształcenie przestrzeni świata planszy.
Uzyskuje lokalizację środka planszy z przestrzeni świata.
Oblicza względne położenie lokalizacji w świecie w odniesieniu do środka planszy.
Konwertuje względną lokalizację w świecie na współrzędne pola.
Określa, czy współrzędne pola znajdują się na planszy.
Zwraca współrzędne pola, jeśli znajdują się na planszy.
Działanie funkcji ToTileCoordinate kończy się powodzeniem tylko wtedy, gdy kończy się powodzeniem działanie funkcji IsTileCoordinateOnBoard .
Przykład
W poniższej sekcji zaprezentowano przykład, w którym wartość tile_coordinate przekonwertowano na wartość vector3, a następnie tę wartość vector3 przekonwertowano z powrotem na wartość tile_coordinate.
Współrzędne pola na wartość Vector3
Załóż, że masz następujące elementy:
Plansza o wymiarach 5 na 5 pól.
Pole gry o wymiarach 512.0 na 512.0 jednostek.
Plansza gry znajduje się w lokalizacji X:= 5000.0, Y:= 0.0, Z := 1000.0 w przestrzeni świata.
Poniżej przedstawiono kroki procedury konwertowania pola o współrzędnych Left := -1, Forward := 2.0 na przestrzeń świata.
ToVector3(tile_coordinate{Left := -1, Forward := 2.0})
BoardTransform:transform = GetTransform()
# BoardTransform := transform{Translation := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}, ...}
CenterOfBoard:vector3 = BoardTransform.Translation
# CenterOfBoard := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
TileOffsetFromCenter:vector3 = vector3:
X := (TileLocation.Forward * TileSize.X)
Dalej opisano kroki, które należy wykonać, aby przekonwertować współrzędne z powrotem przy użyciu funkcji ToTileCoordinate.
ToTileCoordinate(vector3{X := 6024.0, Y := 512.0, Z := 1000.0}):
BoardTransform:transform = GetTransform()
# BoardTransform := transform{Translation := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}, ...}
CenterOfBoard:vector3 = BoardTransform.Translation
# CenterOfBoard := vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
ShiftedWorldLocation:vector3 = WorldLocation - CenterOfBoard
# ShiftedWorldLocation := vector3{X := 6024.0, Y := 512.0, Z := 1000.0} - vector3{X := 5000.0, Y := 0.0, Z := 1000.0}
Ostatnia wartość tile_coordinate jest dokładnie taka sama jak wartość początkowa, co oznacza, że wszystko działa zgodnie z oczekiwaniami.
Podsumowanie
Podsumowując, na tej stronie zaprezentowano następujące kroki:
Definiowanie reprezentacji pola w przestrzeni planszy.
Definiowanie granic przestrzeni planszy.
Definiowanie położenia przestrzeni planszy w przestrzeni świata.
Konwersja pomiędzy przestrzeniami planszy i świata.
Pliki
using { /Verse.org/Simulation }
DataTypes<public> := module:
tile_coordinate<public> := class<concrete>:
Left<public>:int = 0
Forward<public>:int = 0
bounds<public> := class<concrete>:
@editable
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /UnrealEngine.com/Temporary/SpatialMath }
using { /Verse.org/Assets }
using { DataTypes }
using { UtilityFunctions }
board<public> := class(creative_device):
type