Arbetar med SKTransition

Denna handledning lär dig att kombinera UIKit utsikt och SKTransition klass för att skapa vackra, anpassade övergångar mellan olika SKScenes. Läs vidare!


Slutlig förhandsvisning

Illustration av slutresultatet.

1. Övergångar mellan scener

Scener är gränssnitt som innehåller flera visningsobjekt. Normalt utformar du flera scener för varje del av ditt spel och använder sedan övergångar mellan scenerna efter behov. Du kan till exempel skapa olika scenklasser för att representera något av eller alla följande begrepp:

  • En huvudmeny för att välja svårigheten för en specifik nivå som användaren vill spela.
  • En scen för att konfigurera detaljerna för ljud och musik effekter av ett spel.
  • En scen som ger spel-play-gränssnittet.
  • En scen som ger gränssnittet för online-ledarkortet.
  • En scen som ger nuvarande och övergripande spelprestationer.

Som du kan se kan en scen vara allt som programmeraren skulle vilja skapa. Vanligtvis övergår du till en ny scen baserat på spel-play-mål eller direkt användarinmatning. Till exempel, om timern löper ut, kan en ny scen som presenterar ett "spel över" presenteras. Alternativt kan du, om en användare trycker på en alternativknapp, övergå till en ny scen för att konfigurera spelinställningarna. Observera att vid övergångssteget uppdateras scenegenskapen omedelbart för att peka på den nya scenen. Efter detta sker övergången.

En övergång kan också ha ett övergångsobjekt (en effekt eller en animering). Det objektet kommer att skapa en dynamisk, vacker presentation när övergången inträffar. Flera föremål finns, och för en fullständig och officiell referens bör du kontakta SKTransition-klassens referens.


2. Klassmetoder

De SKTransition klassen presenterar flera metoder och två egenskaper (mer om de senare). Målet med alla metoder är att skapa en glänsande och dynamisk övergång mellan scener. Klassmetoderna kan delas in i fyra huvudavsnitt:

  • Med längd: Övergångar som kommer att ske under en bestämd tidsperiod.
  • Med Färg: Övergångar som kommer att använda a UIColor motsätta sig att färga den inneboende övergången.
  • Med riktning: Övergångar som kommer att göras från en angiven riktning.
  • Med CIFilter: Övergångar som använder ett anpassat filter för att skapa en visuell effekt i övergången.

Varaktighet och Färg är enkla objekt, men båda Riktning och CIFilter är inte.

Som namnsförslag innebär riktningsegenskapen att övergången kommer att ske i en specifik riktning. Riktningsegenskapen kan ha en av fyra konstanter. Dessa konstanter förklaras som en NS_ENUM, så här:

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

CIFilter är ännu mer robust än Riktning eftersom det också är en referensklass med klassmetoder, förekomstmetoder och egenskaper. Denna handledning täcker inte CIFilter klass i djupet, men det kommer att presentera ett exempel på hur man använder det för att skapa ett anpassat filter och det inneboende SKTransition. En ytterligare anteckning om CIFilter klass: den stöder dussintals effekter, men inte alla stöds av den senaste versionen av IOS. Du bör konsultera Core Image Filter Reference för att se kompatibilitetslistan.

Observera att du kan använda flera "grupperade metoder" för att skapa en SKTransiton. Men hur vet du vilka som kan kombineras? För detta måste du titta på metodens signatur och bestämma egenskaper som godkänts av varje metod.

Låt oss analysera tre metoder för att se vad de kan hantera:

  • doorsOpenVerticalWithDuration:
  • fadeWithColor: varaktighet:
  • revealWithDirection: varaktighet:

Som tidigare nämnts tillåter metodnamnen dig att snabbt förstå vad varje metod kan göra. För att utarbeta, doorsOpenVerticalWithDuration: Metoden tar endast hänsyn till en varaktighet fadeWithColor: varaktighet: Metoden använder både en färg och en varaktighet. Du måste först definiera a UIColor objekt och sedan en varaktighetstid. De revealWithDirection: varaktighet: Metoden kommer endast att använda en riktning, som i sin tur kan vara en av fyra egenskaper. Observera att du också kan förlänga SKTransition klass för att skapa anpassade övergångar och gå med Varaktighet, Färg, Riktning, och CIFilter.


revealWithDirection (UP) illustration

3. Klassegenskaper

De SKTransition Klassen har endast två egenskaper: pausesIncomingScene och pausesOutgoingScene. Båda konfigurerar huruvida animationer spelas under övergången och båda egenskaperna är Boolean värden. Skillnaden är följande:

  • pausesIncomingScene avgör om den inkommande scenen är pausad under övergången.
  • pausesOutgoingScene bestämmer om den utgående scenen är pausad under övergången.

Eftersom båda är Boolean värden, definitionen är enkel och kan förstås i nästa kod:

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

De pausesIncomingScene och pausesOutgoingScene egenskaper på övergångsobjektet definierar vilka animeringar som spelas under övergången. Som standard fortsätter båda scenerna att behandla animering under övergången. Men du kanske vill pausa en eller båda scenerna tills övergången är klar.


4. Handledningsprojektet

Nu när du vet grunderna i SKTransition klass, kan du nu starta programmeringsfasen.

Steg 1

Det första steget är att öppna Xcode och starta en ny SpriteKit projekt. Därefter bör du lägga till en annan Objective-C klass som heter TransitionResult och en superklass av SKScene.

Syftet med detta projekt är att ha två klasser som ska bytas mellan dem. Den första (Min scen redan definierad av Xcode) innehåller en UITableView som kommer att hänvisa till var och en SKTransition. Den andra (TransitionResult) kommer att bli destinationsscenen efter en övergång.

När användaren knackar på skärmen efter en övergång kommer den återigen att överföras till Min scen.

Steg 2

I MyScene.h, Du kommer att deklarera 3 objekt: a UITableView, UISlider, och en NSArray. De UITableView kommer att visa namnen på varje övergång, den UISlider kommer att definiera Varaktighet av den övergången, och den NSArray kommer att innehålla namnen på varje SKTransition. Den slutliga MyScene.h koden kommer att likna detta stycke:

 @property (behåll, nonatomic) IBOutlet UITableView * tableView; @property (nonatomic, behåll) IBOutlet UISlider * sliderTimer; @property (stark, ickeatomisk) NSArray * övergångarArray;

Steg 3

Nu fokusera din uppmärksamhet i Min scen implementeringsfilen.

Det första steget är att använda -(Id) initWithSize: (CGSize) storlek metod för att initiera de ovan nämnda föremålen. En möjlig konfigurationsinställning är följande:

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

En varning presenteras emellertid sedan sliderAction saknas. Metoden kommer att uppdateras i realtid transitionTimerText med beaktande av UISlider värde.

 -(void) sliderAction transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Övergångstid:% f", _sliderTimer.value); 

Observera att vyerna, platsen, konfigurationen och layouten är helt konfigurerbara. Om du vill kan du ställa in detta för dina bästa intressen. Dessutom lägger du till en SKLabelNode att lagra och visa UISlider värde. Det värdet kommer att vara representativt för SKTransitionens varaktighet effekter. Lägg till SKLabelNode * transitionTimerText till din implementeringsfil och motsvarande initialisering kommer att vara:

 transitionTimerText = [SKLabelNode labelNodeWithFontNamed: @ "Chalkduster"]; transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Övergångstid:% 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);

Steg 4

Nu när du har objekten konfigurerad behöver du bara lägga till dem på scenen. För det kommer du att använda -(void) didMoveToView: (SKView *) vy metod. Lägg till den i din fil och lägg till ovan nämnda vyer i huvudvisningen:

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

Om du kör projektet nu ser du två objekt på skärmen: a UISlider och a SKLabelNode.

Steg 5

Nästa steg är att visa SKTransition metoder i UITableView. För detta måste du ändra din MyScene.h fil och förläng din klass med protokoll. Den slutliga MyScene.h ska se så här ut:

 @interface MyScene: SKScene 

Gå tillbaka till implementeringsfilen och du kommer att presenteras med en varning. Den varningen säger att du måste implementera ytterligare metoder som är inneboende för UITableView. De metoder som behövs är: -(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sektion och -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath. Den första kommer att returnera antalet rader i tabellen, medan den andra kommer att hantera logiken för varje cell inuti bordet. För ytterligare anmärkningar angående UITableView klass, bör du konsultera den officiella referensklassen.

Den första metoden är enkel och är bara en enda rad:

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

Den andra metoden är mer komplex eftersom vi måste definiera tabellcellens egenskaper och konfigurationer (cellinnehåll). I det här exemplet kommer du att använda en enkel UITableViewCellStyleSubtitle. Om du har problem med att skriva metoden presenteras den fullständiga versionen nedan:

 -(UITableViewCell *) tableView: (UITableView *) tableVisa cellForRowAtIndexPath: (NSIndexPath *) indexPath NSString * övergångar = [_transitionsArray objectAtIndex: indexPath.row]; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: @ "Identifier"]; om (cell == noll) cell = [[UITableViewCell allok] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: @ "Identifier"];  [cell.textLabel setText: övergångar]; returcell; 

Kör din kod nu och du bör se varje cellinje med ett unikt namn. Varje namn representerar det inneboende SKTransiton används om användaren tappar den cellen. Du kommer också att notera att UITableView har ingen titel Låt oss fixa det!

Steg 6

Lägg till följande metod: - (NSString *) tableView: (UITableView *) tableView titleForHeaderInSection: (NSInteger) sektion. Inom denna metod lägger du till följande kod:

 NSString * sectionName; switch (avsnitt) case 0: sectionName = NSLocalizedString (@ "SKTransition List", @ "SKTransition List"); ha sönder; standard: sectionName = @ ""; ha sönder;  returnera sektionName;

Denna metod tillåts ha flera titlar för flera UITableView sektioner. Vi kommer dock bara ha ett avsnitt, så titeln kommer att bli "SKTransition List" (eller någon annan av ditt val).

Steg 7

Vid denna tidpunkt måste du lägga till användarinteraktion i cellerna. För att göra detta behövs ytterligare en metod. Den här gången -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath Metoden ska kallas. Denna metod är lång, men det är lätt att förstå. Du kommer att fördela de resurser som behövs för varje SKTransition och baserat på den cell som tappats, presenterar du en annan SKScene.

Det första steget är att importera TransitionResult header-fil och definiera sedan en TransitionResult motsätta sig den resulterande SKScene. Ta en titt på följande för att se detta i åtgärd:

 TransitionResult * transitionResult; SKTransition * transitionCrossFade; SKTransition * transitionDoorsCloseHorizontal; SKTransition * transitionDoorsCloseVertical; SKTransition * övergångsdörrarOpenHorizontal; 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, i -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath metod, det är dags att allokera nödvändiga resurser. Den fullständiga koden är:

 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 = [SKTransition 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: SKTransitionDirectionRight duration: _sliderTimer.value]; transitionPushWithDirection = [SKTransition pushWithDirection: SKTransitionDirectionDown duration: _sliderTimer.value]; transitionRevealWithDirectionUp = [SKTransition revealWithDirection: SKTransitionDirectionUp duration: _sliderTimer.value]; CGRect screenRect = [[UIScreen mainScreen] gränser]; CIVector * extent = [CIVector vectorWithX: 0 Y: 0 Z: screenRect.size.width W: screenRect.size.height]; transitionWithCIFilter = [SKTransition transitionWithCIFilter: [CIFilter filterWithName: @ "CIFlashTransition" keysAndValues: @ "inputExtent", omfattning, @ "inputCenter", [CIVector vectorWithX: 0.3 * screenRect.size.width Y: 0.7 * screenRect.size.height] @ "inputColor", [CIColor colorWithRed: 1.0 grön: 0,8 blå: 0,6 alfa: 1], @ "inputMaxStriationRadius", @ 2,5, @ "inputStriationStrength", @ 0.5, @ "inputStriationContrast", @ 1.37, @ "inputFadeThreshold" @ 0,85, noll] varaktighet: _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]; ha sönder; fall 1: [self.scene.view presentScene: transitionResult övergång: transitionDoorsCloseHorizontal]; [self removeUIKitViews]; ha sönder; fall 2: [self.scene.view presentScene: transitionResult övergång: transitionDoorsCloseVertical]; [self removeUIKitViews]; ha sönder; fall 3: [self.scene.view presentScene: transitionResult övergång: transitiondoorsOpenHorizontal]; [self removeUIKitViews]; ha sönder; fall 4: [self.scene.view presentScene: transitionResult övergång: transitionDoorsOpenVertical]; [self removeUIKitViews]; ha sönder; fall 5: [self.scene.view presentScene: transitionResult övergång: transitionDoorway]; [self removeUIKitViews]; ha sönder; fall 6: [self.scene.view presentScene: transitionResult övergång: transitionFadeWithColor]; [self removeUIKitViews]; ha sönder; fall 7: [self.scene.view presentScene: transitionResult övergång: transitionFadeWithDuration]; [self removeUIKitViews]; ha sönder; fall 8: [self.scene.view presentScene: transitionResult övergång: transitionFlipHorizontal]; [self removeUIKitViews]; ha sönder; fall 9: [self.scene.view presentScene: transitionResult övergång: transitionFlipVertical]; [self removeUIKitViews]; ha sönder; fall 10: [self.scene.view presentScene: transitionResult övergång: transitionMoveInWithDirectionDown]; [self removeUIKitViews]; ha sönder; fall 11: [self.scene.view presentScene: transitionResult övergång: transitionMoveInWithDirectionUp]; [self removeUIKitViews]; ha sönder; fall 12: [self.scene.view presentScene: transitionResult övergång: transitionMoveInWithDirectionLeft]; [self removeUIKitViews]; ha sönder; fall 13: [self.scene.view presentScene: transitionResult övergång: transitionMoveInWithDirectionRight]; [self removeUIKitViews]; ha sönder; fall 14: [self.scene.view presentScene: transitionResult transition: transitionPushWithDirection]; [self removeUIKitViews]; ha sönder; fall 15: [self.scene.view presentScene: transitionResult övergång: transitionRevealWithDirectionUp]; [self removeUIKitViews]; ha sönder; fall 16: [self.scene.view presentScene: transitionResult övergång: transitionWithCIFilter]; [self removeUIKitViews]; ha sönder; standard: break; 

Du får en varning som säger att en metod (removeUIKitViews) saknas. Den här metoden är ett enkelt samtal för att ta bort vissa vyer från föräldra- och supervyn. Medan det är förenklat är den nödvändiga koden:

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

Nu för flera anteckningar angående -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath metod.

  • De SKTransition Övergångsinitiering liknar alla övergångar.
  • Det definierade filtret är en anpassad en. Som ovan nämnts kan du omkonfigurera det eller definiera ett helt nytt filter.
  • De Varaktighet tiden definieras av UISlider värde.

Steg 8

För att köra koden och prova övergångarna måste du fylla i TransitionResult klass. Flytta den klassen och lägg till -(Id) initWithSize: (CGSize) storlek metod. Det liknar MyScene.m metod. Du kan försöka skriva det själv. Kopiera och klistra in från den andra klassen så att den ser ut som nästa metod:

 -(id) initWithSize: (CGSize) storlek om (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 = @ "Tryck på gå tillbaka"; myLabel.fontSize = 15; myLabel.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMidY (self.frame)); [self addChild: myLabel];  återvänd själv 

Du kan nu köra koden och testa övergångarna. Fortsätt och försök dem!

Steg 9

Som du kanske redan har märkt, måste du köra koden igen varje gång du vill testa en ny övergång. Så, låt oss ändra TransitionResult.m fil som möjliggör en oändlig navigering. Varje gång användaren knackar på skärmen flyttas den till den ursprungliga scenen.

Du behöver den -(void) touchesBegan: (NSSet *) berörs medEvent: (UIEvent *) händelse metod och du måste importera MyScene.h klass. Så det sista steget är att allokera och initiera ett klassobjekt och byta scenerna. Nästa kodning hjälper dig att göra just det:

 -(void) touchesBegan: (NSSet *) berörs medEvent: (UIEvent *) händelse MyScene * home = [[MyScene allokera] initWithSize: CGSizeMake (CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame)); [self.scene.view presentScene: home]; 

Slutligen kör ditt program och testa alla SKTransitions. Nästa bild representerar en av övergångarna:


En annan SKTRansition-effektillustration

Slutsats

Under loppet av detta SKTransition handledning har vi täckt följande:

  • En fullständig översikt över SKTransition klass.
  • Hur man skapar och konfigurerar alla SKTransition alternativ.
  • Arbetar med SKTransition egenskaper.
  • Hur man skapar och konfigurerar a UITableView och UISlider och använd dem parallellt med Sprite Kit.

Om du har några frågor eller kommentarer, var god och lämna dem nedan!