Post

Replies

Boosts

Views

Activity

Using Swift, how do I *continuously* test for a GamePad being on/connected?
Using Swift, how do I continuously test for a GamePad being on/connected? When you build a Browser-based Canvas + Javascript Game, you do the above via: function listenForGamepadConnected() {     window.addEventListener("gamepadconnected", (event) => {                // this is the BIGEE that is always testing     }); }   // listenForGamepadConnected And it definitely works! I cannot find its equivalent in the Xcode/Swift world? I do see the following that’s built into a boilerplate Game that you initially create using Xcode - but it seems that it just looks once, versus continuously:     func ObserveForGameControllers() {                          NotificationCenter.default.addObserver(                     self,                     selector: #selector(connectControllers),                     name: NSNotification.Name.GCControllerDidConnect,                     object: nil)                 NotificationCenter.default.addObserver(                     self,                     selector: #selector(disconnectControllers),                     name: NSNotification.Name.GCControllerDidDisconnect,                     object: nil)             }   // ObserveForGameControllers                  @objc func connectControllers() {                 // Unpause the Game if it is currently paused         self.isPaused = false                 // Used to register the Nimbus Controllers to a specific Player Number         var indexNumber = 0         // Run through each controller currently connected to the system         for controller in GCController.controllers() {                         // Check to see whether it is an extended Game Controller (Such as a Nimbus)             if controller.extendedGamepad != nil {                 print("CONNECTED - Extended Gamepad #\(indexNumber)")                                  controller.playerIndex = GCControllerPlayerIndex.init(rawValue: indexNumber)!                                  indexNumber += 1                 setupControllerControls(controller: controller)             }             else {                 print("CONNECTED - but, NOT an Extended Gamepad #\(indexNumber)")             }                     }             }   // connectControllers          @objc func disconnectControllers() {                 print("DIS-CONNECTED")         // Pause the Game if a controller is disconnected ~ This is mandated by Apple         self.isPaused = true             }   // disconnectControllers I try to call it in a Timer loop, but still does not work:     @objc func testForGamepadIsConnected() {         ObserveForGameControllers         var gamepadOn = !self.isPaused   // does not work             }   // testForGamepadIsConnected     func startTestForGamepad() {         guard (gamepadTimer != nil) else {             gamepadTimer = Timer.scheduledTimer(                                     timeInterval: 1.0,                                     target: self,                                     selector:#selector(testForGamepadIsConnected),                                     userInfo: nil,                                     repeats: true)             return         }     }   // startTestForGamepad     func stopTestForGamepad() {         guard (gamepadTimer == nil) else {             gamepadTimer!.invalidate()             // .invalidate() removes Timer() from gamepadTimer, so reinitialize it.             gamepadTimer = Timer()             return         }     }   // stopTestForGamepad Scoured the Google world, but I’ve come up empty. Would appreciate some genius out there providing what I’m missing. Thanks loads.
17
0
2.5k
Apr ’23
100% Inappropriate Behavior of a App Reviewer
Someone somewhere in Apple Development needs to do something. This just cannot be allowed to continue. This has been reported by many others before me .. but nothing changes. What their Reviewers do borders on Assault which is a Crime. How much longer? The very capable folk such as Quinn are tarnished by working along side some of the Reviewers. I truly feel sorry for Quinn. Submitted my Monster Paddle Pong App that operates on Apple TV and iPad with a Game Controller.  SO the Tester uploads my App to their iPad and starts poking their finger all over the screen .. and NOTHING happens.  Maybe their reading skills aren’t ample because that Game Controller requirement is delineated in sentence #1.  Promotional Text: Monster Paddle Pong is FUN! to play on a iPad + Apple TV with a Extended Game Controller. Match wits with your skill to react quickly. See the Description for more info. Description Text: Monster Paddle Pong is FUN! to play on a iPad or Apple TV with a Game Controller. It mischievously matches wits with your skill to react quickly. It's 100% free, so give it a GO!  Pressing the Right Shoulder Button starts the Game and causes the Dinossaur Ball to start moving .. and unless the Ball is moving the Monster Paddle will not move. As a matter of fact, until this Right Shoulder Button is first pressed, only the Left Shoulder Button works (described below). This makes sense because after all what’s so hard in hitting a stationary target? Right? Use your Game Controller’s A, B, X, Y buttons & the Joysticks to move the Monster Paddle and hit the moving Dinossaur Ball. If you’re successful then your Score in the upper right corner advances. If instead your Monster Paddle hits one of the 4 Walls, your score decreases by 1. All this is graphically depicted in the About Scene which can be accessed by pressing your Controller’s Left Shoulder Button once. BTW, press this Left Shoulder a 2nd time, and you will see my Credits Scene. I don’t want to get too detailed here because a big part of FUN! is the thrill of Discovering. So, feel free to DISCOVER, most notably pressing all the buttons on your Controller to see the MAGIC! each of them makes happen.
9
0
1.8k
Feb ’23
Too complex to compile after update to Xcode 14.3.1
Too Complex to Compile? Ventura 13.4.1 New error after update to Xcode 14.3.1 from 14.3.0 // ... <= -(roomHeight/2 - kFudge) too complex to compile ?? if (playerPosY - playerHeight/2) <= (kFudge - roomHeight/2) { // ... this variation works, the previous one doesn't } kFudge and the other parms are declared Double! within AppDelegate. I don't understand what is suddenly wrong after Xcode update.
9
0
1.1k
Jun ’23
How to integrate UIDevice rotation and creating a new UIBezierPath after rotation?
How to integrate UIDevice rotation and creating a new UIBezierPath after rotation? My challenge here is to successfully integrate UIDevice rotation and creating a new UIBezierPath every time the UIDevice is rotated. (Please accept my apologies for this Post’s length .. but I can’t seem to avoid it) As a preamble, I have bounced back and forth between NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: UIDevice.orientationDidChangeNotification, object: nil) called within my viewDidLoad() together with @objc func rotated() { } and override func viewWillLayoutSubviews() { // please see code below } My success was much better when I implemented viewWillLayoutSubviews(), versus rotated() .. so let me provide detailed code just for viewWillLayoutSubviews(). I have concluded that every time I rotate the UIDevice, a new UIBezierPath needs to be generated because positions and sizes of my various SKSprieNodes change. I am definitely not saying that I have to create a new UIBezierPath with every rotation .. just saying I think I have to. Start of Code // declared at the top of my `GameViewController`: var myTrain: SKSpriteNode! var savedTrainPosition: CGPoint? var trackOffset = 60.0 var trackRect: CGRect! var trainPath: UIBezierPath! My UIBezierPath creation and SKAction.follow code is as follows: // called with my setTrackPaths() – see way below func createTrainPath() { // savedTrainPosition initially set within setTrackPaths() // and later reset when stopping + resuming moving myTrain // via stopFollowTrainPath() trackRect = CGRect(x: savedTrainPosition!.x, y: savedTrainPosition!.y, width: tracksWidth, height: tracksHeight) trainPath = UIBezierPath(ovalIn: trackRect) trainPath = trainPath.reversing() // makes myTrain move CW } // createTrainPath func startFollowTrainPath() { let theSpeed = Double(5*thisSpeed) var trainAction = SKAction.follow( trainPath.cgPath, asOffset: false, orientToPath: true, speed: theSpeed) trainAction = SKAction.repeatForever(trainAction) createPivotNodeFor(myTrain) myTrain.run(trainAction, withKey: runTrainKey) } // startFollowTrainPath func stopFollowTrainPath() { guard myTrain == nil else { myTrain.removeAction(forKey: runTrainKey) savedTrainPosition = myTrain.position return } } // stopFollowTrainPath Here is the detailed viewWillLayoutSubviews I promised earlier: override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() if (thisSceneName == "GameScene") { // code to pause moving game pieces setGamePieceParms() // for GamePieces, e.g., trainWidth setTrackPaths() // for trainPath reSizeAndPositionNodes() // code to resume moving game pieces } // if (thisSceneName == "GameScene") } // viewWillLayoutSubviews func setGamePieceParms() { if (thisSceneName == "GameScene") { roomScale = 1.0 let roomRect = UIScreen.main.bounds roomWidth = roomRect.width roomHeight = roomRect.height roomPosX = 0.0 roomPosY = 0.0 tracksScale = 1.0 tracksWidth = roomWidth - 4*trackOffset // inset from screen edge #if os(iOS) if UIDevice.current.orientation.isLandscape { tracksHeight = 0.30*roomHeight } else { tracksHeight = 0.38*roomHeight } #endif // center horizontally tracksPosX = roomPosX // flush with bottom of UIScreen let temp = roomPosY - roomHeight/2 tracksPosY = temp + trackOffset + tracksHeight/2 trainScale = 2.8 trainWidth = 96.0*trainScale // original size = 96 x 110 trainHeight = 110.0*trainScale trainPosX = roomPosX #if os(iOS) if UIDevice.current.orientation.isLandscape { trainPosY = temp + trackOffset + tracksHeight + 0.30*trainHeight } else { trainPosY = temp + trackOffset + tracksHeight + 0.20*trainHeight } #endif } // setGamePieceParms // a work in progress func setTrackPaths() { if (thisSceneName == "GameScene") { if (savedTrainPosition == nil) { savedTrainPosition = CGPoint(x: tracksPosX - tracksWidth/2, y: tracksPosY) } else { savedTrainPosition = CGPoint(x: tracksPosX - tracksWidth/2, y: tracksPosY) } createTrainPath() } // if (thisSceneName == "GameScene") } // setTrackPaths func reSizeAndPositionNodes() { myTracks.size = CGSize(width: tracksWidth, height: tracksHeight) myTracks.position = CGPoint(x: tracksPosX, y: tracksPosY) // more Nodes here .. } End of Code My theory says when I call setTrackPaths() with every UIDevice rotation, createTrainPath() is called. Nothing happens of significance visually as far as the UIBezierPath is concerned .. until I call startFollowTrainPath(). Bottom Line It is then that I see for sure that a new UIBezierPath has not been created as it should have been when I called createTrainPath() when I rotated the UIDevice. The new UIBezierPath is not new, but the old one. If you’ve made it this far through my long code, the question is what do I need to do to make a new UIBezierPath that fits the resized and repositioned SKSpriteNode?
8
0
1.5k
Feb ’24
How to detect the location of a mouseDown event using Swift?
How to detect the location of a mouseDown event using Swift? With the following code snippet, I get the error "Cannot find type 'NSEvent' in scope"? import SpriteKit func mouseDown(with event: NSEvent) { if let ourScene = GameScene(fileNamed: "GameScene") { let location = event.location(in: view) let node:SKNode = ourScene.atPoint(location) if (node.name == "creditsInfo") { showCredits() } } // if let ourScene } // mouseDown Anybody have a floodlight to shine on this very basic error?
5
0
1.3k
Feb ’24
Detecting touching a SKSpriteNode within a touchesBegan event?
Detecting touching a SKSpriteNode within a touchesBegan event? My experience to date has focused on using GamepadControllers with Apps, not a touch-activated iOS App. Here are some short code snippets: Note: the error I am trying to correct is noted in the very first snippet = touchesBegan within the comment <== shows "horse" Yes, there is a "horse", but it is no where near the "creditsInfo" SKSpriteNode within my .sksfile. Please note that this "creditsInfo" SKSpriteNode is programmatically generated by my addCreditsButton(..) and will be placed very near the top-left of my GameScene. override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { if let ourScene = GameScene(fileNamed: "GameScene") { if let touch:UITouch = touches.first { let location = touch.location(in: view) let node:SKNode = ourScene.atPoint(location) print("node.name = \(node.name!)") // <== shows "horse" if (node.name == "creditsInfo") { showCredits() } } } // if let ourScene } // touchesBegan The above touchesBegan function is an extension GameViewController which according to the docs is okay, namely, touchesBegan is a UIView method besides being a UIViewController method. Within my primary showScene() function, I have: if let ourScene = GameScene(fileNamed: "GameScene") { #if os(iOS) addCreditsButton(toScene: ourScene) #endif } with: func addCreditsButton(toScene: SKScene) { if thisSceneName == "GameScene" { itsCreditsNode.name = "creditsInfo" itsCreditsNode.anchorPoint = CGPoint(x: 0.5, y: 0.5) itsCreditsNode.size = CGSize(width: 2*creditsCircleRadius, height: 2*creditsCircleRadius) itsCreditsNode.zPosition = 3 creditsCirclePosY = roomHeight/2 - creditsCircleRadius - creditsCircleOffsetY creditsCirclePosX = -roomWidth/2 + creditsCircleRadius + creditsCircleOffsetX itsCreditsNode.position = CGPoint(x: creditsCirclePosX, y: creditsCirclePosY) toScene.addChild(itsCreditsNode) } // if thisSceneName } // addCreditsButton To finish, I repeat what I stated at the very top: The error I am trying to correct is noted in the very first snippet = touchesBegan within the comment <== shows "horse"
5
0
1.4k
Mar ’24
Moving a SKSpriteNode image in response to a change in its position
Moving a SKSpriteNode image in response to a change in its position is not working. Based on the code below, does anyone have an idea why? N.B. I change the position of the image within my class GameScene. Then, I call, e.g., this function: func drawBall() {             let positionInSceneCoordinates = CGPoint(x: ballPosX, y: ballPosY)             myBall!.removeAction(forKey: "moveTO")     let moveTO = SKAction.move(to: positionInSceneCoordinates, duration: TimeInterval(1))     myBall!.run(moveTO, withKey: "moveTO)") } Selective placement of print statements prove that the ballPosX, ballPosY are changing as they should, but I am observing zero movement on the Xcode Simulator via the call to myBall!run(..). I am at a loss here on how to proceed. Thanks bunches!
4
0
634
Feb ’23
Nimbus+ game controller **not** working with Ventura 13.3 and comparable tvOS
Nimbus+ game controller not working with Ventura 13.3 and comparable tvOS Prior to updating these OS' yesterday, my Computer App in the App Store worked. After updating, not working. I have contacted SteelSeries, the mgr of Nimbus+, and they refuse to admit it's their firmware. And I have definitely started up their SteelSeries CG application and looked for a firmware update -- none. Replacement of hardware is not the solution. Any contrary ideas you folk may have would be extremely helpful.
4
0
1.6k
Apr ’23
Why is Add Emitter to Node not happening immediately?
Why is Add Emitter to Node not happening immediately? Within an extension to GameViewController I have: func addEmitterToNode(_ particleName: String, _ theNode:SKSpriteNode) { if let emitter = SKEmitterNode(fileNamed: particleName) { emitter.name = "emitter" emitter.position = CGPoint(x: 0, y: 0) // = at center theNode.addChild(emitter) } } // addEmitterToNode Here is the func (extension to GameViewController) wherein I call the above. The problem is the explosion sound plays but the smoke particle emitter is not immediately added. func increaseSpeed() { if thisSpeed > maxSpeed { pauseGame() // sets myTrain.isPaused = true playSound(theSoundName: "explosion") addEmitterToNode("smokeParticle.sks", myTrain) trainHasCrashed = true } } // increaseSpeed What I do not understand is that the following within GameScene's sceneDidLoad, the smoke particle emitter is added = override func sceneDidLoad() { if itsGameViewController.trainHasCrashed { itsGameViewController.addEmitterToNode("smokeParticle.sks", myTrain) } }
4
0
753
Jul ’24
How do I correctly show a PDF document?
How do I correctly show a PDF document? iPad and Xcode 15.4 Within my GameViewController, I have: func presentScene(_ theScene: SKScene) { theScene.scaleMode = .resizeFill if let skView = self.view as? SKView { skView.ignoresSiblingOrder = true skView.showsFPS = true skView.showsNodeCount = true #if os(iOS) let theTransition = SKTransition.doorway(withDuration: 2.0) skView.presentScene(theScene, transition: theTransition) #elseif os(tvOS) skView.presentScene(theScene) #endif } } // presentScene I believe presentScene(theScene) goes to the sceneDidLoad() func of theScene which adds various SKSpriteNodes to the scene via a call to addChild(theNode). So far so good ... Until I have a SKScene wherein I wish to display a PDF. I use this snippet to display this PDF with this call within the SKScene's sceneDisLoad(): displayPDF("ABOUT_OLD_WEST_LOCOMOTIVE") func displayPDF(_ itsName:String) { let pdfView = PDFView() guard let path = Bundle.main.path(forResource: itsName, ofType: "pdf") else { return } print("path") guard let pdfDocument = PDFDocument(url: URL(fileURLWithPath: path)) else { return } print("pdfDocument") pdfView.displayMode = .singlePageContinuous pdfView.autoScales = true pdfView.displayDirection = .vertical pdfView.document = pdfDocument } // displayPDF The 2 print statements show, yet the SKScene does not display the PDF via pdfView.document = pdfDocument? Anyone have a clue what errors I have committed? Appreciate it.
4
0
955
Jul ’24
Cannot add a iOS Distribution Certificate to my Project or Target?
Cannot add a iOS Distribution Certificate to my Project or Target? During the Submission for Review process, it states I should choose a Build (for Distribution) and I need to do the above add before I can do that. Here is a screen shot of my Certificates set in my Developer Account: Here is the screen shot when I double-click on the iOS Distribution Certificate above: Here is a screen shot of that Certificate in the Finder: Yet in spite of all the above evidence, here is a screen shot of my Target for both my iOS and tvOS Project: So, please provide some hints because this is the only step left before I finally submit my App to the App store.
3
0
2.4k
Feb ’23