Sök…
Generera slumpmässiga nummer
Även om GameplayKit
(som introduceras med iOS 9 SDK) handlar om att implementera spellogik, kan det också användas för att generera slumpmässiga nummer, vilket är mycket användbart i appar och spel.
Förutom GKRandomSource.sharedRandom
som används i följande kapitel finns det ytterligare tre typer av GKRandomSource
utanför rutan.
- GKARC4RandomSource Som använder ARC4-algoritmen
- GKLinearCongruentialRandomSource Vilket är en snabb men inte så slumpmässig
GKRandomSource
- GKMersenneTwisterRandomSource Vilket implementerar en MersenneTwister-algoritm. Det är långsammare men mer slumpmässigt.
I följande kapitel använder vi bara nextInt()
för en GKRandomSource
. Utöver detta finns nextBool() -> Bool
och nextUniform() -> Float
Generation
Först importera GameplayKit
:
Snabb
import GameplayKit
Objective-C
#import <GameplayKit/GameplayKit.h>
Använd sedan den här koden för att generera ett slumpmässigt nummer:
Snabb
let randomNumber = GKRandomSource.sharedRandom().nextInt()
Objective-C
int randomNumber = [[GKRandomSource sharedRandom] nextInt];
Notera
Funktionen nextInt (), när den används utan parametrar, kommer att returnera ett slumptal mellan -2,147,483,648 och 2,147,483,647, inklusive sig själva, så vi är inte säkra på att det alltid är ett positivt eller icke-nolltal.
Genererar ett tal från 0 till n
För att uppnå detta bör du ge n till nextIntWithUpperBound()
:
Snabb
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 10)
Objective-C
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 10];
Den här koden ger oss ett nummer mellan 0 och 10, inklusive sig själva.
Genererar ett nummer från m till n
För att göra detta skapar du ett GKRandomDistribution
objekt med en GKRandomSource
och passerar gränserna. En GKRandomDistribution
kan användas för att ändra distributionsbeteendet som GKGaussianDistribution
eller GKShuffledDistribution
.
Efter det kan objektet användas som varje vanlig GKRandomSource
eftersom det implementerar GKRandom
protokollet också.
Snabb
let randomizer = GKRandomDistribution(randomSource: GKRandomSource(), lowestValue: 0, highestValue: 6)
let randomNumberInBounds = randomizer.nextInt()
Objektiv-C föråldrad
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: n - m] + m;
För att till exempel skapa ett slumpmässigt nummer mellan 3 och 10 använder du den här koden:
Snabb
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 7) + 3
Objektiv-C föråldrad
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 7] + 3;
GKEntity och GKComponent
En enhet representerar ett objekt i ett spel som en spelarfigur eller en fiendefigur. Eftersom detta objekt inte gör mycket utan armar och ben kan vi lägga till komponenterna till detta. För att skapa detta system har GKEntity
klasserna GKEntity
och GKComponent
.
Låt oss anta att vi har följande grupp för följande kapitel:
class Player: GKEntity{}
class PlayerSpriteComponent: GKComponent {}
GKEntity
En enhet är en samling komponenter och erbjuder flera funktioner för att lägga till, ta bort och interagera med komponenter i den.
Även om vi bara kunde använda GKEntity är det vanligt att underklassera det för en specifik typ av spelenhet.
Det är viktigt att det bara är möjligt att lägga till en del av en klass en gång. Om du lägger till en andra komponent i samma klass kommer det att åsidosätta den första existerande komponenten inuti 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
Du kan fråga varför. Anledningen till detta är de metoder som kallas component(for: T.Type)
som returnerar komponenten i en specifik typ av enhet.
let component = player.component(ofType: PlayerSpriteComponent.self)
Förutom komponentmetoderna har den en update
som används för att delegera delta-tiden eller aktuell tid för spellogiken till dess komponenter.
var player = Player()
player.addComponent(PlayerSpriteComponent())
player.update(deltaTime: 1.0) // will call the update method of the PlayerSpriteComponent added to it
GKComponent
En komponent representerar något av en enhet, till exempel den visuella komponenten eller den logiska komponenten.
Om en enhets uppdateringsmetod kallas kommer den att delegera detta till alla dess komponenter. Att åsidosätta denna metod används för att manipulera en enhet.
class PlayerSpriteComponent: GKComponent {
override func update(deltaTime seconds: TimeInterval) {
//move the sprite depending on the update time
}
}
Utöver detta är det möjligt att åsidosätta metoden didAddToEntity
och willRemoveFromEntity
att informera andra komponenter om dess borttagning eller lägg till.
För att manipulera en annan komponent inuti en komponent är det möjligt att få den GKEntity som komponenten läggs till.
override func update(deltaTime seconds: TimeInterval) {
let controller = self.entity?.component(ofType: PlayerControlComponent.self)
//call methods on the controller
}
Även om detta är möjligt är det inte ett vanligt mönster eftersom det kopplar samman de två komponenterna.
GKComponentSystem
Medan vi bara pratade om att använda uppdateringsdelegatmekanismen för GKEntity
att uppdatera GKComponents
finns det ett annat sätt att uppdatera GKComponents
som kallas GKComponentSystem
.
Det används om det behövs att alla komponenter av en specifik typ måste uppdateras på en gång.
Ett GKComponentSystem
skapas för en specifik typ av komponent.
let system = GKComponentSystem(componentClass: PlayerSpriteComponent.self)
För att lägga till en komponent kan du använda tilläggsmetoden:
system.addComponent(PlayerSpriteComponent())
Men ett mer vanligt sätt är att skicka den skapade enheten med dess komponenter till GKComponentSystem
och den hittar en matchande komponent inuti enheten.
system.addComponent(foundIn: player)
För att uppdatera alla komponenter av en viss typ, ring uppdateringen:
system.update(deltaTime: delta)
Om du vill använda GKComponentSystem
istället för en enhetsbaserad uppdateringsmekanism måste du ha ett GKComponentSystem
för varje komponent och ringa uppdateringen på alla system.