Travailler avec SKTransition

Ce tutoriel va vous apprendre à combiner UIKit vues et la SKTransition classe pour créer de belles transitions personnalisées entre différents SKScènes. Continuer à lire!


Aperçu final

Illustration du résultat final.

1. Transitions entre les scènes

Les scènes sont des interfaces contenant plusieurs objets de vue. Normalement, vous concevez plusieurs scènes pour chaque partie de votre jeu, puis utilisez des transitions entre les scènes si nécessaire. Par exemple, vous pouvez créer différentes classes de scène pour représenter tout ou partie des concepts suivants:

  • Une scène de menu principale pour choisir la difficulté d'un niveau spécifique que l'utilisateur veut jouer.
  • Une scène pour configurer les détails des effets sonores et musicaux d'un jeu.
  • Une scène qui fournit l'interface de jeu.
  • Une scène qui fournit l'interface en ligne du tableau de classement.
  • Une scène qui fournit les réalisations actuelles et globales du jeu.

Comme vous pouvez le constater, une scène peut être tout ce que le programmeur souhaite créer. En règle générale, vous passez à une nouvelle scène en fonction d'objectifs de jeu ou d'une saisie directe de l'utilisateur. Par exemple, si le temps imparti est écoulé, une nouvelle scène présentant un "game over" peut être présentée. Si un utilisateur appuie sur un bouton d'options, vous pouvez également passer à une nouvelle scène pour configurer les paramètres du jeu. Notez qu'à l'étape de transition, la propriété de la scène est immédiatement mise à jour pour pointer vers la nouvelle scène. Après cela, la transition se produit.

Une transition peut également avoir un objet de transition (un effet ou une animation). Cet objet créera une belle présentation dynamique lors de la transition. Il existe plusieurs objets. Pour une référence complète et officielle, vous devriez consulter la référence de classe SKTransition..


2. Méthodes de classe

le SKTransition La classe présente plusieurs méthodes et deux propriétés (plus à propos de celles plus tard). Le but de toutes les méthodes est de créer une transition brillante et dynamique entre les scènes. Les méthodes de classe peuvent être divisées en quatre sections principales:

  • Avec durée: Transitions qui se produiront sur une période de temps définie.
  • Avec couleur: Les transitions qui utiliseront un UIColor objet à colorier la transition inhérente.
  • Avec Direction: Transitions qui seront effectuées à partir d'une direction spécifiée.
  • Avec CIFilter: Transitions qui utiliseront un filtre personnalisé pour produire un effet visuel dans la transition.

Durée et Couleur sont des objets simples, mais les deux Direction et CIFilter ne sont pas.

Comme son nom l'indique, la propriété direction signifie que la transition se produira dans une direction spécifique. La propriété direction peut avoir l'une des quatre constantes. Ces constantes sont déclarées comme NS_ENUM, comme ça:

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

CIFilter est encore plus robuste que Direction puisqu'il s'agit également d'une classe de référence avec des méthodes de classe, des méthodes d'instance et des propriétés. Ce tutoriel ne couvrira pas la CIFilter classe en profondeur, mais il présentera un exemple de la façon de l’utiliser pour créer un filtre personnalisé et le SKTransition. Une note supplémentaire concernant le CIFilter classe: il prend en charge des dizaines d'effets, mais tous ne sont pas pris en charge par la dernière version d'iOS. Vous devriez consulter le Core Image Filter Reference pour voir la liste de compatibilité..

Notez que vous pouvez utiliser plusieurs "méthodes groupées" pour créer une SKTransiton. Mais comment savoir lesquels peuvent être combinés? Pour cela, vous devez consulter la signature de la méthode et déterminer les propriétés acceptées par chaque méthode..

Par exemple, analysons trois méthodes pour voir ce qu’elles peuvent gérer:

  • DoorsOpenVerticalWithDuration:
  • fadeWithColor: durée:
  • unrealWithDirection: durée:

Comme indiqué précédemment, les noms de méthodes vous permettent de comprendre rapidement ce que chaque méthode peut faire. Pour élaborer, le DoorsOpenVerticalWithDuration: Cette méthode ne prendra en considération qu'une durée fadeWithColor: durée: méthode utilise à la fois une couleur et une durée. Vous devez d'abord définir un UIColor objet et ensuite une durée. le unrealWithDirection: durée: méthode utilisera uniquement une direction, qui peut être une des quatre propriétés. Notez que vous pouvez également étendre la SKTransition classe pour créer des transitions personnalisées et rejoindre Durée, Couleur, Direction, et CIFilter.


Illustration de la méthode réveler avec la direction (UP)

3. Propriétés de la classe

le SKTransition La classe n'a que deux propriétés: pausesIncomingScene et pausesOutgoingScene. Les deux déterminent si les animations sont lues pendant la transition et les deux propriétés sont Booléen valeurs. La différence est la suivante:

  • pausesIncomingScene détermine si la scène entrante est en pause pendant la transition.
  • pausesOutgoingScene détermine si la scène sortante est en pause pendant la transition.

Puisque les deux sont Booléen valeurs, la définition est facile et peut être comprise dans le prochain extrait:

 // autre code… transitionCrossFade = [SKTransition crossFadeWithDuration: 1]; transitionCrossFade.pausesIncomingScene = TRUE; transitionDoorsCloseHorizontal = [SKPour portes de transitionFermerHorizontalWithDuration: 2]; transitionDoorsCloseHorizontal.pausesOutgoingScene = FALSE;

le pausesIncomingScene et pausesOutgoingScene les propriétés de l'objet de transition définissent les animations lues pendant la transition. Par défaut, les deux scènes continuent de traiter l'animation pendant la transition. Cependant, vous souhaiterez peut-être mettre en pause une ou les deux scènes jusqu'à la fin de la transition..


4. Le projet de tutoriel

Maintenant que vous connaissez les bases du SKTransition classe, vous pouvez maintenant commencer la phase de programmation.

Étape 1

La première étape consiste à ouvrir Xcode et à démarrer une nouvelle SpriteKit projet. Ensuite, vous devriez ajouter un autre Objectif c classe nommée TransitionResult et une super-classe de SKScene.

L'objectif de ce projet est d'avoir deux classes qui seront permutées entre elles. La première (Ma scène déjà défini par le Xcode) contiendra un UITableView qui tiendra la référence à chaque SKTransition. La deuxième (TransitionResult) sera la scène de destination après une transition.

Lorsque l'utilisateur appuie sur l'écran après une transition, il est à nouveau transféré vers Ma scène.

Étape 2

Dans MyScene.h, vous déclarerez 3 objets: un UITableView, UISlider, Et un NSArray. le UITableView affichera les noms de chaque transition, la UISlider définira le Durée de cette transition, et la NSArray contiendra les noms de chaque SKTransition. Le final MyScene.h le code sera similaire à cet extrait:

 @property (keep, nonatomic) IBOutlet UITableView * tableView; @property (nonatomic, keep) IBOutlet UISlider * sliderTimer; @property (strong, nonatomic) NSArray * transitionsArray;

Étape 3

Maintenant, concentrez votre attention sur le Ma scène fichier d'implémentation.

La première étape consiste à utiliser le -(id) initWithSize: taille (CGSize) procédé pour initialiser les objets susmentionnés. Une configuration possible est la suivante:

 _tableView = [[UITableView alloc] initWithFrame: CGRectMake (CGRectGetMinX (self.frame), CGRectGetMinY (self.frame) +20, CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame), CGRectGetMaxY (self.frame)), _tableView.dataSource = self; _tableView.delegate = self; _sliderTimer = [[UISlider alloc] initWithFrame: CGRectMake (CGRectGetMidX (self.frame) -70, CGRectGetMaxY (self.frame) -40, 140, 3)]; [_sliderTimer addTarget: action propre: @selector (sliderAction) forControlEvents: UIControlEventValueChanged]; [_sliderTimer setBackgroundColor: [UIColor clearColor]]; _sliderTimer.minimumValue = 1; _sliderTimer.maximumValue = 4; _sliderTimer.continuous = YES; _sliderTimer.value = 1; _transitionsArray = [[NSArray alloc] initWithObjects: @ "crossFadeWithDuration", @ "doorsCloseHorizontalWithDuration", @ "doorsCloseVerticalWithDuration", "porteOpenHorizontalWithDuration", @ , @ "flipHorizontalWithDuration", @ "flipVerticalWithDurationDurée", @ "moveInWithDirectionDownown: durée", @ "moveInWithDirectionUp: durée", @ "moveInWithDirectionLeft: durée", @ "moveInWithDirectionRight: durée", @ "pushWithDirection: duration". durée ", @" transitionWithCIFilter: durée ", nil];

Cependant, un avertissement est présenté depuis le sliderAction est manquant. La méthode mettra à jour en temps réel le transitionTimerText en tenant compte de la UISlider valeur.

 -(void) sliderAction transitionTimerText.text = [[NSString alloc]] initWithFormat: @ "Durée de la transition:% f", _sliderTimer.value]; 

Notez que les vues, l'emplacement, la configuration et la présentation sont entièrement configurables. Si vous le souhaitez, vous pouvez régler cela au mieux de vos intérêts. De plus, vous ajouterez un SKLabelNode pour stocker et afficher le UISlider valeur. Cette valeur sera représentative de la SKTransition Durée effets. Ajouter le SKLabelNode * transitionTimerText à votre fichier d'implémentation et l'initialisation correspondante sera:

 transitionTimerText = [SKLabelNode labelNodeWithFontNamed: @ "Chalkduster"]; transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Durée de la transition:% f", _sliderTimer.value]; transitionTimerText.fontSize = 10; transitionTimerText.color = [SKColor colorWithRed: 0 vert: 0 bleu: 0 alpha: 1]; transitionTimerText.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMinY (self.frame) +45);

Étape 4

Maintenant que vous avez configuré les objets, il vous suffit de les ajouter à la scène. Pour cela, vous utiliserez le -(void) didMoveToView: (SKView *) voir méthode. Ajoutez-le à votre fichier et ajoutez à l'intérieur les vues susmentionnées à la vue principale:

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

Si vous exécutez le projet maintenant, vous verrez deux objets à l’écran: un UISlider et un SKLabelNode.

Étape 5

L'étape suivante consiste à afficher le SKTransition méthodes dans le UITableView. Pour cela, vous devez modifier votre MyScene.h déposer et étendre votre classe avec le protocoles. Le final MyScene.h devrait ressembler à ceci:

 @interface MyScene: SKScene 

Retournez au fichier d'implémentation et un avertissement vous sera présenté. Cet avertissement indique que vous devez implémenter des méthodes supplémentaires inhérentes à la UITableView. Les méthodes nécessaires sont: -(NSInteger) tableView: (UITableView *) table numéro de sectionOfRowsInSection: (NSInteger) section et -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath. Le premier renverra le nombre de lignes du tableau, tandis que le second traitera la logique de chaque cellule du tableau. Pour des notes supplémentaires concernant la UITableView classe, vous devriez consulter la classe de référence officielle.

La première méthode est simple et consiste en une seule ligne:

 -(NSInteger) tableView: (UITableView *) numéro de la table (numéro de la vue): (NSInteger) section return [_transitionsArray count]; 

La seconde méthode est plus complexe car il faut définir les propriétés et les configurations des cellules du tableau (contenu de la cellule). Dans cet exemple, vous utiliserez un simple UITableViewCellStyleSubtitle. Si vous rencontrez des problèmes pour écrire la méthode, la version complète est présentée ci-dessous:

 -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath NSString * transitions = [_transitionsArray objectAtIndex: indexPath.row]; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: @ "identificateur"]; if (cell == nil) cell = [[UITableViewCell alloc]] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: @ "Identificateur"];  [cell.textLabel setText: transitions]; cellule de retour; 

Exécutez votre code maintenant et vous devriez voir chaque ligne de cellule avec un nom unique. Chaque nom représente l'inhérent SKTransiton utilisé si l'utilisateur appuie sur cette cellule. Vous noterez également que le UITableView n'a pas de titre. Corrigeons ça!

Étape 6

Ajoutez la méthode suivante: - (NSString *) tableView: (UITableView *) tableView titreForHeaderInSection: section (NSInteger). Dans cette méthode, ajoutez le code suivant:

 NSString * sectionName; commutateur (section) cas 0: sectionName = NSLocalizedString (@ "SKTransition List", @ "SKTransition List"); Pause; défaut: sectionName = @ ""; Pause;  retourne nom de section;

Cette méthode est autorisée à avoir plusieurs titres pour plusieurs UITableView sections. Cependant, nous n’aurons qu’une section, le titre sera "SKTransition List" (ou toute autre liste de votre choix)..

Étape 7

À ce stade, vous devez ajouter une interaction utilisateur aux cellules. Pour ce faire, une autre méthode supplémentaire est nécessaire. Cette fois le -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath méthode devrait être appelée. Cette méthode est longue, mais simple à comprendre. Vous allouerez les ressources nécessaires pour chaque SKTransition et, en fonction de la cellule mise sur écoute, vous présenterez une autre SKScene.

La première étape consiste à importer le TransitionResult en-tête, puis définissez un TransitionResult objet pour le résultat SKScene. Regardez ce qui suit pour voir cela en action:

 TransitionResult * transitionResult; SKTransition * transitionCrossFade; 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;

Maintenant, dans le -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath méthode, il est temps d’allouer les ressources nécessaires. Le code complet est:

 transitionCrossFade = [SKTransition crossFadeWithDuration: _sliderTimer.value]; transitionCrossFade.pausesIncomingScene = TRUE; transitionDoorsCloseHorizontal = [SKPortes de transitionCloseHorizontalWithDuration: _sliderTimer.value]; transitionDoorsCloseHorizontal.pausesOutgoingScene = FALSE; transitionDoorsCloseVertical = [SKTransition doorsCloseVerticalWithDuration: _sliderTimer.value]; transitiondoorsOpenHorizontal = [SKPortes de transitionOuvreHorizontalesWithDuration: _sliderTimer.value]; transitionDoorsOpenVertical = [SKTransition doorsOpenVerticalWithDuration: _sliderTimer.value]; transitionDoorway = [SKTransition doorwayWithDuration: _sliderTimer.value]; transitionFadeWithColor = [SKTransition fadeWithColor: [UIColor yellowColor] durée: _sliderTimer.value]; transitionFadeWithDuration = [SKTransition fadeWithDuration: _sliderTimer.value]; transitionFlipHorizontal = [SKTransition flipHorizontalWithDuration: _sliderTimer.value]; transitionFlipVertical = [SKTransition flipVerticalWithDuration: _sliderTimer.value]; transitionMoveInWithDirectionDown = [SKTransition moveInWithDirection: SKTransitionDirectionDown durée: _sliderTimer.value]; transitionMoveInWithDirectionUp = [SKTransition moveInWithDirection: SKTransitionDirectionUp durée: _sliderTimer.value]; transitionMoveInWithDirectionLeft = [SKTransition moveInWithDirection: SKTransitionDirectionLeft durée: _sliderTimer.value]; transitionMoveInWithDirectionRight = [SKTransition moveInWithDirection: SKTransitionDirectionRight durée: _sliderTimer.value]; transitionPushWithDirection = [SKTransition pushWithDirection: SKTransitionDirectionDown durée: _sliderTimer.value]; transitionRevealWithDirectionUp = [SKTransition révélateurWithDirection: SKTransitionDirectionUp durée: _sliderTimer.value]; CGRect screenRect = [[UIScreen mainScreen]]]; CIVector * mesure = [CIVector vectorWithX: 0 Y: 0 Z: screenRect.size.width W: screenRect.size.height]; transitionWithCIFilter = [SKTransition transitionWithCIFilter: [CIFilter filterWithName: @ "CIFlashTransition" keysAndValues: @ "inputExtent", mesure, @ "inputCenter", [CIVector vecteurWithX: 0.3 * screenRect.size.width Y: 0.7 * screenRect.size.] @ "inputColor", [CIColor colorWithRed: 1.0 vert: 0.8 bleu: 0.6 alpha: 1], @ "inputMaxStriationRadius", @ 2.5, @ "inputStriationStrength", @ 0.5, @ "inputStriationContrast", @ 1.37, @ "37 inputFadeThreshold", @ 0,85, nil] durée: _sliderTimer.value]; transitionResult = [[TransitionResult alloc] initWithSize: CGSizeMake (CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frame)))]; switch (indexPath.row) cas 0: [self.scene.view presentScene: transitionResult transition: transitionCrossFade]; [self removeUIKitViews]; Pause; cas 1: [self.scene.view presentScene: transitionResult transition: transitionDoorsCloseHorizontal]; [self removeUIKitViews]; Pause; cas 2: [self.scene.view presentScene: transitionResult transition: transitionDoorsCloseVertical]; [self removeUIKitViews]; Pause; cas 3: [self.scene.view presentScene: transitionResult transition: transitiondoorsOpenHorizontal]; [self removeUIKitViews]; Pause; cas 4: [self.scene.view presentScene: transitionResult transition: transitionDoorsOpenVertical]; [self removeUIKitViews]; Pause; cas 5: [self.scene.view presentScene: transitionResult transition: transitionDoorway]; [self removeUIKitViews]; Pause; cas 6: [self.scene.view presentScene: transitionResult transition: transitionFadeWithColor]; [self removeUIKitViews]; Pause; cas 7: [self.scene.view presentScene: transitionResult transition: transitionFadeWithDuration]; [self removeUIKitViews]; Pause; cas 8: [self.scene.view presentScene: transitionResult transition: transitionFlipHorizontal]; [self removeUIKitViews]; Pause; cas 9: [self.scene.view presentScene: transitionResult transition: transitionFlipVertical]; [self removeUIKitViews]; Pause; cas 10: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionDown]; [self removeUIKitViews]; Pause; cas 11: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionUp]; [self removeUIKitViews]; Pause; cas 12: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionLeft]; [self removeUIKitViews]; Pause; cas 13: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionRight]; [self removeUIKitViews]; Pause; cas 14: [self.scene.view presentScene: transitionResult transition: transitionPushWithDirection]; [self removeUIKitViews]; Pause; cas 15: [self.scene.view presentScene: transitionResult transition: transitionRevealWithDirectionUp]; [self removeUIKitViews]; Pause; cas 16: [self.scene.view presentScene: transitionResult transition: transitionWithCIFilter]; [self removeUIKitViews]; Pause; défaut: break; 

Vous recevrez un avertissement indiquant qu'une méthode (removeUIKitViews) est manquant. Cette méthode est un simple appel à supprimer certaines vues des vues parent et super. Bien que simpliste, le code nécessaire est:

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

Passons maintenant à plusieurs notes concernant la -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath méthode.

  • le SKTransition l'initialisation de la transition est similaire à toutes les transitions.
  • Le filtre défini est personnalisé. Comme indiqué ci-dessus, vous pouvez le reconfigurer ou définir un tout nouveau filtre.
  • le Durée le temps est défini par le UISlider valeur.

Étape 8

Pour exécuter le code et tester les transitions, vous devrez renseigner le TransitionResult classe. Déplacez cette classe et ajoutez le -(id) initWithSize: taille (CGSize) méthode. C'est semblable à la MyScene.m méthode. Vous pouvez essayer de l'écrire vous-même. Copier-coller depuis l'autre classe pour lui donner l'apparence de la méthode suivante:

 -(id) initWithSize: (CGSize) taille if (self = [super initWithSize: size]) self.backgroundColor = [SKColor couleurWithRed: 0,35 vert: 0,45 bleu: 0,23 alpha: 1,0]; SKLabelNode * myLabel = [SKLabelNode labelNodeWithFontNamed: @ "Chalkduster"]; myLabel.text = @ "Tapez sur retour"; myLabel.fontSize = 15; myLabel.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMidY (self.frame)); [auto addChild: myLabel];  retourner soi-même; 

Vous pouvez maintenant exécuter le code et tester les transitions. Allez-y et essayez-les!

Étape 9

Comme vous l'avez peut-être déjà remarqué, chaque fois que vous souhaitez tester une nouvelle transition, vous devez réexécuter le code. Alors, modifions le TransitionResult.m fichier qui permet une navigation infinie. Chaque fois que l'utilisateur appuie sur l'écran, il sera déplacé vers la scène initiale.

Vous aurez besoin du -(void) toucheBegan: (NSSet *) touche avecEvent: (UIEvent *) événement méthode et vous devrez importer le MyScene.h classe. La dernière étape consiste donc à allouer et initier un objet de classe et à permuter les scènes. Le prochain extrait vous aidera à faire exactement cela:

 -(void) touchesBegan: (NSSet *) touche withEvent: (UIEvent *) événement MyScene * home = [[MyScene alloc] initWithSize: CGSizeMake (CGRectGetMaxX (self.frame), CGRectGetMaxY (self.frameame)); [self.scene.view presentScene: home]; 

Enfin, lancez votre programme et testez tous les SKTransitions. L'image suivante représente l'une des transitions:


Une autre illustration de l'effet SKTRansition

Conclusion

Au cours de cette SKTransition tutoriel, nous avons couvert les éléments suivants:

  • Un aperçu complet de la SKTransition classe.
  • Comment créer et configurer tous les SKTransition options.
  • Travailler avec SKTransition Propriétés.
  • Comment créer et configurer un UITableView et UISlider et les utiliser en parallèle avec Sprite Kit.

Si vous avez des questions ou des commentaires, n'hésitez pas à les laisser ci-dessous.!