Ricerca…
Generare numeri casuali
Anche se GameplayKit
(introdotto con iOS 9 SDK) riguarda l'implementazione della logica di gioco, potrebbe anche essere utilizzato per generare numeri casuali, il che è molto utile in app e giochi.
Oltre al GKRandomSource.sharedRandom
che viene utilizzato nei seguenti capitoli ci sono tre tipi aggiuntivi di GKRandomSource
'out of the box.
- GKARC4RandomSource Che utilizza l'algoritmo ARC4
- GKLinearCongruentialRandomSource Che è un veloce ma non così casuale
GKRandomSource
- GKMersenneTwisterRandomSource Che implementa un algoritmo MersenneTwister. È più lento ma più casuale.
Nel capitolo seguente usiamo solo il metodo nextInt()
di GKRandomSource
. In aggiunta a questo c'è il nextBool() -> Bool
e il nextUniform() -> Float
Generazione
Innanzitutto, importa GameplayKit
:
veloce
import GameplayKit
Objective-C
#import <GameplayKit/GameplayKit.h>
Quindi, per generare un numero casuale, utilizzare questo codice:
veloce
let randomNumber = GKRandomSource.sharedRandom().nextInt()
Objective-C
int randomNumber = [[GKRandomSource sharedRandom] nextInt];
Nota
La funzione nextInt (), se usata senza parametri, restituirà un numero casuale compreso tra -2,147,483,648 e 2.147.483.647, inclusi se stessi, quindi non siamo sicuri che sia sempre un numero positivo o diverso da zero.
Generando un numero da 0 a n
Per ottenere ciò, devi dare n al metodo nextIntWithUpperBound()
:
veloce
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 10)
Objective-C
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 10];
Questo codice ci darà un numero compreso tra 0 e 10, inclusi se stessi.
Generare un numero da m a n
Per fare questo si crea un oggetto GKRandomDistribution
con un GKRandomSource
e si passa ai limiti. Una GKRandomDistribution
può essere utilizzata per modificare il comportamento di distribuzione come GKGaussianDistribution
o GKShuffledDistribution
.
Successivamente l'oggetto può essere utilizzato come ogni normale GKRandomSource
poiché implementa anche il protocollo GKRandom
.
veloce
let randomizer = GKRandomDistribution(randomSource: GKRandomSource(), lowestValue: 0, highestValue: 6)
let randomNumberInBounds = randomizer.nextInt()
Obiettivo-C obsoleto
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: n - m] + m;
Ad esempio, per generare un numero casuale compreso tra 3 e 10, si utilizza questo codice:
veloce
let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: 7) + 3
Obiettivo-C obsoleto
int randomNumber = [[GKRandomSource sharedRandom] nextIntWithUpperBound: 7] + 3;
GKEntity e GKComponent
Un'entità rappresenta un oggetto di un gioco come una figura del giocatore o una figura nemica. Poiché questo oggetto non fa molto senza braccia e gambe, possiamo aggiungere i componenti a questo. Per creare questo sistema, Apple ha le classi GKEntity
e GKComponent
.
Supponiamo di avere la seguente classe per i seguenti capitoli:
class Player: GKEntity{}
class PlayerSpriteComponent: GKComponent {}
GKEntity
Un'entità è una raccolta di componenti e offre diverse funzioni per aggiungere, rimuovere e interagire con componenti di essa.
Mentre potremmo semplicemente usare GKEntity è normale sottoclassi per un tipo specifico di entità di gioco.
È importante che sia possibile aggiungere un componente di una classe solo una volta. Se aggiungi un secondo componente della stessa classe, sostituirà il primo componente esistente all'interno di 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
Potresti chiedere perché. La ragione di ciò sono i metodi chiamati component(for: T.Type)
che restituiscono il componente di un tipo specifico dell'entità.
let component = player.component(ofType: PlayerSpriteComponent.self)
Oltre ai metodi-componenti, ha un metodo di update
che viene utilizzato per delegare il delta time o l'ora corrente della logica di gioco ai suoi componenti.
var player = Player()
player.addComponent(PlayerSpriteComponent())
player.update(deltaTime: 1.0) // will call the update method of the PlayerSpriteComponent added to it
GKComponent
Un componente rappresenta qualcosa di un'entità, ad esempio il componente visivo o il componente logico.
Se viene chiamato un metodo di aggiornamento di un'entità, lo delegherà a tutti i suoi componenti. L'override di questo metodo viene utilizzata per manipolare un'entità.
class PlayerSpriteComponent: GKComponent {
override func update(deltaTime seconds: TimeInterval) {
//move the sprite depending on the update time
}
}
Oltre a questo è possibile sovrascrivere il metodo didAddToEntity
e willRemoveFromEntity
per informare altri componenti sulla sua rimozione o aggiunta.
Per manipolare un altro componente all'interno di un componente è possibile ottenere GKEntity a cui è aggiunto il componente.
override func update(deltaTime seconds: TimeInterval) {
let controller = self.entity?.component(ofType: PlayerControlComponent.self)
//call methods on the controller
}
Mentre questo è possibile, non è un modello comune, poiché fili i due componenti insieme.
GKComponentSystem
Mentre abbiamo appena parlato dell'utilizzo del meccanismo delegato di aggiornamento di GKEntity
per aggiornare GKComponents
c'è un modo diverso per aggiornare GKComponents
che si chiama GKComponentSystem
.
Viene utilizzato nel caso sia necessario che tutti i componenti di un tipo specifico debbano essere aggiornati in un colpo solo.
Un GKComponentSystem
viene creato per un tipo specifico di componente.
let system = GKComponentSystem(componentClass: PlayerSpriteComponent.self)
Per aggiungere un componente puoi usare il metodo add:
system.addComponent(PlayerSpriteComponent())
Ma un modo più comune è passare l'entità creata con i suoi componenti a GKComponentSystem
e troverà un componente corrispondente all'interno dell'entità.
system.addComponent(foundIn: player)
Per aggiornare tutti i componenti di un tipo specifico chiama l'aggiornamento:
system.update(deltaTime: delta)
Nel caso in cui si desideri utilizzare GKComponentSystem
anziché un meccanismo di aggiornamento basato sull'entità, è necessario disporre di un GKComponentSystem
per ogni componente e chiamare l'aggiornamento su tutti i sistemi.