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!
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:
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.
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:
UIColor
motsätta sig att färga den inneboende ö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
.
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.
Nu när du vet grunderna i SKTransition
klass, kan du nu starta programmeringsfasen.
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
.
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;
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);
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
.
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!
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).
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.
SKTransition
Övergångsinitiering liknar alla övergångar.Varaktighet
tiden definieras av UISlider
värde.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!
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:
Under loppet av detta SKTransition
handledning har vi täckt följande:
SKTransition
klass.SKTransition
alternativ.SKTransition
egenskaper.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!