Werken met SKTransition

Deze tutorial leert je combineren UIKit uitzichten en de SKTransition klasse om mooie, aangepaste overgangen tussen verschillende te maken SKScenes. Lees verder!


Laatste voorbeeld

Illustratie van eindresultaat.

1. Overgangen tussen scènes

Scènes zijn interfaces die verschillende weergave-objecten bevatten. Normaal ontwerp je verschillende scènes voor elk deel van je spel en gebruik je zo nodig overgangen tussen de scènes. U kunt bijvoorbeeld verschillende scèneklassen maken om een ​​of alle van de volgende concepten weer te geven:

  • Een scène in het hoofdmenu om de moeilijkheidsgraad van een specifiek niveau te kiezen dat de gebruiker wil spelen.
  • Een scène om de details van het geluid en de muziekeffecten van een game te configureren.
  • Een scène die de interface voor spelen en spelen biedt.
  • Een scène die de online leaderboard-interface biedt.
  • Een scène die actuele en algehele spelprestaties biedt.

Zoals u kunt zien, kan een scène alles zijn dat de programmeur zou willen maken. Doorgaans gaat u over op een nieuwe scène op basis van speldoel-doelstellingen of directe gebruikersinvoer. Bijvoorbeeld, als de timer afloopt, kan een nieuwe scène met een "game over" worden gepresenteerd. Als een gebruiker op een optieknop drukt, kunt u ook overstappen naar een nieuwe scène om de spelinstellingen te configureren. Merk op dat, in de overgangsfase, de scène-eigenschap onmiddellijk wordt bijgewerkt om naar de nieuwe scène te wijzen. Hierna vindt de overgang plaats.

Een overgang kan ook een overgangsobject (een effect of een animatie) hebben. Dat object zal een dynamische, mooie presentatie creëren wanneer de overgang plaatsvindt. Er zijn verschillende objecten en voor een volledige en officiële referentie dient u de SKTransition-klasseverwijzing te raadplegen.


2. Klasse-methoden

De SKTransition klas presenteert verschillende methoden en twee eigenschappen (meer daarover later). Het doel van alle methoden is om een ​​glanzende en dynamische overgang tussen scènes te maken. De klassemethoden kunnen worden onderverdeeld in vier hoofdsecties:

  • Met duur: Overgangen die zich over een bepaalde periode voordoen.
  • Met kleur: Overgangen die een a zullen gebruiken UIColor object om de inherente overgang te kleuren.
  • Met richting: Overgangen die vanuit een bepaalde richting worden gemaakt.
  • Met CIFilter: Overgangen die een aangepast filter gebruiken om een ​​visueel effect in de overgang te produceren.

Looptijd en Kleur zijn eenvoudige objecten, maar beide Richting en CIFilter zijn niet.

Als de naamsuggesties betekent de richtingseigenschap dat de overgang in een specifieke richting zal plaatsvinden. De richtingseigenschap kan een van de vier constanten hebben. Deze constanten worden verklaard als een NS_ENUM, zoals dit:

 typedef NS_ENUM (NSInteger, SKTransitionDirection) SKTransitionDirectionUp, SKTransitionDirectionDown, SKTransitionDirectionRight, SKTransitionDirectionLeft,;

CIFilter is zelfs nog robuuster dan Richting omdat het ook een referentieklasse is met klassemethoden, instantiemethoden en eigenschappen. Deze tutorial behandelt de CIFilter in de diepte, maar het zal een voorbeeld zijn van hoe het te gebruiken om een ​​aangepast filter en het inherente te maken SKTransition. Een aanvullende opmerking over de CIFilter klasse: het ondersteunt tientallen effecten, maar niet alle worden ondersteund door de nieuwste versie van iOS. Raadpleeg de Core Image Filter Reference om de compatibiliteitslijst te bekijken.

Merk op dat u verschillende "gegroepeerde methoden" kunt gebruiken om een SKTransiton. Maar hoe weet u welke kunnen worden gecombineerd? Hiervoor moet u naar de handtekening van de methode kijken en de eigenschappen bepalen die door elke methode worden geaccepteerd.

Laten we bijvoorbeeld drie methoden analyseren om te zien wat ze kunnen verwerken:

  • doorsOpenVerticalWithDuration:
  • fadeWithColor: Duur:
  • revealWithDirection: Duur:

Zoals eerder vermeld, kunt u met de naam van de methoden snel begrijpen wat elke methode kan doen. Om uit te werken, de doorsOpenVerticalWithDuration: methode houdt alleen rekening met een duur van The fadeWithColor: Duur: methode gebruikt zowel een kleur als een duur. U moet eerst een definiëren UIColor object en vervolgens een duur. De revealWithDirection: Duur: methode gebruikt alleen een richting, die op zijn beurt een van de vier eigenschappen kan zijn. Merk op dat u ook het. Kunt verlengen SKTransition klasse om aangepaste overgangen en join te maken Looptijd, Kleur, Richting, en CIFilter.


onthul de richting (UP) illustratie

3. Klasse-eigenschappen

De SKTransition klasse heeft slechts twee eigenschappen: pausesIncomingScene en pausesOutgoingScene. Beide configureren of animaties worden afgespeeld tijdens de overgang en beide eigenschappen zijn Boolean waarden. Het verschil is als volgt:

  • pausesIncomingScene bepaalt of de inkomende scène is gepauzeerd tijdens de overgang.
  • pausesOutgoingScene bepaalt of de uitgaande scène is gepauzeerd tijdens de overgang.

Omdat beide zijn Boolean waarden, de definitie is eenvoudig en kan worden begrepen in het volgende fragment:

 // andere code ... transitionCrossFade = [SKTransition crossFadeWithDuration: 1]; transitionCrossFade.pausesIncomingScene = TRUE; transitionDoorsCloseHorizontal = [SKTransition doorsCloseHorizontalWithDuration: 2]; transitionDoorsCloseHorizontal.pausesOutgoingScene = FALSE;

De pausesIncomingScene en pausesOutgoingScene eigenschappen van het overgangsobject bepalen welke animaties tijdens de overgang worden afgespeeld. Standaard blijven beide scènes animatie verwerken tijdens de overgang. Mogelijk wilt u een of beide scènes echter pauzeren totdat de overgang is voltooid.


4. Het zelfstudieproject

Nu dat je de basisprincipes kent van de SKTransition klasse, kunt u nu de programmeerfase starten.

Stap 1

De eerste stap is om Xcode te openen en een nieuwe te starten SpriteKit project. Voeg vervolgens nog een toe Doelstelling C klasse genoemd TransitionResult en een superklasse van SKScene.

Het doel van dit project is om twee klassen te hebben die tussen hen worden uitgewisseld. De eerste (Mijn scene al gedefinieerd door de Xcode) bevat een UITableView die de referentie naar elk zal bevatten SKTransition. De seconde (TransitionResult) wordt de doelscène na een overgang.

Wanneer de gebruiker na een overgang op het scherm tikt, wordt deze opnieuw overgedragen naar Mijn scene.

Stap 2

In MyScene.h, je declareert 3 objecten: a UITableView, UISlider, en een NSArray. De UITableView toont de namen van elke overgang, de UISlider definieert de Looptijd van die overgang, en de NSArray zal de namen van elk bevatten SKTransition. De laatste MyScene.h code zal vergelijkbaar zijn met dit fragment:

 @property (behouden, niet-atomisch) IBOutlet UITableView * tableView; @property (nonatomic, retain) IBOutlet UISlider * sliderTimer; @property (strong, nonatomic) NSArray * transitionsArray;

Stap 3

Richt nu uw aandacht in de Mijn scene implementatiebestand.

De eerste stap is om de -(Id) initWithSize: (CGSize) formaat methode om de bovengenoemde objecten te initialiseren. Een mogelijke configuratie-instelling is de volgende:

 _tableView = [[UITableView alloc] initWithFrame: CGRectMake (CGRectGetMinX (self.frame), CGRectGetMinY (self.frame) +20, CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame) -80)]; _tableView.dataSource = zelf; _tableView.delegate = zelf; _sliderTimer = [[UISlider alloc] initWithFrame: CGRectMake (CGRectGetMidX (self.frame) -70, CGRectGetMaxY (self.frame) -40, 140, 3)]; [_sliderTimer addTarget: self action: @selector (sliderAction) forControlEvents: UIControlEventValueChanged]; [_sliderTimer-set Achtergrondkleur: [UIColor clearColor]]; _sliderTimer.minimumValue = 1; _sliderTimer.maximumValue = 4; _sliderTimer.continuous = YES; _sliderTimer.value = 1; _transitionsArray = [[NSArray alloc] initWithObjects: @ "crossFadeWithDuration", @ "doorsCloseHorizontalWithDuration", @ "doorsCloseVerticalWithDuration", @ "doorsOpenHorizontalWithDuration", @ "doorsOpenVerticalWithDuration", @ "doorwayWithDuration", @ "fadeWithColor: duration", @ "fadeWithDuration" , @ "flipHorizontalWithDuration", @ "flipVerticalWithDuration", @ "moveInWithDirectionDown: duration", @ "moveInWithDirectionUp: duration", @ "moveInWithDirectionLeft: duration", @ "moveInWithDirectionRight: duration", @ "pushWithDirection: duration", @ "revealWithDirection: duration ", @" transitionWithCIFilter: duration ", nihil];

Er wordt echter een waarschuwing weergegeven sinds de sliderAction ontbreekt. De methode zal in real time het transitionTimerText rekening houden met de UISlider waarde.

 -(void) sliderAction transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Transition Duration:% f", _sliderTimer.value]; 

Houd er rekening mee dat de weergaven, locatie, configuratie en lay-out volledig configureerbaar zijn. Als u wilt, kunt u dit afstemmen op uw belangen. Bovendien voegt u een toe SKLabelNode om het te bewaren en weer te geven UISlider waarde. Die waarde zal representatief zijn voor de SKTransition-duur bijwerkingen. Voeg de toe SKLabelNode * transitionTimerText naar uw implementatiebestand en de bijbehorende initialisatie zal zijn:

 transitionTimerText = [SKLabelNode labelNodeWithFontNamed: @ "Chalkduster"]; transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Transitieduur:% f", _sliderTimer.value]; transitionTimerText.fontSize = 10; transitionTimerText.color = [SKColor colorWithRed: 0 green: 0 blue: 0 alpha: 1]; transitionTimerText.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMinY (self.frame) +45);

Stap 4

Nu de objecten zijn geconfigureerd, hoeft u ze alleen maar toe te voegen aan de scène. Daarvoor gebruikt u de -(void) didMoveToView: (SKView *) weergave methode. Voeg het toe aan uw bestand en voeg binnen de bovenstaande weergaven toe aan de hoofdweergave:

 -(void) didMoveToView: (SKView *) view [self addChild: transitionTimerText]; [self.scene.view addSubview: _sliderTimer]; [self.scene.view addSubview: _tableView]; 

Als u het project nu uitvoert, ziet u twee objecten op het scherm: UISlider en een SKLabelNode.

Stap 5

De volgende stap is om de SKTransition methoden in de UITableView. Hiervoor moet je je aanpassen MyScene.h bestand en uw klas uitbreiden met de protocols. De laatste MyScene.h zou er als volgt uit moeten zien:

 @interface MyScene: SKScene 

Ga terug naar het implementatiebestand en je krijgt een waarschuwing te zien. Die waarschuwing zegt dat je extra methoden moet implementeren die inherent zijn aan de UITableView. De benodigde methoden zijn: -(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sectie en -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath. De eerste geeft het aantal rijen in de tabel terug, terwijl de tweede de logica voor elke cel in de tabel verwerkt. Voor aanvullende opmerkingen over de UITableView klas, moet u de officiële referentieklasse raadplegen.

De eerste methode is eenvoudig en is slechts één regel:

 -(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section return [_transitionsArray count]; 

De tweede methode is complexer omdat we de eigenschappen en configuraties van de tabelcellen (celinhoud) moeten definiëren. In dit voorbeeld gebruikt u een eenvoudig UITableViewCellStyleSubtitle. Als u problemen ondervindt bij het schrijven van de methode, wordt de volledige versie hieronder weergegeven:

 -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath NSString * transitions = [_transitionsArray objectAtIndex: indexPath.row]; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: @ "Identifier"]; if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: @ "Identifier"];  [cell.textLabel setText: overgangen]; terugkeer cel; 

Voer nu uw code uit en u zou elke cellijn met een unieke naam moeten zien. Elke naam vertegenwoordigt het inherente SKTransiton gebruikt als de gebruiker op die cel tikt. U zult ook opmerken dat de UITableView heeft geen titel. Laten we dat oplossen!

Stap 6

Voeg de volgende methode toe: - (NSString *) tableView: (UITableView *) tableView titleForHeaderInSection: (NSInteger) sectie. Voeg binnen deze methode de volgende code toe:

 NSString * sectionName; switch (sectie) case 0: sectionName = NSLocalizedString (@ "SKTransition List", @ "SKTransition List"); breken; standaard: sectionName = @ ""; breken;  return sectionName;

Deze methode mag meerdere titels hebben voor meerdere UITableView secties. We hebben echter maar één sectie, dus de titel is "SKTransition List" (of een andere naar keuze).

Stap 7

Op dit punt moet u gebruikersinteractie toevoegen aan de cellen. Hiervoor is nog een extra methode nodig. Deze keer de -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath methode moet worden aangeroepen. Deze methode is lang, maar het is eenvoudig te begrijpen. Je zal de nodige middelen toewijzen voor elk SKTransition en, gebaseerd op de getikte cel, zul je een andere presenteren SKScene.

De eerste stap is het importeren van TransitionResult headerbestand en definieer vervolgens a TransitionResult object voor de resulterende SKScene. Bekijk het volgende om dit in actie te zien:

 TransitionResult * transitionResult; SKTransition * transitionCross Fade; SKTransition * transitionDoorsCloseHorizontal; SKTransition * transitionDoorsCloseVertical; SKTransition * transitiondoorsOpenHorizontal; SKTransition * transitionDoorsOpenVertical; SKTransition * transitionDoorway; SKTransition * transitionFadeWithColor; SKTransition * transitionFadeWithDuration; SKTransition * transitionFlipHorizontal; SKTransition * transitionFlipVertical; SKTransition * transitionMoveInWithDirectionDown; SKTransition * transitionMoveInWithDirectionUp; SKTransition * transitionMoveInWithDirectionLeft; SKTransition * transitionMoveInWithDirectionRight; SKTransition * transitionPushWithDirection; SKTransition * transitionRevealWithDirectionUp; SKTransition * transitionWithCIFilter;

Nu, in de -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath methode, is het tijd om de nodige middelen toe te wijzen. De volledige code is:

 transitionCrossFade = [SKTransition crossFadeWithDuration: _sliderTimer.value]; transitionCrossFade.pausesIncomingScene = TRUE; transitionDoorsCloseHorizontal = [SKTransition doorsCloseHorizontalWithDuration: _sliderTimer.value]; transitionDoorsCloseHorizontal.pausesOutgoingScene = FALSE; transitionDoorsCloseVertical = [SKTransition doorsCloseVerticalWithDuration: _sliderTimer.value]; transitiondoorsOpenHorizontal = [SKTransition doorsOpenHorizontalWithDuration: _sliderTimer.value]; transitionDoorsOpenVertical = [SKTransition doorsOpenVerticalWithDuration: _sliderTimer.value]; transitionDoorway = [SKTransation doorwayWithDuration: _sliderTimer.value]; transitionFadeWithColor = [SKTransition fadeWithColor: [UIColor yellowColor] duration: _sliderTimer.value]; transitionFadeWithDuration = [SKTransition fadeWithDuration: _sliderTimer.value]; transitionFlipHorizontal = [SKTransition flipHorizontalWithDuration: _sliderTimer.value]; transitionFlipVertical = [SKTransition flipVerticalWithDuration: _sliderTimer.value]; transitionMoveInWithDirectionDown = [SKTransition moveInWithDirection: SKTransitionDirectionDown duration: _sliderTimer.value]; transitionMoveInWithDirectionUp = [SKTransition moveInWithDirection: SKTransitionDirectionUp duration: _sliderTimer.value]; transitionMoveInWithDirectionLeft = [SKTransition moveInWithDirection: SKTransitionDirectionLeft duration: _sliderTimer.value]; transitionMoveInWithDirectionRight = [SKTransition moveInWithDirection: SKTransitionDirectionRechtsduur: _sliderTimer.value]; transitionPushWithDirection = [SKTransition pushWithDirection: SKTransitionDirectionDown duration: _sliderTimer.value]; transitionRevealWithDirectionUp = [SKTransition revealWithDirection: SKTransitionDirectionUp duration: _sliderTimer.value]; CGRect screenRect = [[UIScreen mainScreen] bounds]; CIVector * extent = [CIVector vectorWithX: 0 Y: 0 Z: screenRect.size.width W: screenRect.size.height]; transitionWithCIFilter = [SKTransition transitionWithCIFilter: [CIFilter filterWithName: @ "CIFlashTransition" keysAndValues: @ "inputExtent", extent, @ "inputCenter", [CIVector vectorWithX: 0.3 * screenRect.size.width Y: 0.7 * screenRect.size.height], @ "inputColor", [CIColor colorWithRed: 1.0 green: 0.8 blue: 0.6 alpha: 1], @ "inputMaxStriationRadius", @ 2.5, @ "inputStriationStrength", @ 0.5, @ "inputStriationContrast", @ 1.37, @ "inputFadeThreshold", @ 0.85, nul] duur: _sliderTimer.value]; transitionResult = [[TransitionResult alloc] initWithSize: CGSizeMake (CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame))]; switch (indexPath.row) case 0: [self.scene.view presentScene: transitionResult transition: transitionCrossFade]; [self removeUIKitViews]; breken; case 1: [self.scene.view presentScene: transitionResult transition: transitionDoorsCloseHorizontal]; [self removeUIKitViews]; breken; case 2: [self.scene.view presentScene: transitionResult transition: transitionDoorsCloseVertical]; [self removeUIKitViews]; breken; case 3: [self.scene.view presentScene: transitionResult transition: transitiondoorsOpenHorizontal]; [self removeUIKitViews]; breken; case 4: [self.scene.view presentScene: transitionResult transition: transitionDoorsOpenVertical]; [self removeUIKitViews]; breken; case 5: [self.scene.view presentScene: transitionResult transition: transitionDoorway]; [self removeUIKitViews]; breken; case 6: [self.scene.view presentScene: transitionResult transition: transition FadeWithColor]; [self removeUIKitViews]; breken; case 7: [self.scene.view presentScene: transitionResult transition: transitionFadeWithDuration]; [self removeUIKitViews]; breken; case 8: [self.scene.view presentScene: transitionResult transition: transitionFlipHorizontal]; [self removeUIKitViews]; breken; case 9: [self.scene.view presentScene: transitionResult transition: transitionFlipVertical]; [self removeUIKitViews]; breken; case 10: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionDown]; [self removeUIKitViews]; breken; case 11: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionUp]; [self removeUIKitViews]; breken; case 12: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionLeft]; [self removeUIKitViews]; breken; case 13: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionRight]; [self removeUIKitViews]; breken; case 14: [self.scene.view presentScene: transitionResult transition: transitionPushWithDirection]; [self removeUIKitViews]; breken; case 15: [self.scene.view presentScene: transitionResult transition: transitionRevealWithDirectionUp]; [self removeUIKitViews]; breken; case 16: [self.scene.view presentScene: transitionResult transition: transitionWithCIFilter]; [self removeUIKitViews]; breken; standaard: pauze; 

U ontvangt een waarschuwing die zegt dat een methode (removeUIKitViews) ontbreekt. Die methode is een eenvoudige aanroep om enkele weergaven van de bovenliggende en superweergave te verwijderen. Hoewel simplistisch, is de benodigde code:

 -(void) removeUIKitViews [transitionTimerText removeFromParent]; [_tableView removeFromSuperview]; [_sliderTimer removeFromSuperview]; 

Nu voor verschillende opmerkingen met betrekking tot de -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath methode.

  • De SKTransition overgangsinitialisatie is vergelijkbaar met alle overgangen.
  • Het gedefinieerde filter is aangepast. Zoals hierboven vermeld, kunt u het opnieuw configureren of een volledig nieuw filter definiëren.
  • De Looptijd tijd wordt gedefinieerd door de UISlider waarde.

Stap 8

Om de code uit te voeren en de overgangen te testen, moet u de TransitionResult klasse. Verplaats die klasse en voeg de -(Id) initWithSize: (CGSize) formaat methode. Het is vergelijkbaar met de MyScene.m methode. U kunt proberen het zelf te schrijven. Kopieer en plak vanuit de andere klasse om het op de volgende methode te laten lijken:

 -(id) initWithSize: (CGSize) size if (self = [super initWithSize: size]) self.backgroundColor = [SKColor colorWithRed: 0.35 green: 0.45 blue: 0.23 alpha: 1.0]; SKLabelNode * myLabel = [SKLabelNode labelNodeWithFontNamed: @ "Chalkduster"]; myLabel.text = @ "Tap go back"; myLabel.fontSize = 15; myLabel.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMidY (self.frame)); [self addChild: myLabel];  terugkeer zelf; 

U kunt nu de code uitvoeren en de overgangen testen. Ga je gang en probeer ze!

Stap 9

Zoals je misschien al hebt gemerkt, moet je elke keer dat je een nieuwe overgang wilt testen, de code opnieuw uitvoeren. Dus laten we het aanpassen TransitionResult.m bestand dat een oneindige navigatie mogelijk maakt. Telkens wanneer de gebruiker op het scherm tikt, wordt deze naar de beginscène verplaatst.

Je hebt de -(ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis methode en u zult het moeten importeren MyScene.h klasse. Dus de laatste stap is om een ​​klassenobject toe te wijzen en te initiëren en de scènes te wisselen. Het volgende fragment helpt u precies dat te doen:

 -(ongeldig) raaktBegan: (NSSet *) raakt aan metEvent: (UIEvent *) -gebeurtenis MyScene * home = [[MyScene-toewijzing] initWithSize: CGSizeMake (CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame))]; [self.scene.view presentScene: home]; 

Eindelijk, voer je programma uit en test alle SKTransitions. De volgende afbeelding vertegenwoordigt een van de overgangen:


Een andere illustratie van het SKTRansition-effect

Conclusie

In de loop hiervan SKTransition tutorial hebben we het volgende behandeld:

  • Een compleet overzicht van de SKTransition klasse.
  • Hoe alle te maken en te configureren SKTransition opties.
  • Werken met SKTransition eigenschappen.
  • Hoe een te maken en configureren UITableView en UISlider en gebruik ze parallel met Sprite Kit.

Als u vragen of opmerkingen heeft, kunt u deze hieronder laten staan!