Post

Replies

Boosts

Views

Activity

Reply to Code sharing between iOS and watchOS
Hi CatastropheZero, For the hosting view, use SpriteKit's SwiftUI SpriteView, which renders an SKScene and works on both iOS and watchOS — so you avoid the platform-specific SKView (iOS) vs. WKInterfaceSKScene (watchOS) split. For input, SwiftUI supports the same basic tap/drag gestures on watchOS as on iOS, though you'll often wire them to different in-game actions per platform. There are also inputs unique to watchOS — most notably the Digital Crown via. digitalCrownRotation. To support both cleanly, keep the game logic platform-agnostic and feed it semantic intents rather than raw input. The shared engine never references a touch or the crown — each platform translates its own input into the same intents. /// hardware (touches, drags, Digital Crown) onto these cases. public enum GameIntent { case aim(at: CGPoint) // a scene-space point (e.g. iOS drag/tap location) case moveHorizontal(Double) // a relative nudge (e.g. watchOS Digital Crown delta) case primaryAction // fire / jump / select — a tap on either platform } public final class GameScene: SKScene { private let player = SKShapeNode(circleOfRadius: 20) private var targetX: CGFloat? public override func didMove(to view: SKView) { ... } /// The ONE entry point for input. Platforms call this; the scene never /// touches UIResponder, gestures, or the crown directly. public func apply(_ intent: GameIntent) { switch intent { case .aim(let p): targetX = p.x case .moveHorizontal(let d): targetX = (targetX ?? player.position.x) + CGFloat(d) * 8 case .primaryAction: fire() } } public override func update(_ currentTime: TimeInterval) { ... } private func fire() { ... } } =================================================================================== // iOS — touches → intents SpriteView(scene: scene) .gesture(DragGesture(minimumDistance: 0) .onChanged { scene.apply(.aim(at: scene.convertPoint(fromView: $0.location))) } .onEnded { _ in scene.apply(.primaryAction) }) // watchOS — Digital Crown + tap → the SAME intents SpriteView(scene: scene) .focusable() .digitalCrownRotation($crown) .onChange(of: crown) { _, new in scene.apply(.moveHorizontal(new - last)); last = new } .onTapGesture { scene.apply(.primaryAction) }
Topic: General SubTopic:
Games Technologies Q&A
Jun ’26
Reply to Code sharing between iOS and watchOS
Hi CatastropheZero, For the hosting view, use SpriteKit's SwiftUI SpriteView, which renders an SKScene and works on both iOS and watchOS — so you avoid the platform-specific SKView (iOS) vs. WKInterfaceSKScene (watchOS) split. For input, SwiftUI supports the same basic tap/drag gestures on watchOS as on iOS, though you'll often wire them to different in-game actions per platform. There are also inputs unique to watchOS — most notably the Digital Crown via. digitalCrownRotation. To support both cleanly, keep the game logic platform-agnostic and feed it semantic intents rather than raw input. The shared engine never references a touch or the crown — each platform translates its own input into the same intents. /// hardware (touches, drags, Digital Crown) onto these cases. public enum GameIntent { case aim(at: CGPoint) // a scene-space point (e.g. iOS drag/tap location) case moveHorizontal(Double) // a relative nudge (e.g. watchOS Digital Crown delta) case primaryAction // fire / jump / select — a tap on either platform } public final class GameScene: SKScene { private let player = SKShapeNode(circleOfRadius: 20) private var targetX: CGFloat? public override func didMove(to view: SKView) { ... } /// The ONE entry point for input. Platforms call this; the scene never /// touches UIResponder, gestures, or the crown directly. public func apply(_ intent: GameIntent) { switch intent { case .aim(let p): targetX = p.x case .moveHorizontal(let d): targetX = (targetX ?? player.position.x) + CGFloat(d) * 8 case .primaryAction: fire() } } public override func update(_ currentTime: TimeInterval) { ... } private func fire() { ... } } =================================================================================== // iOS — touches → intents SpriteView(scene: scene) .gesture(DragGesture(minimumDistance: 0) .onChanged { scene.apply(.aim(at: scene.convertPoint(fromView: $0.location))) } .onEnded { _ in scene.apply(.primaryAction) }) // watchOS — Digital Crown + tap → the SAME intents SpriteView(scene: scene) .focusable() .digitalCrownRotation($crown) .onChange(of: crown) { _, new in scene.apply(.moveHorizontal(new - last)); last = new } .onTapGesture { scene.apply(.primaryAction) }
Topic: General SubTopic:
Games Technologies Q&A
Replies
Boosts
Views
Activity
Jun ’26