En este tutorial, la segunda entrega de la serie SpriteKit From Scratch, aprenderá sobre las restricciones y las acciones. Estas características se utilizan para agregar fácilmente movimientos y animaciones a tu juego SpriteKit, al tiempo que limitan la posición y la orientación de los nodos en el juego..
Para seguirme, puede usar el proyecto que creó en el primer tutorial de esta serie o descargar una copia nueva de GitHub.
Los gráficos utilizados para el juego en esta serie se pueden encontrar en GraphicRiver. GraphicRiver es una gran fuente para encontrar ilustraciones y gráficos para tus juegos.
Antes de poder comenzar a agregar restricciones y acciones a una escena, primero debemos crear algunas clases para poder trabajar con nuestros nodos en el código. Crear una nueva clase, PlayerNode, basado en el iOS> Fuente> Cocoa Touch Class Plantilla y asegúrese de que es una subclase de SKSpriteNode
.
Si Xcode emite un error después de crear la clase, agregue una declaración de importación para el marco SpriteKit debajo de importar UIKit
declaración:
importar UIKit importar SpriteKit
A continuación, declare las siguientes tres propiedades en el PlayerNode
clase. Estas propiedades mantendrán las restricciones utilizadas para limitar el movimiento horizontal del automóvil..
importar UIKit importar SpriteKit class PlayerNode: SKSpriteNode var leftConstraint: SKConstraint! var middleConstraint: SKConstraint! var rightConstraint: SKConstraint!
Crea otro Clase de Cocoa Touch y nombrarlo MainScene, convirtiéndolo en una subclase de SKScene
.
En la parte superior, agregue una declaración de importación para el marco SpriteKit.
importar UIKit importar SpriteKit
Con estas clases creadas, abiertas. MainScene.sks, haga clic en el fondo gris para seleccionar la escena, abra el Inspector de clase personalizado a la derecha, y puesta. Clase personalizada a MainScene.
Selecciona el coche y establece su clase en PlayerNode De la misma manera que hiciste para la escena. Por último, con el coche aún seleccionado, abrir el Inspector de atributos y cambio Nombre a Jugador.
Ahora que hemos configurado las clases básicas, podemos comenzar a crear algunas restricciones en el código.
Restricciones en SpriteKit, representadas por el SKConstraint
clase, se utilizan para limitar la posición y orientación de nodos particulares. Se puede lograr mucha variedad con restricciones, ya que pueden ser relativas a la escena o a otros nodos. Las restricciones también funcionan con rangos de valores además de valores constantes, por lo que los sprites dentro de su escena pueden fijarse en una ubicación específica o pueden moverse dentro de un área determinada.
Las restricciones que vamos a agregar son las tres que declaramos en el PlayerNode
clase. Estas restricciones se utilizarán para bloquear el automóvil en los tres carriles del juego..
Abierto MainScene.swift y crea una propiedad para el jugador de tipo PlayerNode!
. Esta propiedad almacenará una referencia al nodo jugador.
importar UIKit importar SpriteKit clase MainScene: SKScene var player: PlayerNode!
A continuación, anulamos didMoveToView (_ :)
método de la MainScene
clase:
anular la función didMoveToView (ver: SKView) super.didMoveToView (ver) size = view.frame.size si dejar foundPlayer = childNodeWithName ("Player") como? PlayerNode player = foundPlayer let center = size.width / 2.0, Difference = CGFloat (70.0) player.leftConstraint = SKConstraint.positionX (SKRange (constantValue: center - Difference)) player.middleConstraint = SKConstraint.positionX (SKRange (constantValue: center)) player.rightConstraint = SKConstraint.positionX (SKRange (constantValue: center + Difference)) player.leftConstraint.enabled = false player.rightConstraint.enabled = false player.constraints = [player.leftConstraint, player.middleConstraint, player.rightConstraint ]
Vamos a ver el código paso a paso. los didMoveToView (_ :)
El método se llama siempre que la escena es presentada por una vista. Después de llamar al didMoveToView (_ :)
Método de la superclase, redimensionamos la escena al mismo tamaño que la vista actual. Esto asegura que la escena siempre llene el tamaño de la pantalla del dispositivo actual y se ajuste correctamente..
Accedemos al reproductor sprite que agregamos en el editor de escenas de Xcode buscándolo por el nombre que le dimos anteriormente. Entonces le asignamos este valor a la jugador
propiedad.
Después de calcular el centro de la escena y especificar una diferencia constante de 70.0
, Creamos las restricciones del sprite. Utilizando el positionX (_ :)
método de clase de la SKConstraint
clase, creamos las restricciones izquierda, media y derecha para el jugador sprite. Este método requiere una SKRange
instancia como un parámetro, que, en nuestro caso, es un rango con un valor constante. Si desea ver las posibles restricciones y rangos en SpriteKit, le recomiendo echar un vistazo a la SKConstraint
y SKRange
referencias de clase.
Deshabilitamos las restricciones de izquierda y derecha, porque no queremos que estas actúen en el nodo del jugador cuando comienza el juego. Por último, asignamos estas restricciones a la restricciones
Propiedad del nodo jugador. Esta propiedad se define en el SKNode
clase.
Construye y ejecuta tu juego en cualquier simulador o dispositivo físico. Ahora debería ver que su escena se escala correctamente con el auto centrado en la parte inferior.
Puedes ver que el auto ahora está restringido al centro horizontal de la escena y puede ser restringido a los carriles izquierdo y derecho una vez que agregamos algo de movimiento al juego.
Las acciones en SpriteKit están representadas por los poderosos. SKAcción
clase. Las acciones nos permiten animar y mover fácilmente sprites en una escena. Son ejecutados por nodos y evaluados por las API de SpriteKit y funcionan junto con restricciones y simulaciones físicas..
Además de especificar qué hace una acción, también puede programar cómo funciona la acción configurándola. Por ejemplo, puede pausar y reanudar acciones o configurar el comportamiento de aceleración de una acción. Esto te da un mayor grado de control, ya que puedes acelerar o ralentizar fácilmente ciertas acciones para producir algunos elementos de juego interesantes.
De manera similar a cómo los nodos pueden tener nodos secundarios, hay tres tipos de acciones que pueden tener acciones secundarias:
Puede crear acciones mediante programación o en el editor de escenas de Xcode, que usamos en el tutorial anterior. Vamos a utilizar ambas técnicas en este tutorial..
Abierto MainScene.sks y haga clic en el icono junto a la Animar botón en la parte inferior izquierda de la escena para que aparezca el Vista del editor de acciones.
A continuación, desplácese hacia abajo en la Biblioteca de objetos de la derecha y encontrar el Mover acción ít. Haga clic y arrastre esto en la línea de tiempo del Vista del editor de acciones y colóquelo en el borde izquierdo como se muestra a continuación:
Esto hace que la acción comience a ejecutarse en 0:00, Es decir, en cuanto se presenta la escena. Si se coloca en otro lugar, la acción comenzará a ejecutarse después del intervalo de tiempo que se muestra en la parte superior de la línea de tiempo.
Mueva el mouse sobre la acción y haga clic en el icono de flecha pequeña en la parte inferior izquierda. En la ventana emergente que aparece, haga clic en infinito botón de la izquierda. Esto hace que la acción se repita para siempre..
Con la acción aún seleccionada, abre el Inspector de atributos a la derecha y cambiar el Y Offset valor para 100.
Los otros valores especifican que el coche arranca se animará inmediatamente (Hora de inicio) y cada 1 segundo (Duración) Se moverá 0 puntos en el X dirección y 100 en el Y dirección (Compensar). los Función de tiempo La propiedad se puede utilizar para iniciar y / o detener una acción gradualmente. En este caso, estamos utilizando Lineal, lo que significa que el coche siempre se mueve a la misma velocidad.
Finalmente, para probar la acción, haga clic en Animar Botón en la parte inferior izquierda del editor de escenas. La barra de herramientas inferior debería volverse azul y el auto debería comenzar a ascender..
Con la acción de movimiento implementada, es hora de crear las acciones horizontales mediante programación. Antes de hacerlo, debemos agregar algo de lógica para que los botones del juego puedan controlar el auto..
Crea un nuevo archivo eligiendo el iOS> Fuente> Archivo Swift plantilla y nombre LaneStateMachine.
Agregue el siguiente código al nuevo archivo:
import GameplayKit class LaneStateMachine: GKStateMachine class LaneState: GKState var playerNode: PlayerNode init (player: PlayerNode) playerNode = player class LeftLane: LaneState override func isValidNextate (stateClass: AnyClass) -> MiddleLane.self return true return false override func didEnterWithPreviousState (previousState: GKState?) PlayerNode.moveInDirection (.Left, toLane: self) class MiddleLane: LaneState override func isValidNextState (stateClass: ClassClass) - if stateClass == LeftLane.self || stateClass == RightLane.self return true return false override func didEnterWithPreviousState (previousState: GKState?) si previousState es LeftLane playerNode.moveInDirection (.Right, toLane: self) else si previousState es RightLane playerNode.moveInDirection .Left, toLane: self) clase RightLane: LaneState override func isValidNextState (stateClass: AnyClass) -> Bool if stateClass == MiddleLane.self return true return false override func didEnterWithPreviousState (previousState: GKState) playerNode.moveInDirection (.Right, toLane: self)
Todo lo que hace este código es utilizar el nuevo marco GameplayKit para crear una máquina de estados que represente los tres carriles y el movimiento entre ellos en el juego. Si quieres comprender mejor lo que hace este código, consulta mi tutorial que cubre GameplayKit.
A continuación, abrir PlayerNode.swift y agregar los siguientes dos métodos a la PlayerNode
clase:
func disableAllConstraints () leftConstraint.enabled = false middleConstraint.enabled = false rightConstraint.enabled = false func moveInDirection (dirección: ButtonDirection, toLane lane: LaneState) disableAllConstraints () let changeInX = (direction == .Left)? -70.0: 70.0 dejar rotación = (dirección == .Left)? M_PI / 4: -M_PI / 4 let duration = 0.5 let moveAction = SKAction.moveByX (CGFloat (changeInX), y: 0.0, duration: duration) let rotateAction = SKAction.rotateByAngle (CGFloat (rotación), duración: duration / 2) rotateAction.timingMode = .EaseInEaseOut permite rotateSequence = SKAction.sequence ([rotateAction, rotateAction.reversedAction ()]) let moveGroup = SKAction.gnp.pdf. lane case is LeftLane: self.leftConstraint.enabled = true case is MiddleLane: self.middleConstraint.enabled = true case is RightLane: self.rightConstraint.enabled = true default: break let sequenceAction = SKAction.sequence ([moveGroup, completar]) runAction (sequenceAction)
los disableAllConstraints ()
El método es un método conveniente para deshabilitar las restricciones del nodo del jugador..
En moveInDirection (_: toLane :)
, Determinamos en qué dirección debe moverse el automóvil horizontalmente., -70.0 cuando se mueve a la izquierda y +70.0 cuando se mueve a la derecha. Luego calculamos el ángulo correcto (en radianes) para rotar el automóvil cuando se mueve. Tenga en cuenta que los números positivos representan una rotación hacia la izquierda.
Después de especificar una duración constante, creamos las acciones de mover y rotar usando el moveByX (_: y: duration :)
y rotateByAngle (_: duration :)
métodos de clase respectivamente. Creamos una secuencia de rotación para hacer que el carro gire de nuevo a cómo estaba antes del movimiento. los reversedAction ()
El método crea automáticamente el reverso de una acción para ti..
A continuación, creamos una acción de grupo de movimiento para ejecutar el movimiento horizontal y la rotación al mismo tiempo. Finalmente, creamos una acción de finalización para ejecutar un cierre cuando se ejecuta. En este cierre, averiguamos en qué carril está el automóvil actualmente y habilitamos la restricción correcta para ese carril.
Abierto ViewController.swift y añadir una propiedad, máquina estatal
, de tipo LaneStateMachine!
al ViewController
clase.
clase ViewController: UIViewController var stateMachine: LaneStateMachine!…
Reemplazar las implementaciones de viewDidLoad ()
y didPressButton (_ :)
en el ViewController
clase con lo siguiente:
anular la función viewDidLoad () super.viewDidLoad () permite que skView = SKView (frame: view.frame) permita a scene = MainScene (fileNamed: "MainScene")! skView.presentScene (scene) view.insertSubview (skView, atIndex: 0) let left = LeftLane (player: scene.player) let middle = MiddleLane (player: scene.player) let right = RightLane (player: scene.player) stateMachine = LaneStateMachine (indica: [izquierda, central, derecha]) stateMachine.enterState (MiddleLane) @IBAction func didPressButton (sender: UIButton) switch sender.tag case ButtonDirection.Left.rawValue: switch stateMachine.currentState case is RightLane : el estado de stateMachine.enterState (MiddleLane) es MiddleLane: stateMachine.enterState (LeftLane) predeterminado: break case ButtonDirection.Right.rawValue: switch stateMachine.currentState case is LeftLane: stateMachine.enterState (MiddleLane) case is MiddleLane: stateMachineenterenter (RightLane) predeterminado: break predeterminado: break
En viewDidLoad ()
, insertamos el SKView
objeto en el índice 0 Para que los botones de control sean visibles y también inicialicemos la máquina de estados..
En didPressButton (_ :)
, Averiguamos qué botón presionó el usuario, en función de las etiquetas de los botones, y entramos en el carril correcto desde donde se encuentra el automóvil actualmente..
Construye y ejecuta el juego. Presione el botón izquierdo o derecho en la parte inferior de la pantalla para hacer que el automóvil se mueva. Debería ver el automóvil girar y moverse en la dirección del botón que presionó.
Tenga en cuenta que los iconos de los botones pueden no coincidir como se muestra a continuación.
Para solucionarlo, abra el catálogo de activos (Image.xcassets) y para cada imagen (Flecha izquierda y Flecha correcta) conjunto Modo de representación a Imagen original.
Ahora debe tener confianza al usar restricciones y acciones en SpriteKit. Como puedes ver, estas características del marco hacen que sea muy fácil agregar animaciones y movimientos a un juego SpriteKit.
En el siguiente tutorial de esta serie, veremos los nodos de la cámara en SpriteKit para que nuestro auto no siempre se mueva de la parte superior de la pantalla. Después de esto, analizaremos en profundidad el sistema de simulación física en SpriteKit con un enfoque en los cuerpos físicos y la detección de colisiones..
Como siempre, asegúrese de dejar sus comentarios y sugerencias en los comentarios a continuación.