SpriteKit

RSS for tag

Drawing shapes, particles, text, images, and video in two dimensions using SpriteKit.

SpriteKit Documentation

Posts under SpriteKit tag

101 Posts
Sort by:
Post not yet marked as solved
0 Replies
307 Views
I'm building a game where the player is able to speak commands, so I want to enable speech-to-text capability. I've setup the required info.plist property (for speech recognition privacy) as well as the App Sandbox hardware setting (for audio input). I've confirmed that the application is listening via the audio tap and sending audio buffers to the recognition request. However, the recognition task never executes. NOTE: This is for MacOS, NOT iOS. Also, it works when I have this in a Playground, but when I try to do this in an actual application, the recognition task isn't called. Specs: MacOS: 12.1 XCode: 13.2.1 (13C100) Swift: 5.5.2 Here is the code that I've placed in the AppDelegate of a freshly built SpriteKit application: // // AppDelegate.swift // import Cocoa import AVFoundation import Speech @main class AppDelegate: NSObject, NSApplicationDelegate {   private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!   private let audioEngine = AVAudioEngine()   private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?   private var recognitionTask: SFSpeechRecognitionTask?   func applicationDidFinishLaunching(_ aNotification: Notification) {     SFSpeechRecognizer.requestAuthorization(requestMicrophoneAccess)   }   func applicationWillTerminate(_ aNotification: Notification) {     // Insert code here to tear down your application   }   func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {     return true   }   fileprivate func requestMicrophoneAccess(authStatus: SFSpeechRecognizerAuthorizationStatus) {     OperationQueue.main.addOperation {       switch authStatus {       case .authorized:           self.speechRecognizer.supportsOnDeviceRecognition = true           if let speechRecognizer = SFSpeechRecognizer() {             if speechRecognizer.isAvailable {               do {                 try self.startListening()               } catch {                 print(">>> ERROR >>> Listening Error: \(error)")               }             }           }       case .denied:           print("Denied")                 case .restricted:           print("Restricted")                 case .notDetermined:           print("Undetermined")                 default:           print("Unknown")       }     }   }   func startListening() throws {     // Cancel the previous task if it's running.     recognitionTask?.cancel()     recognitionTask = nil           let inputNode = audioEngine.inputNode     // Configure the microphone input.     let recordingFormat = inputNode.outputFormat(forBus: 0)     inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) {(buffer: AVAudioPCMBuffer, when: AVAudioTime) in /********** * Confirmed that the following line is executing continuously **********/       self.recognitionRequest?.append(buffer)     }     startRecognizing()     audioEngine.prepare()     try audioEngine.start()   }   func startRecognizing() {     // Create a recognition task for the speech recognition session.     recognitionRequest = SFSpeechAudioBufferRecognitionRequest()     guard let recognitionRequestInternal = recognitionRequest else { fatalError("Unable to create a SFSpeechAudioBufferRecognitionRequest object") }     recognitionRequestInternal.shouldReportPartialResults = true     recognitionRequestInternal.requiresOnDeviceRecognition = true /************** * Confirmed that the following line is executed, * however the function given to 'recognitionTask' is never called **************/     recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequestInternal) { result, error in       var isFinal = false               if result != nil {         let firstTranscriptionTimestamp = result!.transcriptions.first?.segments.first?.timestamp ?? TimeInterval.zero         isFinal = result!.isFinal || (firstTranscriptionTimestamp != 0)       }               if error != nil {         // Stop recognizing speech if there is a problem.         print("\n>>> ERROR >>> Recognition Error: \(error)")         self.audioEngine.stop()         self.audioEngine.inputNode.removeTap(onBus: 0)         self.recognitionRequest = nil         self.recognitionTask = nil       } else if isFinal {         self.recognitionTask = nil       }     }   } }
Posted Last updated
.
Post not yet marked as solved
1 Replies
591 Views
GCVirtualController isn't displaying when used with SKScene class. The Virtual controllers appear but then it seems that they are obscured by the SKScene itself!? The documentation says that calling connect() will display the virtual controllers but I seem to be missing how to add the controllers to the SKScene? class GameScene: SKScene { private var _virtualController: Any? @available(iOS 15.0, *) public var virtualController: GCVirtualController? { get { return self._virtualController as? GCVirtualController } set { self._virtualController = newValue } } override func didMove(to view: SKView) { let background = SKSpriteNode(imageNamed: ".jpg") background.zPosition = -1 addChild(background) let virtualConfig = GCVirtualController.Configuration() virtualConfig.elements = [GCInputLeftThumbstick, GCInputRightThumbstick, GCInputButtonA, GCInputButtonB] virtualController = GCVirtualController(configuration: virtualConfig) virtualController?.connect() } } I've also tried adding the virtual controllers in the UIViewController but this doesn't work either.
Posted Last updated
.
Post not yet marked as solved
2 Replies
874 Views
Hi all,I'm having trouble in trying to access the content of a sprite kit particle file in a way that conforms with the recent deprecation of several functions in NSKeyedArchiver.Briefly, my project contains a file named "ParticleSmoke.sks", which I used to access easily with the following lines of code: NSString *smokePath = [[NSBundle mainBundle] pathForResource:@"ParticleSmoke" ofType:@"sks"]; SKEmitterNode* smoke = [NSKeyedUnarchiver unarchiveObjectWithFile:smokePath];now that the unarchiving function has been deprecated, I fail to use the (poorly documented) unarchivedObjectOfClass function. Especially, the code below returns nil. NSString *smokePath = [[NSBundle mainBundle] pathForResource:@"ParticleSmoke" ofType:@"sks"]; NSData* smokeData = [NSData dataWithContentsOfFile:smokePath]; NSError* error=nil; Class cls = [SKEmitterNode class]; SKEmitterNode* smoke = (SKEmitterNode*)[NSKeyedUnarchiver unarchivedObjectOfClass:cls fromData:smokeData error:&error];Unexpectedly, the content of "error" (code 4864) was@"NSDebugDescription" : @"value for key 'NS.objects' was of unexpected class 'NSColor'. Allowed classes are '{(\n SKKeyframeSequence,\n NSArray,\n NSNumber,\n NSMutableArray\n)}'."Has anyone an idea to fix this issue?Thanks for your help....
Posted
by chps67.
Last updated
.
Post not yet marked as solved
2 Replies
279 Views
I am trying to get a simple animated sprite image in a very basic game using SpriteKit and Xcode 12. I am creating an skspritenode with image named and setting its position form the touch point and adding it as a child but a red X image is shown on the simulator of iPhone 8 Plus. I have attached screenshots. Can someone help me with this?
Posted Last updated
.
Post not yet marked as solved
0 Replies
653 Views
Im programmin a plong game import SpriteKit import GameplayKit class GameScene: SKScene {     var ball = SKSpriteNode()     var enemy = SKSpriteNode()     var main = SKSpriteNode()     override func didMove(to view: SKView) {         ball = self.childNode(withName: "ball") as! SKSpriteNode         enemy = self.childNode(withName: "enemy") as! SKSpriteNode         main = self.childNode(withName: "main") as! SKSpriteNode                  ball.physicsBody?.applyImpulse(CGVector(dx: -20, dy: -20))                  let border = SKPhysicsBody (edgeLoopFrom: self.frame)         border.friction = 0         border.restitution = 1         self.physicsBody = border     }     override func touchesBegan(_ touches: Set, with event: UIEvent?) {     for touch in touches {             let location = touch.location(in: self)                      main.run (SKAction.moveTo(x: location.x, duration: 0.2))                      }     }     override func touchesMoved(_ touches: Set, with event: UIEvent?) {     for touch in touches {             let location = touch.location(in: self)                      main.run (SKAction.moveTo(x: location.x, duration: 0.2))                      }     }          override func update(_ currentTime: TimeInterval) {         enemy.run(SKAction.moveTo(x: ball.position.x, duration: 1.0))     } } and it comms a problem "Editor placeholder in source file" what i can do now??
Posted Last updated
.
Post not yet marked as solved
0 Replies
225 Views
When I start my project the tile added to my SKScene using the editor do not appear until after I have clicked on the tiles that was selected in the scene setup. Anyone any ideas why> Also should these tiles be in the list shown to the left of the scene as those sprites (not part of the tileset) I dragged into the scene are. I have attached screen shots of at start and after clicking the tiles.
Posted Last updated
.
Post not yet marked as solved
19 Replies
6.7k Views
The project I'm currently working on will be my last SpriteKit project. With about 14k lines of code I can't afford to switch to another library so I'm stuck for now. I'll never make the same mistake again and rely on this framework though.I had also started sketching out other projects with SpriteKit but will abandon all of them and rebuild with other tools.With all the problems SpriteKit has in iOS 9 and Apple's lack of communication about the issue, have you decided to abandon the framework as well?
Posted
by nilPill.
Last updated
.
Post not yet marked as solved
1 Replies
239 Views
I wanted to build a game for my class like "UniWar: Multiplayer Strategy." It is a hexagonal tile 2d strategy game. Everywhere I search online, everything points to using SpriteKit and using the tile sets to accomplish what I want. The problem I am running into is that there is very little if not poor examples online of using Tile Sets and SpriteKit (or maybe they are super good but my novice skills is getting in the way). Every tutorial I have found is either 6 years old and is unrecognizable or Apple Documentation that tends to explain what it is but not how to use it. I should mention a couple things, one, yes, I am a novice swift programmer and, two, I learn best by doing not by being told (so for example, someone showing me how to use it helps a lot more than "use this code"). I really want to learn so does anyone have some suggestions for learning Tile Sets and SpriteKit in general? P.S. I am also not above a course that costs something (I have already searched Udemy for a course on this but couldn't find one)
Posted
by jhfernan.
Last updated
.
Post marked as solved
1 Replies
516 Views
I'm developing a game that will use speech recognition to execute various commands. I am using code from Apple's Recognizing Speech in Live Audio documentation page. When I run this in a Swift Playground, it works just fine. However, when I make a SpriteKit game application (basic setup from Xcode's "New Project" menu option), I get the following error: required condition is false: IsFormatSampleRateAndChannelCountValid(hwFormat) Upon further research, it appears that my input node has no channels. The following is the relevant portion of my code, along with debug output: let inputNode = audioEngine.inputNode print("Number of inputs: \(inputNode.numberOfInputs)") // 1 print("Input Format: \(inputNode.inputFormat(forBus: 0))") // <AVAudioFormat 0x600001bcf200: 0 ch, 0 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved> let channelCount = inputNode.inputFormat(forBus: 0).channelCount print("Channel Count: \(channelCount)") // 0 <== Agrees with the inputFormat output listed previously // Configure the microphone input. print("Number of outputs: \(inputNode.numberOfOutputs)") // 1 let recordingFormat = inputNode.outputFormat(forBus: 0) print("Output Format: \(recordingFormat)") // <AVAudioFormat 0x600001bf3160: 2 ch, 44100 Hz, Float32, non-inter> inputNode.installTap(onBus: 0, bufferSize: 256, format: recordingFormat, block: audioTap) // <== This is where the error occurs. // NOTE: 'audioTap' is a function defined in this class. Using this defined function instead of an inline, anonymous function. The code snippet is included in the game's AppDelegate class (which includes import statements for Cocoa, AVFoundation, and Speech), and executes during its applicationDidFinishLaunching function. I'm having trouble understanding why Playground works, but a game app doesn't work. Do I need to do something specific to get the application to recognize the microphone? NOTE: This if for MacOS, NOT iOS. While the "How To" documentation cited earlier indicates iOS, Apple stated at WWDC19 that it is now supported on the MacOS. NOTE: I have included the NSSpeechRecognitionUsageDescription key in the applications plist, and successfully acknowledged the authorization request for the microphone.
Posted Last updated
.
Post not yet marked as solved
0 Replies
172 Views
I'm toying around with SpriteKit and using SKS files to construct scenes. I've started with the stock Game project and added one extra SKS file and a class to go along with it. My class will attempt to load the SKS file to build its scene just like the stock files do. However, when I go to the GameViewController and actually try to use my class, I get a runtime error that my SKS file can't be found. I've verified that the SKS file is in the project, is part of the bundle, is visible at runtime from within the bundle, but my class that uses the SKScene initializer to load the file can't see it and I'm not sure why.
Posted Last updated
.
Post not yet marked as solved
0 Replies
170 Views
How does one lock the pointer on the macOS using an NSViewController with SpriteKit and GameController. On iOS we can use the prefersPointerLocked solution from WWDC2020. https://developer.apple.com/videos/play/wwdc2020/10617/
Posted Last updated
.
Post not yet marked as solved
4 Replies
986 Views
Ciao, I would like to use SpriteKit within SwiftUI on WatchOS 7. Which works fabulously on iOS 14 via SpriteView(scene: scene) But when I use the same code from iOS 14: import SwiftUI import SpriteKit class GameScene: SKScene { override func didMove(to view: SKView) { physicsBody = SKPhysicsBody(edgeLoopFrom: frame)     } } SKView throws an error. And now I'm not sure how to use SpiteKit within SwiftUI on watchOS 7. Before with WatchKit. I used WKInterfaceSKScene... via Storyboard. I would love to get some some suggestions what I've been missing. Grazie Vasco
Posted Last updated
.
Post not yet marked as solved
0 Replies
155 Views
I want to learning make a sample game on Apple Watch which install watchOS 8. I use SwiftUI to wrap the SpriteView for displaying the game scene. All work fine except handling the touch event. When I override the function " touchesEnded " in GameScene, it report error for no such function on watchOS. How to handle the tap event on watchOS ? Any suggestion is welcome, thank you. struct ContentView: View {     var sz = WKInterfaceDevice.current().screenBounds.size     var scene: SKScene {         let scene = GameScene()         scene.size = sz         scene.scaleMode = .resizeFill         return scene     }          var body: some View {         SpriteView(scene: scene)             .frame(width: sz.width, height: sz.height)             .ignoresSafeArea()     } } class GameScene: SKScene {     override func sceneDidLoad() {         print("sceneDidLoad size=\(size.width),\(size.height)")         myInit()     }   override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { // build error for no touchesEnded func on watchOS } }
Posted
by Ericba.
Last updated
.
Post not yet marked as solved
2 Replies
335 Views
I have a game with SpriteKit for iPhone, iPad and Mac. I am gonna make for Apple TV. But I take it override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { doesn't work for tvOS. Then what I am supposed to use to make my buttons selectable and I can press ones?
Posted
by matovsky.
Last updated
.
Post not yet marked as solved
1 Replies
346 Views
While learning and playing around with Swift and Spritekit i run into an issue: I can´t seem to create many SKShapeNodes at Runtime. I am trying to fill the Screen with "random" Triangles (The green Triangle on top is just a "dummy" Triangle moving from the left to the right so i get to see the FPS) These brown-ish Triangles are SKShapeNodes created like this: func createTwoFloorTrianglesAtLocation(xPos:CGFloat, yPos:CGFloat, width:CGFloat, height:CGFloat, orientation:Bool) -> [SKShapeNode] { let path1 = UIBezierPath() let path2 = UIBezierPath() if orientation { path1.move(to: CGPoint(x: xPos, y: yPos)) path1.addLine(to: CGPoint(x: xPos, y: yPos + height)) path1.addLine(to: CGPoint(x: xPos + width, y: yPos)) path2.move(to: CGPoint(x: xPos + width, y: yPos)) path2.addLine(to: CGPoint(x: xPos + width, y: yPos + height)) path2.addLine(to: CGPoint(x: xPos, y: yPos + height)) } else { path1.move(to: CGPoint(x: xPos, y: yPos)) path1.addLine(to: CGPoint(x: xPos + width, y: yPos + height)) path1.addLine(to: CGPoint(x: xPos, y: yPos + height)) path2.move(to: CGPoint(x: xPos + width, y: yPos)) path2.addLine(to: CGPoint(x: xPos, y: yPos)) path2.addLine(to: CGPoint(x: xPos + width, y: yPos + height)) } let triangle1 = SKShapeNode(path: path1.cgPath) triangle1.fillColor = groundColors[GKRandomSource.sharedRandom().nextInt(upperBound: groundColors.count)]! triangle1.name = "colorSprite" triangle1.lineWidth = 0.0 let triangle2 = SKShapeNode(path: path2.cgPath) triangle2.fillColor = groundColors[GKRandomSource.sharedRandom().nextInt(upperBound: groundColors.count)]! triangle2.name = "colorSprite" triangle2.lineWidth = 0.0 return [triangle1, triangle2] } I add these Triangles calling #addChild(SKNode) to the GameScene. These Triangles don´t move or anything, they are supposed to disappear later in the Game by "drawing lines" above them. The Problem is that i get very bad FPS and a high CPU-Usage as well as a high Power-Usage in both the XCode-Simulator and on a real Device (iPhone 13 Pro Max, too). If i reduce the Amount of Triangles it gets better, but i´d like to not do that. Is there any way to fix this issue? I also read online (https://stackoverflow.com/questions/23461966/create-an-sktexture-from-an-skshapenode) that some use SKSpriteNode instead of SKShapeNode. But if use the following code to "convert" my ShapeNodes to SpriteNodes before adding them as a Child to the Scene, i see the Node-Counter in the Bottom left is also around 1000ish but there are no Rectangles rendered. func addNodesToParent(_ stuff:[SKShapeNode]) { for n in stuff { addChild(SKSpriteNode(texture: self.view?.texture(from: n))) //addChild(n) } } I hope someone has an idea that i can try. Thanks in advance, Greetings, Nico
Posted
by Nico770.
Last updated
.
Post not yet marked as solved
0 Replies
209 Views
What I'm try to do, is replicate some digital instrument gauge ...using Spritekit.. On my project I have to use a SpriteKit Scene as material for Scenekit SCNnode. In order to do that I create a sub class of SKscene and and apply it as "material.diffuse.contents" of the SCNNode. all working fine, I can see my SKscene as material of the SCNNode. Here the issue: I try to animate/replicate the correct indication of the instrument based of some value my app received from other source. To do so, i decide to use the SKsceneDelegate and use the method "update(_ currentTime: TimeInterval)" simply the update method look for the sknode of the green needle "fulcro" remove it , and make a new line calculating the angle and new coordinate for the new line. Like this I should have a smooth needle indication... Here is the update method inside my subclass SKscene: override func update(_ currentTime: TimeInterval) {                  guard let fulcroToRemove = self.childNode(withName: "fulcro") else {return}         fulcroToRemove.removeFromParent() // issue here...          let fulcro = SKNode()         fulcro.name = "fulcro"         fulcro.position = CGPoint(x: 300, y: 260)         let line = makeLine(startPos: CGPoint(x: 0, y: 0),                             endPos: getCoordinate(angleDeg: getCurrentEGT()),                             name: "EGT_LINE")         fulcro.addChild(line)         self.addChild(fulcro)     } here how I apply the material SKscene to my SCNnode class LowerECAM : SCNNode {     var systems: PlaneSystems     init(systems: PlaneSystems) { self.systems = systems         super.init()         createLowerECAM()     }     required init?(coder: NSCoder) {         fatalError("init(coder:) has not been implemented for Make Cockpit")     }     func createLowerECAM(){ systems.lowerECAMView.presentScene(systems.newAPU)         let plane = SCNPlane(width: 1, height: 1)         let material = SCNMaterial()         material.isDoubleSided  = true         material.diffuse.contents = systems.lowerECAMView.scene // apply here plane.materials = [material]         let lowerECAM = SCNNode(geometry: plane)         lowerECAM.eulerAngles = SCNVector3(deg2rad(180), deg2rad(90), 0)         lowerECAM.scale = SCNVector3(3.3, 3.3, 3.3)         self.name = "LowerECAM"         self.addChildNode(lowerECAM)     }     func deg2rad(_ number: Double) -> Double {         return number * .pi / 180     }   func rad2deg(_ number: Double) -> Double {         return number * 180 / .pi     } } But.. I'm getting the following crash: Question?? why scene kit crash when the render I'm using is the Spritekit render.. ?? I did't even write the SceneKit render method.. The issue looks like is when I remove the "fulcro" but I can't find the solution. I tried to make a new project only with spritekit and it works perfect.. can't understand why as material of SCNode it crash. Any Suggestion.. Appreciate.. Thanks a lot
Posted
by dm1886.
Last updated
.