I am creating a game in sprite kit using swift, and I am trying to be able to move the SKScene around with a finger because not all of the nodes fit within the scene. I have already created world, overlay, and camera nodes with this code.
override func didMoveToView(view: SKView) {
world = self.childNodeWithName("world")!
if !isCreated {
isCreated = true
// Camera setup
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.world = SKNode()
self.world.name = "world"
addChild(self.world)
self.cam = SKNode()
self.cam.name = "camera"
self.world.addChild(self.cam)
// UI setup
self.overlay = SKNode()
self.overlay.zPosition = 10
self.overlay.name = "overlay"
addChild(self.overlay)
}
I would like to be able to move the camera around by using a pan gesture with a single finger. How would I do this? Any help would be appreciated.
Create a variable that will initialize and host the Game Scene var scene: SKScene { let scene = GameScene() scene.size = CGSize(width: 216, height: 216) scene.scaleMode = .fill return scene } var body: some View { // 3. Using the SpriteView, show the game scene in your SwiftUI view // You can even use modifiers!
Create a variable to host your GameScene object, which will be where your game is in the future. Use the SpriteView (scene:) view to host your GameScene object and show it in your application. import SwiftUI // 1. Import the SpriteKit framework import SpriteKit struct ContentView: View { // 2.
Even though the default Game Xcode Template creates the project based on a UIKit application, you can create a SwiftUI app and put your SpriteKit game inside it without any hustle thanks to the SpriteView view! The documentation page for the SpriteView SwiftUI view.
Import the SpriteKit framework, so you have access to everything it has to offer. Without it you won’t be able to have access to the SKScene class, for example, and you wouldn’t be able to create your GameScene object. Create a variable to host your GameScene object, which will be where your game is in the future.
If anybody needs it, here is an all-in-one solution:
class GameScene: SKScene {
var previousCameraPoint = CGPoint.zero
override func didMove(to view: SKView) {
let panGesture = UIPanGestureRecognizer()
panGesture.addTarget(self, action: #selector(panGestureAction(_:)))
view?.addGestureRecognizer(panGesture)
}
@objc func panGestureAction(_ sender: UIPanGestureRecognizer) {
// The camera has a weak reference, so test it
guard let camera = self.camera else {
return
}
// If the movement just began, save the first camera position
if sender.state == .began {
previousCameraPoint = camera.position
}
// Perform the translation
let translation = sender.translation(in: self.view)
let newPosition = CGPoint(
x: previousCameraPoint.x + translation.x * -1,
y: previousCameraPoint.y + translation.y
)
camera.position = newPosition
}
}
As an alternative to @Kris's solution (which is based in UIKit), you can also monitor touches in Sprite Kit with your SKScene subclass. I wrote a small sample which should point you in the right direction.
class YourSceneSubclass : SKScene
{
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touch = touches.first else {
return
}
let location = touch.locationInNode(self)
let previousLocation = touch.previousLocationInNode(self)
camera?.position.x += location.x - previousLocation.x
camera?.position.y += location.y - previousLocation.y
}
}
I didn't run this, just wrote it in a playground. Also note that if you want to handle other taps/gestures as well you will have to write additional code making sure the recognition works well for all your intended scenarios.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With