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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow