Szukaj…
Generowanie liczb losowych
Chociaż GameplayKit
(który jest wprowadzany z iOS 9 SDK) dotyczy implementacji logiki gry, można go również wykorzystać do generowania liczb losowych, co jest bardzo przydatne w aplikacjach i grach.
Oprócz GKRandomSource.sharedRandom
który jest używany w następnych rozdziałach, istnieją trzy dodatkowe typy GKRandomSource
.
- GKARC4RandomSource Który wykorzystuje algorytm ARC4
- GKLinearCongruentialRandomSource Który jest szybkim, ale nie tak losowym
GKRandomSource
- GKMersenneTwisterRandomSource który implementuje algorytm MersenneTwister. Jest wolniejszy, ale bardziej losowy.
W następnym rozdziale używamy tylko metody nextInt()
GKRandomSource
. Oprócz tego istnieje nextBool() -> Bool
i nextUniform() -> Float
Pokolenie
Najpierw zaimportuj GameplayKit
:
Szybki
import GameplayKit
Cel C
#import <GameplayKit/GameplayKit.h>
Następnie, aby wygenerować liczbę losową, użyj tego kodu:
Szybki
let randomNumber = GKRandomSource.sharedRandom().nextInt()
Cel C
int randomNumber = [[GKRandomSource sharedRandom] nextInt];
Uwaga
Funkcja nextInt (), jeśli zostanie użyta bez parametrów, zwróci liczbę losową z przedziału od -2 147 483 648 do 2 147 483 647, łącznie z nimi, więc nie jesteśmy pewni, czy zawsze jest to liczba dodatnia lub niezerowa.
Generowanie liczby od 0 do n
Aby to osiągnąć, powinieneś podać n nextIntWithUpperBound()
:
Szybki
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 10)
Cel C
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 10];
Ten kod da nam liczbę od 0 do 10, łącznie z nimi samymi.
Generowanie liczby od m do n
W tym celu należy utworzyć obiekt GKRandomDistribution
za pomocą GKRandomSource
i przekazać w granicach. Za pomocą GKRandomDistribution
można zmienić zachowanie dystrybucji, takie jak GKGaussianDistribution
lub GKShuffledDistribution
.
Następnie obiekt może być używany jak każdy zwykły GKRandomSource
ponieważ implementuje również protokół GKRandom
.
Szybki
let randomizer = GKRandomDistribution(randomSource: GKRandomSource(), lowestValue: 0, highestValue: 6)
let randomNumberInBounds = randomizer.nextInt()
Cel C jest przestarzały
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: n - m] + m;
Na przykład, aby wygenerować losową liczbę od 3 do 10, użyj tego kodu:
Szybki
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 7) + 3
Cel C jest przestarzały
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 7] + 3;
GKEntity i GKComponent
Istota reprezentuje przedmiot gry, taki jak figurka gracza lub figurka wroga. Ponieważ ten przedmiot niewiele robi bez rąk i nóg, możemy do tego dodać elementy. Aby stworzyć ten system, jabłko ma klasy GKEntity
i GKComponent
.
Załóżmy, że mamy następującą klasę dla następujących rozdziałów:
class Player: GKEntity{}
class PlayerSpriteComponent: GKComponent {}
GKEntity
Jednostka jest kolekcją komponentów i oferuje kilka funkcji dodawania, usuwania i interakcji z jej komponentami.
Chociaż moglibyśmy po prostu użyć GKEntity, często podklasuje się go dla określonego rodzaju bytu gry.
Ważne jest, aby można było dodać składnik klasy tylko raz. W przypadku dodania drugiego komponentu tej samej klasy zastąpi on pierwszy istniejący komponent w GKEntity
let otherComponent = PlayerSpriteComponent()
var player = Player()
player.addComponent(PlayerSpriteComponent())
player.addComponent(otherComponent)
print(player.components.count) //will print 1
print(player.components[0] === otherComponent) // will print true
Możesz zapytać dlaczego. Powodem tego są metody nazywane component(for: T.Type)
która zwraca składnik określonego typu bytu.
let component = player.component(ofType: PlayerSpriteComponent.self)
Oprócz metod komponentów ma także metodę update
, która służy do delegowania czasu delty lub bieżącego czasu logiki gry na jego komponenty.
var player = Player()
player.addComponent(PlayerSpriteComponent())
player.update(deltaTime: 1.0) // will call the update method of the PlayerSpriteComponent added to it
GKComponent
Komponent reprezentuje coś z bytu, na przykład komponent wizualny lub logiczny.
Jeśli wywoływana jest metoda aktualizacji encji, deleguje to do wszystkich swoich komponentów. Przesłonięcie tej metody służy do manipulowania jednostką.
class PlayerSpriteComponent: GKComponent {
override func update(deltaTime seconds: TimeInterval) {
//move the sprite depending on the update time
}
}
Oprócz tego można zastąpić metodę didAddToEntity
i willRemoveFromEntity
aby poinformować inne komponenty o jej usunięciu lub dodaniu.
Aby manipulować innym komponentem wewnątrz komponentu, można uzyskać GKEntity, do którego komponent jest dodawany.
override func update(deltaTime seconds: TimeInterval) {
let controller = self.entity?.component(ofType: PlayerControlComponent.self)
//call methods on the controller
}
O ile jest to możliwe, że nie jest to wspólny wzór, ponieważ przewody te dwa składniki razem.
GKComponentSystem
Chociaż właśnie rozmawialiśmy o użyciu mechanizmu delegowania aktualizacji GKEntity
do aktualizacji GKComponents
istnieje inny sposób aktualizacji GKComponents
który nazywa się GKComponentSystem
.
Jest stosowany w przypadku, gdy wszystkie komponenty określonego typu wymagają aktualizacji za jednym razem.
System GKComponentSystem
jest tworzony dla określonego typu komponentu.
let system = GKComponentSystem(componentClass: PlayerSpriteComponent.self)
Aby dodać komponent, możesz użyć metody add:
system.addComponent(PlayerSpriteComponent())
Ale bardziej powszechnym sposobem jest przekazanie utworzonego obiektu z jego komponentami do GKComponentSystem
a on znajdzie pasujący komponent wewnątrz encji.
system.addComponent(foundIn: player)
Aby zaktualizować wszystkie komponenty określonego typu, wywołaj aktualizację:
system.update(deltaTime: delta)
Jeśli chcesz użyć GKComponentSystem
zamiast mechanizmu aktualizacji opartego na jednostkach, musisz mieć GKComponentSystem
dla każdego komponentu i wywołać aktualizację we wszystkich systemach.