Trabajando con SKTransition

Este tutorial te enseñará a combinar UIKit vistas y la SKTransition Clase para crear transiciones hermosas y personalizadas entre diferentes. SKScenes. Sigue leyendo!


Vista previa final

Ilustración del resultado final.

1. Transiciones entre escenas

Las escenas son interfaces que contienen varios objetos de vista. Normalmente, diseñas varias escenas para cada parte de tu juego y luego usas las transiciones entre las escenas según sea necesario. Por ejemplo, puede crear diferentes clases de escena para representar cualquiera o todos los siguientes conceptos:

  • Una escena del menú principal para elegir la dificultad de un nivel específico que el usuario quiere jugar..
  • Una escena para configurar los detalles de los efectos de sonido y música de un juego..
  • Una escena que proporciona la interfaz de juego-juego..
  • Una escena que proporciona la interfaz de la tabla de líderes en línea.
  • Una escena que proporciona logros actuales y generales del juego..

Como puede ver, una escena puede ser cualquier cosa que el programador quiera crear. Por lo general, la transición a una nueva escena se basa en los objetivos del juego o en la entrada directa del usuario. Por ejemplo, si el temporizador se agota, se puede presentar una nueva escena que presenta un "juego terminado". Alternativamente, si un usuario presiona un botón de opciones, puede hacer la transición a una nueva escena para configurar los ajustes del juego. Tenga en cuenta que, en el paso de transición, la propiedad de la escena se actualiza inmediatamente para que apunte a la nueva escena. Después de esto, se produce la transición..

Una transición también puede tener un objeto de transición (un efecto o una animación). Ese objeto creará una presentación dinámica y hermosa cuando ocurra la transición. Existen varios objetos, y para una referencia completa y oficial debe consultar la referencia de la clase SKTransition.


2. Métodos de clase

los SKTransition La clase presenta varios métodos y dos propiedades (más acerca de estos más adelante). El objetivo de todos los métodos es crear una transición brillante y dinámica entre escenas. Los métodos de clase se pueden dividir en cuatro secciones principales:

  • Con Duración: Transiciones que ocurrirán en un período de tiempo definido.
  • Con color: Transiciones que utilizará un UIColor objeto de colorear la transición inherente.
  • Con direccion Transiciones que se harán desde una dirección específica..
  • Con CIFilter: Transiciones que usarán un filtro personalizado para producir un efecto visual en la transición.

Duración y Color son objetos simples, pero ambos Dirección y CIFilter no son.

Como las sugerencias de nombres, la propiedad de dirección significa que la transición se producirá en una dirección específica. La propiedad de dirección puede tener una de cuatro constantes. Estas constantes se declaran como una NS_ENUM, Me gusta esto:

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

CIFilter es incluso más robusto que Dirección ya que también es una clase de referencia con métodos de clase, métodos de instancia y propiedades. Este tutorial no cubrirá el CIFilter clase en profundidad, pero presentará un ejemplo de cómo usarlo para crear un filtro personalizado y el inherente SKTransition. Una nota adicional sobre el CIFilter clase: admite docenas de efectos, pero no todos son compatibles con la última versión de iOS. Debe consultar la Referencia del filtro de imágenes del núcleo para ver la lista de compatibilidad.

Tenga en cuenta que puede utilizar varios "métodos agrupados" para crear un SK brason. ¿Pero cómo sabes cuáles se pueden combinar? Para ello, debe consultar la firma del método y determinar las propiedades aceptadas por cada método..

Por ejemplo, analicemos tres métodos para ver qué pueden manejar:

  • puertasAbiertoVerticalConDuración:
  • fadeWithColor: duración:
  • revelar con direccion: duracion

Como se indicó anteriormente, los nombres de los métodos le permiten comprender rápidamente qué puede hacer cada método. Para elaborar, el puertasAbiertoVerticalConDuración: método sólo tendrá en cuenta una duración El fadeWithColor: duración: El método utiliza tanto un color como una duración. Primero debes definir un UIColor Objeto y luego un tiempo de duración. los revelar con direccion: duracion El método solo usará una dirección que, a su vez, puede ser una de las cuatro propiedades. Tenga en cuenta que también puede extender el SKTransition clase para crear transiciones personalizadas y unirse Duración, Color, Dirección, y CIFilter.


Revelar con la ilustración de la dirección (UP)

3. Propiedades de la clase

los SKTransition La clase solo tiene dos propiedades: pausas incomingescene y pausas salientes. Ambos configuran si las animaciones se reproducen durante la transición y ambas propiedades son Booleano valores. La diferencia es la siguiente:

  • pausas incomingescene determina si la escena entrante se detiene durante la transición.
  • pausas salientes determina si la escena saliente se detiene durante la transición.

Ya que ambos son Booleano valores, la definición es fácil y se puede entender en el siguiente fragmento de código:

 // otro código ... transitionCrossFade = [SKTransition crossFadeWithDuration: 1]; transitionCrossFade.pausesIncomingScene = TRUE; transitionDoorsCloseHorizontal = [SKTransition doorsCloseHorizontalWithDuration: 2]; transitionDoorsCloseHorizontal.pausesOutgoingScene = FALSE;

los pausas incomingescene y pausas salientes Las propiedades en el objeto de transición definen qué animaciones se reproducen durante la transición. Por defecto, ambas escenas continúan procesando la animación durante la transición. Sin embargo, es posible que desee pausar una o ambas escenas hasta que se complete la transición..


4. El Proyecto Tutorial

Ahora que conoces los fundamentos de la SKTransition clase, ahora puede comenzar la fase de programación.

Paso 1

El primer paso es abrir Xcode y comenzar una nueva SpriteKit proyecto. A continuación, debe agregar otro C objetivo clase nombrada TransitionResult y una super clase de SKScene.

El objetivo de este proyecto es tener dos clases que serán intercambiadas entre ellas. El primero (Mi escena ya definido por el Xcode) contendrá una UITableView que mantendrá la referencia a cada SKTransition. El segundo (TransitionResult) será la escena de destino después de una transición.

Cuando el usuario toca la pantalla después de una transición, una vez más será transferido a Mi escena.

Paso 2

En MyScene.h, declararás 3 objetos: a UITableView, UISlider, y un NSArray. los UITableView mostrará los nombres de cada transición, el UISlider definirá el Duración de esa transición, y la NSArray contendrá los nombres de cada uno SKTransition. El final MyScene.h El código será similar a este fragmento:

 @ propiedad (retener, no atómica) IBOutlet UITableView * tableView; @ propiedad (no atómica, retener) IBOutlet UISlider * sliderTimer; @property (strong, nonatomic) NSArray * transitionsArray;

Paso 3

Ahora, enfoca tu atención en el Mi escena archivo de implementación.

El primer paso es utilizar el -(id) initWithSize: (CGSize) tamaño Método para inicializar los objetos antes mencionados. Una posible configuración de configuración es la siguiente:

 _tableView = [[UITableView alloc] initWithFrame: CGRectMake (CGRectGetMinX (selfframe), CGRectGetMinY (selfframe) +20, CGRectGetMaxX (selfframe), CGRectGetMaxY (selfframe) -80)]; _tableView.dataSource = self; _tableView.delegate = self; _sliderTimer = [[UISlider alloc] initWithFrame: CGRectMake (CGRectGetMidX (self.frame) -70, CGRectGetMaxY (self.frame) -40, 140, 3)]; [_sliderTimer addTarget: self action: @selector (sliderAction) forControlEvents: UIControlEventValueChanged]; [_sliderTimer setBackgroundColor: [UIColor clearColor]]; _sliderTimer.minimumValue = 1; _sliderTimer.maximumValue = 4; _sliderTimer.continuous = YES; _sliderTimer.value = 1; _transitionsArray = [[NSArray alloc] initWithObjects: @ crossFadeWithDunationPlanticationPlantication_Acceso_Corrección_Pertición_Agrasas_Perticidad_Agrasa_Perticidad_Agrana_Perticidad_Agrava_Agrana_Pertica_Alta vAcceso_Alto_Perticio_Aparcamiento_Aparcamiento_Alta_Alguna_Pertica_Alta vAcceso_Poricultura_Agrasas_Alta vAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA " , @ "flipHorizontalWithDuration", @ "flipVerticalWithDuration", @ "moveInWithDirectionDown: duration", @ "moveInWithDirectionUp: duration", @ "moveInWithDirectionLeyft: duration", @ "moveInWithDirectionRight: natu duration ", @" transitionWithCIFilter: duration ", nil];

Sin embargo, se presenta una advertencia ya que la sliderAction Está perdido. El método actualizará en tiempo real el transitionTimerText teniendo en cuenta la UISlider valor.

 -(void) sliderAction transitionTimerText.text = [[NSString alloc] initWithFormat: @ "Duración de la transición:% f", _sliderTimer.value]; 

Tenga en cuenta que las vistas, la ubicación, la configuración y el diseño son completamente configurables. Si lo desea, puede ajustar esto para sus mejores intereses. Además, agregará un SKLabelNode para almacenar y mostrar el UISlider valor. Ese valor será representativo de la Duración de la transición efectos Añade el SKLabelNode * transitionTimerText A su archivo de implementación y la inicialización correspondiente será:

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

Etapa 4

Ahora que tiene los objetos configurados, solo necesita agregarlos a la escena. Para eso, usarás el -(void) didMoveToView: (SKView *) view método. Agréguelo a su archivo y dentro agregue las vistas antes mencionadas a la vista principal:

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

Si ejecuta el proyecto ahora verá dos objetos en la pantalla: un UISlider y un SKLabelNode.

Paso 5

El siguiente paso es mostrar el SKTransition métodos en el UITableView. Para esto, necesitas modificar tu MyScene.h archiva y extiende tu clase con el protocolos El final MyScene.h debería verse así:

 @interface MyScene: SKScene 

Regrese al archivo de implementación y aparecerá una advertencia. Esa advertencia dice que necesita implementar métodos adicionales inherentes a la UITableView. Los métodos necesarios son: -(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sección y -(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath. El primero devolverá el número de filas en la tabla, mientras que el segundo manejará la lógica de cada celda dentro de la tabla. Para notas adicionales sobre el UITableView Clase, debes consultar la clase de referencia oficial..

El primer método es simple y es solo una línea:

 -(NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) sección return [_transitionsArray count]; 

El segundo método es más complejo ya que debemos definir las propiedades y las configuraciones de las celdas de la tabla (contenido de las celdas). En este ejemplo, utilizarás un simple UITableViewCellStyleSubtitle. Si tiene problemas para escribir el método, a continuación se presenta la versión completa:

 -(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: transitions]; celda de retorno 

Ejecute su código ahora y debería ver cada línea de celda con un nombre único. Cada nombre representa el inherente SK brason Se usa si el usuario toca esa celda. Usted también notará que el UITableView no tiene titulo Vamos a arreglar eso!

Paso 6

Agregue el siguiente método: - (NSString *) tableView: (UITableView *) tableView titleForHeaderInSection: (NSInteger) sección. Dentro de este método, agregue el siguiente código:

 NSString * sectionName; switch (sección) caso 0: sectionName = NSLocalizedString (@ "SKTransition List", @ "SKTransition List"); descanso; por defecto: sectionName = @ ""; descanso;  return sectionName;

Este método tiene permitido tener múltiples títulos para múltiples UITableView secciones Sin embargo, solo tendremos una sección, por lo que el título será "Lista de SKTransition" (o cualquier otra de su elección).

Paso 7

En este punto, debe agregar la interacción del usuario a las celdas. Para hacer esto, se necesita otro método adicional. Esta vez el -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath El método debe ser llamado. Este método es largo, pero es fácil de entender. Asignarás los recursos necesarios para cada uno. SKTransition y, en función de la celda pulsada, presentarás otra. SKScene.

El primer paso es importar el TransitionResult archivo de encabezado, a continuación, defina un TransitionResult objeto para el resultado SKScene. Echa un vistazo a lo siguiente para ver esto en acción:

 TransitionResult * transitionResult; SKTransition * transitionCrossFade; SKTransition * transition DoorsCloseHorizontal; SKTransition * transition DoorsCloseVertical; Transición de SK * TransposicionesOpenHorizontal SKTransition * transition DoorsOpenVertical; SKTransition * transition Doorway; SKTransition * transitionFadeWithColor; SKTransition * transitionFadeWithDuration; SKTransition * transitionFlipHorizontal; SKTransition * transitionFlipVertical; SKTransition * transitionMoveInWithDirectionDown; SKTransition * transitionMoveInWithDirectionUp; SKTransition * transitionMoveInWithDirectionLeft; SKTransition * transitionMoveInWithDirectionRight; SKTransition * transitionPushWithDirection; SKTransition * transitionRevealWithDirectionUp; SKTransition * transitionWithCIFilter;

Ahora en el -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath Método, es hora de asignar los recursos necesarios. El código completo es:

 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] edge]; CIVector * extensión = [CIVector vectorWithX: 0 Y: 0 Z: screenRect.size.width W: screenRect.size.height]; transitionWithCIFilter = [SKTransition transitionWithCIFilter: [CIFilter filterWithName: @ "CIFlashTransition" keysAndValues: @ "inputExtent", extension, @ "inputCenter", [CIVector vectorWithX: 0.3 * screenRect.size.width Y: 0.7 * screen.ect. @ "inputColor", [CIColor colorWithRed: 1.0 verde: 0.8 azul: 0.6 alpha: 1], @ "inputMaxStriationRadius", @ 2.5, @ "inputStriationStrength", @ 0.5, @ "inputStriationContrast", @ 1.37, @ "inputFadeThreshold", @ 0.85, nil] duración: _sliderTimer.value]; transitionResult = [[TransitionResult alloc] initWithSize: CGSizeMake (CGRectGetMaxX (selfframe), CGRectGetMaxY (selfframe))]; switch (indexPath.row) caso 0: [self.scene.view presentScene: transitionResult transition: transitionCrossFade]; [auto removeUIKitViews]; descanso; caso 1: [self.scene.view presentScene: transitionResult transition: transition DoorsCloseHorizontal]; [auto removeUIKitViews]; descanso; caso 2: [self.scene.view presentScene: transitionResult transition: transitionDoorsCloseVertical]; [auto removeUIKitViews]; descanso; caso 3: [self.scene.view presentScene: transitionResult transition: transitiondoorsOpenHorizontal]; [auto removeUIKitViews]; descanso; caso 4: [self.scene.view presentScene: transitionResult transition: transitionDoorsOpenVertical]; [auto removeUIKitViews]; descanso; caso 5: [self.scene.view presentScene: transitionResult transition: transitionDoorway]; [auto removeUIKitViews]; descanso; caso 6: [self.scene.view presentScene: transitionResult transition: transitionFadeWithColor]; [auto removeUIKitViews]; descanso; caso 7: [self.scene.view presentScene: transitionResult transition: transitionFadeWithDuration]; [auto removeUIKitViews]; descanso; caso 8: [self.scene.view presentScene: transitionResult transition: transitionFlipHorizontal]; [auto removeUIKitViews]; descanso; caso 9: [self.scene.view presentScene: transitionResult transition: transitionFlipVertical]; [auto removeUIKitViews]; descanso; caso 10: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionDown]; [auto removeUIKitViews]; descanso; caso 11: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionUp]; [auto removeUIKitViews]; descanso; caso 12: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionLeft]; [auto removeUIKitViews]; descanso; caso 13: [self.scene.view presentScene: transitionResult transition: transitionMoveInWithDirectionRight]; [auto removeUIKitViews]; descanso; caso 14: [self.scene.view presentScene: transitionResult transition: transitionPushWithDirection]; [auto removeUIKitViews]; descanso; caso 15: [self.scene.view presentScene: transitionResult transition: transitionRevealWithDirectionUp]; [auto removeUIKitViews]; descanso; caso 16: [self.scene.view presentScene: transitionResult transition: transitionWithCIFilter]; [auto removeUIKitViews]; descanso; por defecto: break; 

Recibirá una advertencia que dice que un método (eliminarUIKitViews) Está perdido. Ese método es una simple llamada para eliminar algunas vistas de la vista principal y superior. Si bien simplista, el código necesario es:

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

Ahora para varias notas con respecto a la -(void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath método.

  • los SKTransition La inicialización de la transición es similar a todas las transiciones..
  • El filtro definido es personalizado. Como se indicó anteriormente, puede volver a configurarlo o definir un filtro totalmente nuevo..
  • los Duración el tiempo es definido por el UISlider valor.

Paso 8

Para ejecutar el código y probar las transiciones, deberá completar el TransitionResult clase. Mueve esa clase y agrega el -(id) initWithSize: (CGSize) tamaño método. Es similar a la MyScene.m método. Puedes intentar escribirlo tú mismo. Copie y pegue desde la otra clase para que se vea como el siguiente método:

 -(id) initWithSize: (CGSize) tamaño 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 back"; myLabel.fontSize = 15; myLabel.position = CGPointMake (CGRectGetMidX (self.frame), CGRectGetMidY (self.frame)); [auto addChild: myLabel];  devuélvete a ti mismo; 

Ahora puede ejecutar el código y probar las transiciones. Adelante, pruébalos.!

Paso 9

Como ya habrá notado, cada vez que quiera probar una nueva transición, debe ejecutar el código nuevamente. Entonces, modifiquemos la TransitionResult.m Archivo que permite una navegación infinita. Cada vez que el usuario toque la pantalla, se moverá a la escena inicial..

Necesitarás el -(void) touchesBegan: (NSSet *) toca conEvent: (UIEvent *) event método y tendrá que importar el MyScene.h clase. Entonces, el último paso es asignar e iniciar un objeto de clase e intercambiar las escenas. El siguiente fragmento te ayudará a hacer eso:

 -(void) touchesBegan: (NSSet *) toca withEvent: (UIEvent *) evento MyScene * home = [[MyScene alloc] initWithSize: CGSizeMake (CGRectGetMaxX (selfframe), CGRectGetMaxY (selfframe))]; [self.scene.view presentScene: home]; 

Finalmente, ejecute su programa y pruebe todas las SKTransitions. La siguiente imagen representa una de las transiciones:


Otra ilustración del efecto SKTRansition.

Conclusión

En el transcurso de este SKTransition Tutorial, hemos cubierto lo siguiente:

  • Una visión completa de la SKTransition clase.
  • Cómo crear y configurar todos los SKTransition opciones.
  • Trabajando con SKTransition propiedades.
  • Cómo crear y configurar un UITableView y UISlider y úsalos en paralelo con Sprite Kit..

Si tiene preguntas o comentarios, no dude en dejarlos a continuación.!