Preprocessor defines are specified in build settings under "Other C flags". You would add something like -DMYSCENE. Huh, there it doesn't work.
I found Other C Flags, selected DEBUG
clicked to ADD CONDITIONAL SETTING
and it didn't work from there.
To be safe I tried it with and without the -D
I even used cut and paste so there would be no typo errors
I know Xcode has been under quite a few changes, am using version 12.1 (in was that makes a difference)
Post
Replies
Boosts
Views
Activity
In Swift, they are compilation conditions, and defined by SWIFTACTIVECOMPILATIONCONDITIONS. Hope you don't mind, but while it works, I still want to make sure I put it where I should.
Project -> Build Settings -> All > (search) "Active Compilation"
select Active Compilation Conditions
click +
select Add Conditional Setting
under Debug there is now this additional line :
Any Architecture | Any SDK ______________ MYSCENE_______________ MYSCENE
Again, does work, but it wouldn't be my first time get the result I want but doing it incorrectly
p.s. I can only add one. I try to add a second one, and it overwrites the first. Can't see how to insert it.
I should add that the barrier I create in my code is using PathDraw and SKPhysicsBody(edgeLoopFrom:). However if replace that with an SKSpriteNode with SKPhysicsBody(rectangleOf:)
So I have a work around. But for better understanding I would like to know is, what is it with Path and edgeLoopFrom that is so different?
userInteractionEnabled set to NO on a parent view will cascade down to all subviews. If you need some subviews to have interaction
enabled, but not others, you can separate your subviews into two parent views: one with userInteractionEnabled = YES and the
other NO. So....it appears that if I do the following for every child :
isUserInteractionEnabled = false
and ONLY set it to true for GameScene (the parent)
That I get the cascade of touches, and can for loop through the nodes. Was that what I was doing wrong? Was it that simple of an error? If so I am both relieved and furious with myself at the same time.
All it does is make sure I get touches for the screen itself, not its childrenTrue. And the method touchesBegan(:with:) defined in GameScene detect touches for the scene, not its children. But that's the thing, I need to get the touches for the children, which I was doing before I decided to clean everything up.
I've zipped the real sloppy version and it's here if you'd like to try:
warptv.com/DropSlot.zip_
Only GameScene has touchesBegan, but it gets all the touches for the balls, which is what I want. Yet, I hav no idea how I lost it.
p.s. better to run it on a n iPhone X simulator...hadn't worked on resizing here.
p.p.s. Please excuse how sloppy all the code is...it was my first attempt
Also for the sample code I uploaded today, I somehow left out the code below (in GVC) and call it right after I create myView
		private func addConstraints(){
				 var constraints = [NSLayoutConstraint]()
				//add
				 constraints.append(myView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor))
				 constraints.append(myView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor))
				 constraints.append(myView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor))
				 constraints.append(myView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor))
				//activate
				 NSLayoutConstraint.activate(constraints)
		 }
>In your didMove(to) of GameScene:
				self.isUserInteractionEnabled = false
Why false? It needs to be true when you want to detect touches. I've gone back on that one many times. All it does is make sure I get touches for the screen itself, not its children
I stil don't understand why you create objects in didMove and not in didLoad (important including for setting delegate): sceneDidLoad comes before didMove, and some of the variables from GVC are not yet filled
Ok, have it down to three files, and am not receiving touchesBegan for the red ball. I'd rather it be something stupid I did and be scolded for that
GVC
import SpriteKit
import SwiftUI
class GameViewController: UIViewController {
		public let myView : SKView = {
				let myView = SKView()
				myView.translatesAutoresizingMaskIntoConstraints = false
				return myView
		}()
		override func viewDidLayoutSubviews() {
				super.viewDidLayoutSubviews()
				if myGlobalVars.safeSceneRect == .zero {
						myGlobalVars.sceneRect = view.frame
						myGlobalVars.sceneRect = myView.frame
				}
				
				if #available(iOS 11.0, *) {
						myGlobalVars.topSafeArea		= view.safeAreaInsets.top
						myGlobalVars.bottomSafeArea = view.safeAreaInsets.bottom
				} else {
						myGlobalVars.topSafeArea		= topLayoutGuide.length
						myGlobalVars.bottomSafeArea = bottomLayoutGuide.length
				}
				
				if myGlobalVars.gameScene == nil {
						let scene = GameScene(size: myView.frame.size )
						scene.anchorPoint = CGPoint(x: 0.0, y: 0.0)
						scene.backgroundColor	 = .clear
						scene.scaleMode				 = .aspectFit
						myGlobalVars.gameScene = scene
						myView.presentScene(scene)
				}
		}
		override func viewWillLayoutSubviews() {
				super.viewWillLayoutSubviews()
		}
		override func viewDidLoad() {
				super.viewDidLoad()
				view.addSubview(myView)
				myView.isHidden						 = false
				myView.ignoresSiblingOrder	= true
				myView.showsFPS						 = true
				myView.showsNodeCount			 = true
				myView.showsPhysics				 = true
		}
	
		override var shouldAutorotate: Bool {
				return false
		}
		override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
				if UIDevice.current.userInterfaceIdiom == .phone {
						return .portraitUpsideDown
				} else {
						return .all
				}
		}
		override var prefersStatusBarHidden: Bool {
				return false
		}
}
GC
import SpriteKit
import SwiftUI
struct GlobalVars{
		var backGround			: SKSpriteNode?
		var sceneRect			 : CGRect
		var safeSceneRect	 : CGRect
		var gameScene			 : GameScene?
		var topSafeArea		 : CGFloat
		var bottomSafeArea	: CGFloat
}
struct ScreenDimensions{
		var widthPix				: CGFloat
		var heightPix			 : CGFloat
		var widthPts				: CGFloat
		var heightPts			 : CGFloat
}
var myGlobalVars = GlobalVars(backGround: nil, sceneRect: .zero, safeSceneRect: .zero, gameScene: nil, topSafeArea: 0.0, bottomSafeArea: 0.0)
class GameScene: SKScene, SKPhysicsContactDelegate{
		override func sceneDidLoad(){
				super.sceneDidLoad()
						print ("GC sceneDidLoad")
		}
		
		override func didMove(to view: SKView){
				super.didMove(to: view)
				physicsWorld.contactDelegate = self
				self.isHidden = true
				myGlobalVars.backGround = SKSpriteNode(imageNamed: "background")
				myGlobalVars.backGround!.zPosition = -1
				myGlobalVars.safeSceneRect = view.frame
				myGlobalVars.gameScene = self
				self.isHidden = false
				self.isUserInteractionEnabled = false
				self.addChild(myGlobalVars.backGround!)
				let myAll = MyGem()
				self.addChild(myAll)
		}
		
		
		override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
				super.touchesBegan(touches, with: event)
				#if DEBUG
						print ("touches began")
				#endif
		}
}
Gem
import Foundation
import SpriteKit
class MyGem : SKSpriteNode{
		init(){
		let skTexture = SKTexture(imageNamed: "gem_red")
				super.init(texture: skTexture, color: .clear, size: CGSize(width: 67, height: 67))
		self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
		self.size = CGSize(width: 67, height: 67)
		self.zPosition = 2
		self.position = CGPoint(x: 0, y: 0 )
		self.position = CGPoint(x: 67/2 + 50,
														 y: 67/2 + 50)
		self.size = CGSize(width: 67, height:	67)
		self.isHidden = false;
		self.isUserInteractionEnabled = true
		}
		
		required init?(coder aDecoder: NSCoder) {
				fatalError("init(coder:) has not been implemented")
		}
}
Then do you get the prints in touchesBegan ? Nope, although if put the touchesBegan in the class I am touching, it gets triggered.
Even though only GameScene has SKPhysicsContactDelegate and physicsWorld.contactDelegate = self
So, why don't you set userInteraction to true ?!? I do, what I meant by reduced code was so it could be posted, so I was due to delete something I shouldn't have. But just in the post.
OK, I did not see "I do" was the answer, looked at it as part of the comment. So, you added a super.touchesBegan in touchesBegan. My turn to say, I didn't catch that. I thought you meant super. in the functions in the class. So now I know to put them in the touches events. Didn't fix it, but thank you for letting me know it needs to be done.
Sorry if my reply seemed snippy. It's just that I got my app to a certain point, while learning Swift, and everything worked. So I stopped at a certain point and decided to clean up the code, add comments, make it clean, etc. etc. And I'm so ****** at myself for not testing after each cleanup that I did, and my backups of the clean code doesn't contain a working version.
So I have no other option but to start the cleanup again. I'm going to start all over, and make sure test every 5 minutes.....argh
What I did just try, was to take my lastest code, the one not working, and I copied over a touchesBegan, with print statements, to redSprite.swift. Lo and behold, it is the one receiving the touches signals.
I've checked a million times...only GameScene has:
SKPhysicsContactDelegate
physicsWorld.contactDelegate = self	
I am making sure I call super.init on the redSprite class
and it is being added as a child to GameScene.
What I broke, I have no clue
Do you call super in each function ? I said I do, if you lookout the post.
Did you try to add the print statements ? While the breakpoints showed me when I would or would not receive touch statements, I took your advice and added print statements (easier)
Why do you create a new child each time you move ? I answered that as well..... the code you're looking at is a reduction of my actual code, so that I could post it. So there will be slight errors such as that. If I didn't reduce the code...I would have to post a bunch of separate files. So I reduced it into just GameScene so the error still existed
When creating your own subclasses, call super to forward any events that you do not handle yourself
I do Do you really want to
> self.addChild(redSprite!)at each move ? This is just a quick reduction in my code to post. Hoping someone could spot something
I guess I'm just going to have to find the last version that worked, and slowly copy over all my mods.
The output you have shown is exactly the same as what I expect from your code. I do not understand what you expected. Just wanted to make sure it was folding out the right way. The last problem you helped me kind of gave me an epiphany: The last time I coded I was using the WindowsSDK. I understood how that flowed. I knew how it flowed when one window would start another.
But am totally new to Swift, and iOS. I was able to find the lifecycle of UIViewContrller, but not for SKScene.
Please ignore this question. It shows why I should never be allowed to program. My code is riddled with errors everywhere; not initializing variables, misunderstanding the error msgs I was receiving, etc. etc. etc.
Above that I have to do all that BEFORE calling
super.init(texture: nil, color: .clear, size: .zero)