SpriteKit

RSS for tag

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

SpriteKit Documentation

Posts under SpriteKit subtopic

Post

Replies

Boosts

Views

Activity

SpriteKit SKScene Can't Find SKS File
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.
0
0
497
Dec ’21
How to handle touch event when use SwiftUI & SpriteView on watchOS 8
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 } }
0
0
488
Dec ’21
SKShapeNode bad Performance
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
1
0
953
Dec ’21
Spritekit as material of SCNnode.. crash.. bad
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
0
0
1.1k
Dec ’21
Drag and Drop Activity
Hello, please excuse this question if it seems too simple.. I am new to this and trying to learn :). Im after developing a children's app where the child would drag items into place for example images of numbers being placed in the correct drop areas etc. I don't want to use Unity for this and im keen to learn native swift... Any tips, pointers or starting points would be really welcome for this project please. Be Gentle I am totally new to this! :) Chris
1
0
509
Dec ’21
SKEmitterNode ignoring zPosition on iOS
When compiling and testing an old game (Paul Pixel - The Awakening) on the latest Xcode 12.3 for the latest iOS 14.3, the Spritekit particles appeared on top. The SKEmitterNode.zPosition value was ignored. I regularly compile the app with Xcode. So this regression happened with either iOS 14.2 or Xcode 12.2. It doesn't happen when compiling for macOS. The bug is on iOS only. Does anybody have the same problem? I have already reported the bug to Apple, but they're not responding.
3
0
1.1k
Nov ’21
How do I call scenes without using sks files in Objective-C?
I'm certain this has been asked before, but I do not want to use sks files. I have some very old Cocos2d code that I'm trying to port without a complete rewrite. I would rather programatically move my scene sprites around based on the screensize and do it in Obj-C. It is unclear to me how to do this. I sort of found an answer here: https://stackoverflow.com/questions/43927323/are-spritekit-scene-sks-files-necessary-in-my-project Tried to do something equivalent in Obj-C, but got no where.
1
0
690
Nov ’21
Sound effects in SpriteKit - memory and frame rate issues
I am working on my first game. I was using SKAction.playSoundFileNamed() to play .wav files in my assets, but this was causing problematic memory use growth. After looking online and reading that method has been linked to leaks, I switched to SKAudioNodes. I have added many of those to my scene, and they work, but the frame rate is lower now than before. Any suggestions? I had used this (but I had memory usage growing): let hiss = SKAction.playSoundFileNamed("hiss.wav", waitForCompletion: false) run(hiss) Now I have this (but frame rates are down): let hiss: SKAudioNode = SKAudioNode(fileNamed: "hiss.wav") hiss.autoplayLooped = false hiss.isPositional = false addChild(hiss) hiss.run(SKAction.play())  Any tips?
1
0
816
Nov ’21
SpriteKit draw calls not batched when using a texture atlas from data stored in the app bundle
It seems that SpriteKit doesn't batch the draw calls for textures in the same texture atlas. There are two different behaviors, based on how the SKTextureAtlas gets initialized: The draw calls are not batched when the texture atlas is initialized using SKTextureAtlas(named:) (loading the texture atlas from data stored in the app bundle). But the draw calls seem to be batched when the texture atlas is created dynamically using SKTextureAtlas(dictionary:). The following images show the two different behaviors and the SpriteAtlas inside the Assets Catalog. 1. Draw calls not batched: 2. Draw calls batched: The SpriteAtlas: I created a sample Xcode 13 project to show the different behavior: https://github.com/clns/spritekit-atlas-batching. I have tried this on the iOS 15 simulator on macOS Big Sur 11.6.1. The code to reproduce is very simple: import SpriteKit class GameScene: SKScene { override func didMove(to view: SKView) { let atlas = SKTextureAtlas(named: "Sprites") // let atlas = SKTextureAtlas(dictionary: ["costume": UIImage(named: "costume")!, "tank": UIImage(named: "tank")!]) let costume = SKSpriteNode(texture: atlas.textureNamed("costume")) costume.setScale(0.3) costume.position = CGPoint(x: 200, y: 650) let tank = SKSpriteNode(texture: atlas.textureNamed("tank")) tank.setScale(0.3) tank.position = CGPoint(x: 500, y: 650) addChild(costume) addChild(tank) } } Am I missing something?
1
0
1.2k
Nov ’21
Rendering issues (objects blurred, frame dimensions = 1) when SKScene is inside SwiftUI context
I am developing an app that contains a SpriteKit scene embedded inside a SwiftUI context.I am trying to render a simple SKShapeNode like this:import Foundation import SpriteKit class UIConnection: SKShapeNode { override init() { super.init() self.fillColor = UIColor.clear self.strokeColor = UIColor.blue self.lineWidth = 0.01 } func updatePositions(node1 : CGPoint, node2 : CGPoint) { let path = CGMutablePath() path.move(to: node1) path.addLine(to: CGPoint(x: node1.x, y: node2.y)) path.addLine(to: CGPoint(x: node2.x, y: node2.y)) path.addLine(to: CGPoint(x: node2.x, y: node1.y)) path.addLine(to: node1) self.path = path } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } }When I am adding that Node inside the standard SpriteKit game project template in XCode (without any SwiftUI things), everything is working fine, I get a non-filled rectangle with a blue outline. The frame.width and frame.height variables are valid pixel dimensions like 750 x 1334.let node = UIConnection() self.addChild(node) node.updatePositions(node1: CGPoint(x: frame.midX-frame.width/4, y: frame.midY-frame.height/4), node2: CGPoint(x: frame.midX+frame.width/4, y: frame.midY+frame.height/4))Now I want to embed the SKScene inside a SwiftUI context using this approach:https://dev.to/sgchipman/using-spritekit-with-swiftui-ibcFirst thing I encounter is the fact that frame.width and frame.height both result in a value of 1.Adding the above node to the embedded SKScene results in an extremely blurred rectangle, so no solid line but some weird cloudy object.
1
0
1.1k
Nov ’21
iPhone app rejected for UI layout
I developed an app for iPad earlier this year and finally got around to making a version for iPhone. It's a very simple interactive animation built with SpriteKit. The problem is the layout and design elements are all designed to fit the resolution of my iPhone 11. When I submitted it for review and they tested it on smaller devices the layout gets cropped. All of the code is also specific to that screen size since it gets the location of the touch and checks if its x and y value are within the space of a designated button before performing the associated action. Is there a way to only make the app available to iPhone models 11 and newer? If not, what should I do?
3
0
1.7k
Oct ’21
SKAudioNode .isPositional property on buffered audio
Hi everyone, I am currently trying to use the SKAudioNode .isPositional property in order to have a positional audio feedback for the nodes audio source. While this is easy to accomplish just loading in a file as SKAudioNode source, I am having a hard time doing so when I am buffering the audio via an AVAudioPlayerNode. In general the setup is working to load and play audio, but I am not sure if I correctly setup the EnvironmentNode in order to use the .isPositional property. Any thoughts and help is highly appreciated, here is my code: class GameScene: SKScene { var audioFilePlayer = AVAudioPlayerNode()     var envNode: AVAudioEnvironmentNode!;     var bufferFormat = AVAudioPCMBuffer() override func didMove(to view: SKView) {  let player = SKSpriteNode(imageNamed: "player")         player.position =  CGPoint(x:0,y:0)         scene?.addChild(player)                      guard let filePath = Bundle.main.path(forResource: "bass2", ofType: "m4a") else{ return }         let fileURL = URL(fileURLWithPath: filePath)         var backgroundMusic = SKAudioNode()         player.addChild(backgroundMusic)         do {             let audioFile = try AVAudioFile(forReading: fileURL)             let audioFormat = audioFile.processingFormat             let audioFrameCount = UInt32(audioFile.length)             guard let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount) else { return }             try audioFile.read(into: audioFileBuffer)             // connect the nodes, and use the data to play             let mainMixer = audioEngine.mainMixerNode             backgroundMusic.avAudioNode = audioFilePlayer             envNode = AVAudioEnvironmentNode();             self.audioEngine.attach(envNode);             scene?.audioEngine.attach(backgroundMusic.avAudioNode!)             scene!.audioEngine.connect(backgroundMusic.avAudioNode!, to: envNode, format: audioFileBuffer.format)             scene!.audioEngine.connect(envNode, to: mainMixer, format: audioFileBuffer.format)                      try scene?.audioEngine.start()             audioFilePlayer.play()             audioFilePlayer.scheduleBuffer(audioFileBuffer, completionHandler: nil)                      } catch {             print(error)         }         backgroundMusic.position = CGPoint(x:0,y:0)         label?.addChild(backgroundMusic)     }
1
0
701
Oct ’21
[Metal Compiler Warning] unknown variable
Hi everyone, Running Xcode 12, I'm developing a standalone WatchOS App using Spritekit. I'm using a simple Palette-swap shader using a SKShader with several SKAttributes. The shader seems to work fine, however I get the following message in the console: [Metal Compiler Warning] Warning: Compilation succeeded with:  program_source:3:19: warning: unused variable 's' constexpr sampler s(coord::normalized, I have no idea what this means, there is no variable 's' in my code so I guess this is an issue because GLGS shader code gets compiled to Metal in the background and it goes wrong there? How do I verify this? It seems there is a memory leak associated with this error so I'm prone to solve it. Any help would be appreciated, even if it's just pointing me in a direction. (Like, should I write a new palette shader in Metal?) Thanks in advance! The function that adds the SKShader (an extension to SKSpriteNode): func addMultiColorShader(strokeColor: UIColor, colors:[UIColor]) {         let useColors:[UIColor] = shaderColors(colors)         var attributes:[SKAttribute] = [SKAttribute(name: "a_size", type: .vectorFloat2),                                         SKAttribute(name: "a_scale", type: .vectorFloat2),                                         SKAttribute(name: "a_alpha", type: .float)]                  let colorNames:[String] = ["a_color0","a_color1","a_color2","a_color3"]         for i in 0..<colorNames.count {             attributes += [SKAttribute(name: colorNames[i], type: .vectorFloat4)]         }         let shader = SKShader(fromFile: "SKHMultiColorize", attributes: attributes)         setShaderAttributes(size: self.size, scale: CGSize(width: self.xScale, height: self.yScale), alpha: self.alpha)         setShaderColors(strokeColor: strokeColor, color1: useColors[0], color2: useColors[1], color3: useColors[2])         self.shader = shader     } The actual shader code (OpenGL GS): vec2 nearestNeighbor(vec2 loc, vec2 size) {     vec2 onePixel = vec2(1.0, 1.0) / size;     vec2 coordinate = floor(loc * size) / size; // round     return coordinate + (onePixel * 0.5); } void main() {     vec4 colors[4];     colors[0] = a_color0;     colors[1] = a_color1;     colors[2] = a_color2;     colors[3] = a_color3;              vec4 currentColor = texture2D(u_texture, nearestNeighbor(v_tex_coord, a_size));     int colorIndex = int((currentColor.r * 5.1));      vec4 refColor = colors[colorIndex];     gl_FragColor = refColor * currentColor.a; }
4
1
2.4k
Oct ’21
Precompile SKShader
Is there a way to force precompilation of SKShader()s? I am initializing a basic shader in my SKScene properties, but the shader only gets compiled when it is actually attached and rendered to a sprite. class GameScene: SKScene {   let myShader = SKShader(fileNamed: "myEffect.fsh") override func update(_ currentTime: TimeInterval) { if touches.count > 0 { mySprite.shader = myShader // this is where the warning triggers for the first time } } } I know this because the scene pauses for a bit, immediately before the shader is rendered for the first time, and I also get the Metal warning (which seems to also be a known bug in recent releases - https://developer.apple.com/forums/thread/661774): [Metal Compiler Warning] Warning: Compilation succeeded with:  program_source:3:19: warning: unused variable 's' constexpr sampler s(coord::normalized, I was expecting the shader to compile when it is initialized with SKShader(fileNamed:), since Apple docs says: Compiling a shader and the uniform data associated with it can be expensive. Because of this, you should: Initialize shader objects when your game launches, not while the game is running. https://developer.apple.com/documentation/spritekit/skshader
2
0
1.1k
Oct ’21
I seem to have lost the SpriteKit scene editor. Help!
For some reason, when I select an .sks file in the navigator, the editor for the scene doesn't show up. I do see the scene hierarchy, which usually appears on the left in the editor, but the actual scene, showing the sprites, labels, etc., is entirely missing. Is there some setting that causes .sks files to not be shown that I need to change? I've updated to the newest release, and cleared out the Xcode preferences in ~/Library/Application Support/Xcode, but the problem persists.
2
0
732
Oct ’21
How can I change the bounce of SKSpriteNode dynamically?
I have a very simple app. All SKSpriteNodes, myBall, myBlue, and myRed. Only myBall moves, affected by gravity, and bounces off of different objects (myRed and myBlue). What I can't figure out is how to make myBall bounce harder or softer depending on which body it hits? I hav been playing with the density of all the objects, but it doesn't seem to make any difference? Is there some property I am unaware of? Or are there other methods?
0
0
404
Oct ’21
SKFieldNode isExclusive doesn't work
SKFieldNode.isExclusive = true doesn't seem to work. I created a very simple example in the Game Playground, with two intersecting electric fields and a third object placed at the intersection of the fields, with a negative charge. Each field pulls the object towards its center. The first field (left side) has isExclusive=true, the second field (right side) has isExclusive=false. So based on the definition, the exclusive field is suppressing any other field in its region of effect, and since the object is in both regions, it should be pulled towards the field that is exclusive. Instead, the object doesn't move, since both fields are exerting the same forces on it. The object gets pulled by both fields, thus not moving. If one field is disabled using isEnabled = false, the object immediately starts to move towards the field that is enabled. Playground code: import PlaygroundSupport import SpriteKit class GameScene: SKScene {       override func didMove(to view: SKView) {           /*      Configure two intersecting electric fields      */           let field1 = SKFieldNode.electricField()     field1.region = SKRegion(radius: 190)     field1.position = CGPoint(x: -160, y: 0)     field1.isExclusive = true     addChild(field1)           let field2 = SKFieldNode.electricField()     field2.region = SKRegion(radius: 190)     field2.position = CGPoint(x: 160, y: 0)     field2.isExclusive = false     addChild(field2)           /*      Configure some visuals (shapes and labels) for the fields,      since SKView.showsFields doesn't work.      */           let field1Visual = SKShapeNode(circleOfRadius: 190)     field1Visual.strokeColor = .yellow     field1Visual.addChild(SKLabelNode(text: "isExclusive=true"))     field1.addChild(field1Visual)           let field2Visual = SKShapeNode(circleOfRadius: 190)     field2Visual.addChild(SKLabelNode(text: "isExclusive=false"))     field2.addChild(field2Visual)           /*      Configure object placed at the intersection of the two electric fields,      with a negative charge, so each field attracts this object.      */           let object = SKShapeNode(circleOfRadius: 25)     object.strokeColor = .magenta     object.physicsBody = SKPhysicsBody.init(circleOfRadius: 25)     object.physicsBody!.affectedByGravity = false     object.physicsBody!.charge = -0.1 // is attracted     addChild(object)   } } let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480)) let scene = GameScene(size: CGSize(width: 1024, height: 768)) scene.anchorPoint = CGPoint(x: 0.5, y: 0.5) scene.scaleMode = .aspectFill sceneView.presentScene(scene) sceneView.showsFields = true // doesn't work for electricField() and is broken for other fields PlaygroundSupport.PlaygroundPage.current.liveView = sceneView A bug report was also submitted on Feedback assistant, FB9661601.
0
0
701
Oct ’21
SpriteKit SKScene Can't Find SKS File
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.
Replies
0
Boosts
0
Views
497
Activity
Dec ’21
Is there prefersPointerLocked for NSViewController?
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/
Replies
0
Boosts
0
Views
501
Activity
Dec ’21
How to handle touch event when use SwiftUI & SpriteView on watchOS 8
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 } }
Replies
0
Boosts
0
Views
488
Activity
Dec ’21
touchesBegan for tvOS in the game?
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?
Replies
2
Boosts
0
Views
765
Activity
Dec ’21
SKShapeNode bad Performance
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
Replies
1
Boosts
0
Views
953
Activity
Dec ’21
Spritekit as material of SCNnode.. crash.. bad
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
Replies
0
Boosts
0
Views
1.1k
Activity
Dec ’21
Drag and Drop Activity
Hello, please excuse this question if it seems too simple.. I am new to this and trying to learn :). Im after developing a children's app where the child would drag items into place for example images of numbers being placed in the correct drop areas etc. I don't want to use Unity for this and im keen to learn native swift... Any tips, pointers or starting points would be really welcome for this project please. Be Gentle I am totally new to this! :) Chris
Replies
1
Boosts
0
Views
509
Activity
Dec ’21
SKEmitterNode ignoring zPosition on iOS
When compiling and testing an old game (Paul Pixel - The Awakening) on the latest Xcode 12.3 for the latest iOS 14.3, the Spritekit particles appeared on top. The SKEmitterNode.zPosition value was ignored. I regularly compile the app with Xcode. So this regression happened with either iOS 14.2 or Xcode 12.2. It doesn't happen when compiling for macOS. The bug is on iOS only. Does anybody have the same problem? I have already reported the bug to Apple, but they're not responding.
Replies
3
Boosts
0
Views
1.1k
Activity
Nov ’21
How do I call scenes without using sks files in Objective-C?
I'm certain this has been asked before, but I do not want to use sks files. I have some very old Cocos2d code that I'm trying to port without a complete rewrite. I would rather programatically move my scene sprites around based on the screensize and do it in Obj-C. It is unclear to me how to do this. I sort of found an answer here: https://stackoverflow.com/questions/43927323/are-spritekit-scene-sks-files-necessary-in-my-project Tried to do something equivalent in Obj-C, but got no where.
Replies
1
Boosts
0
Views
690
Activity
Nov ’21
Sound effects in SpriteKit - memory and frame rate issues
I am working on my first game. I was using SKAction.playSoundFileNamed() to play .wav files in my assets, but this was causing problematic memory use growth. After looking online and reading that method has been linked to leaks, I switched to SKAudioNodes. I have added many of those to my scene, and they work, but the frame rate is lower now than before. Any suggestions? I had used this (but I had memory usage growing): let hiss = SKAction.playSoundFileNamed("hiss.wav", waitForCompletion: false) run(hiss) Now I have this (but frame rates are down): let hiss: SKAudioNode = SKAudioNode(fileNamed: "hiss.wav") hiss.autoplayLooped = false hiss.isPositional = false addChild(hiss) hiss.run(SKAction.play())  Any tips?
Replies
1
Boosts
0
Views
816
Activity
Nov ’21
SpriteKit draw calls not batched when using a texture atlas from data stored in the app bundle
It seems that SpriteKit doesn't batch the draw calls for textures in the same texture atlas. There are two different behaviors, based on how the SKTextureAtlas gets initialized: The draw calls are not batched when the texture atlas is initialized using SKTextureAtlas(named:) (loading the texture atlas from data stored in the app bundle). But the draw calls seem to be batched when the texture atlas is created dynamically using SKTextureAtlas(dictionary:). The following images show the two different behaviors and the SpriteAtlas inside the Assets Catalog. 1. Draw calls not batched: 2. Draw calls batched: The SpriteAtlas: I created a sample Xcode 13 project to show the different behavior: https://github.com/clns/spritekit-atlas-batching. I have tried this on the iOS 15 simulator on macOS Big Sur 11.6.1. The code to reproduce is very simple: import SpriteKit class GameScene: SKScene { override func didMove(to view: SKView) { let atlas = SKTextureAtlas(named: "Sprites") // let atlas = SKTextureAtlas(dictionary: ["costume": UIImage(named: "costume")!, "tank": UIImage(named: "tank")!]) let costume = SKSpriteNode(texture: atlas.textureNamed("costume")) costume.setScale(0.3) costume.position = CGPoint(x: 200, y: 650) let tank = SKSpriteNode(texture: atlas.textureNamed("tank")) tank.setScale(0.3) tank.position = CGPoint(x: 500, y: 650) addChild(costume) addChild(tank) } } Am I missing something?
Replies
1
Boosts
0
Views
1.2k
Activity
Nov ’21
Rendering issues (objects blurred, frame dimensions = 1) when SKScene is inside SwiftUI context
I am developing an app that contains a SpriteKit scene embedded inside a SwiftUI context.I am trying to render a simple SKShapeNode like this:import Foundation import SpriteKit class UIConnection: SKShapeNode { override init() { super.init() self.fillColor = UIColor.clear self.strokeColor = UIColor.blue self.lineWidth = 0.01 } func updatePositions(node1 : CGPoint, node2 : CGPoint) { let path = CGMutablePath() path.move(to: node1) path.addLine(to: CGPoint(x: node1.x, y: node2.y)) path.addLine(to: CGPoint(x: node2.x, y: node2.y)) path.addLine(to: CGPoint(x: node2.x, y: node1.y)) path.addLine(to: node1) self.path = path } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } }When I am adding that Node inside the standard SpriteKit game project template in XCode (without any SwiftUI things), everything is working fine, I get a non-filled rectangle with a blue outline. The frame.width and frame.height variables are valid pixel dimensions like 750 x 1334.let node = UIConnection() self.addChild(node) node.updatePositions(node1: CGPoint(x: frame.midX-frame.width/4, y: frame.midY-frame.height/4), node2: CGPoint(x: frame.midX+frame.width/4, y: frame.midY+frame.height/4))Now I want to embed the SKScene inside a SwiftUI context using this approach:https://dev.to/sgchipman/using-spritekit-with-swiftui-ibcFirst thing I encounter is the fact that frame.width and frame.height both result in a value of 1.Adding the above node to the embedded SKScene results in an extremely blurred rectangle, so no solid line but some weird cloudy object.
Replies
1
Boosts
0
Views
1.1k
Activity
Nov ’21
iPhone app rejected for UI layout
I developed an app for iPad earlier this year and finally got around to making a version for iPhone. It's a very simple interactive animation built with SpriteKit. The problem is the layout and design elements are all designed to fit the resolution of my iPhone 11. When I submitted it for review and they tested it on smaller devices the layout gets cropped. All of the code is also specific to that screen size since it gets the location of the touch and checks if its x and y value are within the space of a designated button before performing the associated action. Is there a way to only make the app available to iPhone models 11 and newer? If not, what should I do?
Replies
3
Boosts
0
Views
1.7k
Activity
Oct ’21
SKAudioNode .isPositional property on buffered audio
Hi everyone, I am currently trying to use the SKAudioNode .isPositional property in order to have a positional audio feedback for the nodes audio source. While this is easy to accomplish just loading in a file as SKAudioNode source, I am having a hard time doing so when I am buffering the audio via an AVAudioPlayerNode. In general the setup is working to load and play audio, but I am not sure if I correctly setup the EnvironmentNode in order to use the .isPositional property. Any thoughts and help is highly appreciated, here is my code: class GameScene: SKScene { var audioFilePlayer = AVAudioPlayerNode()     var envNode: AVAudioEnvironmentNode!;     var bufferFormat = AVAudioPCMBuffer() override func didMove(to view: SKView) {  let player = SKSpriteNode(imageNamed: "player")         player.position =  CGPoint(x:0,y:0)         scene?.addChild(player)                      guard let filePath = Bundle.main.path(forResource: "bass2", ofType: "m4a") else{ return }         let fileURL = URL(fileURLWithPath: filePath)         var backgroundMusic = SKAudioNode()         player.addChild(backgroundMusic)         do {             let audioFile = try AVAudioFile(forReading: fileURL)             let audioFormat = audioFile.processingFormat             let audioFrameCount = UInt32(audioFile.length)             guard let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount) else { return }             try audioFile.read(into: audioFileBuffer)             // connect the nodes, and use the data to play             let mainMixer = audioEngine.mainMixerNode             backgroundMusic.avAudioNode = audioFilePlayer             envNode = AVAudioEnvironmentNode();             self.audioEngine.attach(envNode);             scene?.audioEngine.attach(backgroundMusic.avAudioNode!)             scene!.audioEngine.connect(backgroundMusic.avAudioNode!, to: envNode, format: audioFileBuffer.format)             scene!.audioEngine.connect(envNode, to: mainMixer, format: audioFileBuffer.format)                      try scene?.audioEngine.start()             audioFilePlayer.play()             audioFilePlayer.scheduleBuffer(audioFileBuffer, completionHandler: nil)                      } catch {             print(error)         }         backgroundMusic.position = CGPoint(x:0,y:0)         label?.addChild(backgroundMusic)     }
Replies
1
Boosts
0
Views
701
Activity
Oct ’21
[Metal Compiler Warning] unknown variable
Hi everyone, Running Xcode 12, I'm developing a standalone WatchOS App using Spritekit. I'm using a simple Palette-swap shader using a SKShader with several SKAttributes. The shader seems to work fine, however I get the following message in the console: [Metal Compiler Warning] Warning: Compilation succeeded with:  program_source:3:19: warning: unused variable 's' constexpr sampler s(coord::normalized, I have no idea what this means, there is no variable 's' in my code so I guess this is an issue because GLGS shader code gets compiled to Metal in the background and it goes wrong there? How do I verify this? It seems there is a memory leak associated with this error so I'm prone to solve it. Any help would be appreciated, even if it's just pointing me in a direction. (Like, should I write a new palette shader in Metal?) Thanks in advance! The function that adds the SKShader (an extension to SKSpriteNode): func addMultiColorShader(strokeColor: UIColor, colors:[UIColor]) {         let useColors:[UIColor] = shaderColors(colors)         var attributes:[SKAttribute] = [SKAttribute(name: "a_size", type: .vectorFloat2),                                         SKAttribute(name: "a_scale", type: .vectorFloat2),                                         SKAttribute(name: "a_alpha", type: .float)]                  let colorNames:[String] = ["a_color0","a_color1","a_color2","a_color3"]         for i in 0..<colorNames.count {             attributes += [SKAttribute(name: colorNames[i], type: .vectorFloat4)]         }         let shader = SKShader(fromFile: "SKHMultiColorize", attributes: attributes)         setShaderAttributes(size: self.size, scale: CGSize(width: self.xScale, height: self.yScale), alpha: self.alpha)         setShaderColors(strokeColor: strokeColor, color1: useColors[0], color2: useColors[1], color3: useColors[2])         self.shader = shader     } The actual shader code (OpenGL GS): vec2 nearestNeighbor(vec2 loc, vec2 size) {     vec2 onePixel = vec2(1.0, 1.0) / size;     vec2 coordinate = floor(loc * size) / size; // round     return coordinate + (onePixel * 0.5); } void main() {     vec4 colors[4];     colors[0] = a_color0;     colors[1] = a_color1;     colors[2] = a_color2;     colors[3] = a_color3;              vec4 currentColor = texture2D(u_texture, nearestNeighbor(v_tex_coord, a_size));     int colorIndex = int((currentColor.r * 5.1));      vec4 refColor = colors[colorIndex];     gl_FragColor = refColor * currentColor.a; }
Replies
4
Boosts
1
Views
2.4k
Activity
Oct ’21
Precompile SKShader
Is there a way to force precompilation of SKShader()s? I am initializing a basic shader in my SKScene properties, but the shader only gets compiled when it is actually attached and rendered to a sprite. class GameScene: SKScene {   let myShader = SKShader(fileNamed: "myEffect.fsh") override func update(_ currentTime: TimeInterval) { if touches.count > 0 { mySprite.shader = myShader // this is where the warning triggers for the first time } } } I know this because the scene pauses for a bit, immediately before the shader is rendered for the first time, and I also get the Metal warning (which seems to also be a known bug in recent releases - https://developer.apple.com/forums/thread/661774): [Metal Compiler Warning] Warning: Compilation succeeded with:  program_source:3:19: warning: unused variable 's' constexpr sampler s(coord::normalized, I was expecting the shader to compile when it is initialized with SKShader(fileNamed:), since Apple docs says: Compiling a shader and the uniform data associated with it can be expensive. Because of this, you should: Initialize shader objects when your game launches, not while the game is running. https://developer.apple.com/documentation/spritekit/skshader
Replies
2
Boosts
0
Views
1.1k
Activity
Oct ’21
I seem to have lost the SpriteKit scene editor. Help!
For some reason, when I select an .sks file in the navigator, the editor for the scene doesn't show up. I do see the scene hierarchy, which usually appears on the left in the editor, but the actual scene, showing the sprites, labels, etc., is entirely missing. Is there some setting that causes .sks files to not be shown that I need to change? I've updated to the newest release, and cleared out the Xcode preferences in ~/Library/Application Support/Xcode, but the problem persists.
Replies
2
Boosts
0
Views
732
Activity
Oct ’21
How can I change the bounce of SKSpriteNode dynamically?
I have a very simple app. All SKSpriteNodes, myBall, myBlue, and myRed. Only myBall moves, affected by gravity, and bounces off of different objects (myRed and myBlue). What I can't figure out is how to make myBall bounce harder or softer depending on which body it hits? I hav been playing with the density of all the objects, but it doesn't seem to make any difference? Is there some property I am unaware of? Or are there other methods?
Replies
0
Boosts
0
Views
404
Activity
Oct ’21
SKFieldNode isExclusive doesn't work
SKFieldNode.isExclusive = true doesn't seem to work. I created a very simple example in the Game Playground, with two intersecting electric fields and a third object placed at the intersection of the fields, with a negative charge. Each field pulls the object towards its center. The first field (left side) has isExclusive=true, the second field (right side) has isExclusive=false. So based on the definition, the exclusive field is suppressing any other field in its region of effect, and since the object is in both regions, it should be pulled towards the field that is exclusive. Instead, the object doesn't move, since both fields are exerting the same forces on it. The object gets pulled by both fields, thus not moving. If one field is disabled using isEnabled = false, the object immediately starts to move towards the field that is enabled. Playground code: import PlaygroundSupport import SpriteKit class GameScene: SKScene {       override func didMove(to view: SKView) {           /*      Configure two intersecting electric fields      */           let field1 = SKFieldNode.electricField()     field1.region = SKRegion(radius: 190)     field1.position = CGPoint(x: -160, y: 0)     field1.isExclusive = true     addChild(field1)           let field2 = SKFieldNode.electricField()     field2.region = SKRegion(radius: 190)     field2.position = CGPoint(x: 160, y: 0)     field2.isExclusive = false     addChild(field2)           /*      Configure some visuals (shapes and labels) for the fields,      since SKView.showsFields doesn't work.      */           let field1Visual = SKShapeNode(circleOfRadius: 190)     field1Visual.strokeColor = .yellow     field1Visual.addChild(SKLabelNode(text: "isExclusive=true"))     field1.addChild(field1Visual)           let field2Visual = SKShapeNode(circleOfRadius: 190)     field2Visual.addChild(SKLabelNode(text: "isExclusive=false"))     field2.addChild(field2Visual)           /*      Configure object placed at the intersection of the two electric fields,      with a negative charge, so each field attracts this object.      */           let object = SKShapeNode(circleOfRadius: 25)     object.strokeColor = .magenta     object.physicsBody = SKPhysicsBody.init(circleOfRadius: 25)     object.physicsBody!.affectedByGravity = false     object.physicsBody!.charge = -0.1 // is attracted     addChild(object)   } } let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480)) let scene = GameScene(size: CGSize(width: 1024, height: 768)) scene.anchorPoint = CGPoint(x: 0.5, y: 0.5) scene.scaleMode = .aspectFill sceneView.presentScene(scene) sceneView.showsFields = true // doesn't work for electricField() and is broken for other fields PlaygroundSupport.PlaygroundPage.current.liveView = sceneView A bug report was also submitted on Feedback assistant, FB9661601.
Replies
0
Boosts
0
Views
701
Activity
Oct ’21
How can I give an SkSpriteNode an initial push?
I have an SkSpriteNode (ball) in a box. Gravity is set to false, otherwise it has an SkPhysicsBody to bounce off of walls. Is there a method to give the ”ball” an initial push in a specified direction and velocity/strength wise?
Replies
1
Boosts
0
Views
455
Activity
Oct ’21