I know it's uncool to ask vague questions here, but what do they call it when you create a world and follow it with a camera in Swift? Like an RPG? Like Doom?
I want to try and learn that now. And more importantly can it be done without using the Xcode scene builder? Can it be done all via code?
Thanks, as always. Without the forum I would never have gotten much farther than "Hello World!"
Post
Replies
Boosts
Views
Activity
In my app, I have greyBars and one border bar. The border bar keeps the greyBars from falling off the screen.
Only one greyBar is used at a time. When it is completely filed with colored gems, a new bar is created and brought up from the bottom of the screen, with the code below.
The result I want is that the new bar, the one with all white diamonds pushes up the old bar and the new bar remains on the bottom. You can see by the screenshot that somehow the new bar ended up on top, even though it was coming from the bottom.
I slowed down the duration of the greyBar's movement to see what was going wrong.
While the two greyBars do clash with each other, the new one (the one on the bottom) ends up pushing THROUGH the top bar.
My assumption was that the new greyBar would just push up the old bar(s), and remain on the bottom.
Is there some "solidity" type property that I am missing?
myGreyBar[0].physicsBody?.categoryBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].physicsBody?.contactTestBitMask = bodyMasks.blankMask.rawValue
myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.greyBarMask.rawValue
myGreyBar[0].isHidden = false;
myGV.gameScene?.addChild(myGreyBar[0])
let moveAction = SKAction.move(to: CGPoint(x:(myGV.safeSceneRect.width/2) - (size.width/2), y: (myGemBase?.size.height)! + (myGV.border?.size.height)! + 200), duration: 10.0)
myGreyBar[0].run(moveAction, completion:{myGreyBar[0].physicsBody?.collisionBitMask = bodyMasks.borderMask.rawValue|bodyMasks.greyBarMask.rawValue})
I have an SKSpriteNode with an SKAction being run on it:
theGem!.run(premAction, completion: {theGem!.run(repeatAction)})
Can't seem to find out the proper steps to run another action, such as:
theGem.run(endsequence, completion: {theGem.removeAllActions(); theGem.run(stopAction)})
Should I stop the previous action first?
Is there a way to turn the repeat part off so that the first SKAction ends smoothly?
I handled everything through touchesEnded. Was curious if I could hand off the call to touchesEnded from touchesCancelled?
It's a small thing, but every time I open my current Xcode project the default iOS device to run my app on is my phone. Is there a way to change it to one of the simulators? i.e. iPhone Pro 11?
Just curious why I get touchesCanceled even after I process:
@objc func tappedView(_ sender:UITapGestureRecognizer)
It's requiring a lot of extra coding to determine a real cancel vs I just got a tap.
I was looking to find a way to find out if my SKSpriteNode with an SKPhysicsBody is in motion.
I create a box, raise it above the bar, then set the bar and box masks to collide. The bar is pinned, but would love to know when the box stops bouncing.
I am using debug labels so I know when I get any touchesBegan, touchesMoving, touchesEnded, and touchesCanceled.
I get everything I expect, touchesBegan, touchesMoved, and touchesEnded. However, it would appear that if I barely, just barely move an SKSPriteNode, I get a touchesCanceled instead of touchesEnded. Even thought the call right before is touchesMoved.
Is this as intended? Is there some threshold you have to reach to get an ended instead of a canceled? And if so, can I see and change it?
Thanks
More than glad to put my code, tho not sure how that would change anything.
While debugging I would like to get a specific subclass's property. So far I can do this:
if let myPeg = getTargetSlot(node: node, location touchLocation){
print (myPeg.index)
}
Is it possible to write it in one line? Something like this?
print ("\(getTargetSlot(node: node, location touchLocation).index")
Because if there is a way, I cannot figure out the syntax.
Thanks
I know this is a silly question, but I just want to be safe.
I have multiple subclasses of SKSpriteNode in my app. In touchesBegan I am looking for a specific type, MyPeg. I just want to make sure that the code below fails if the node is not a MyPeg. I have this fear that if another of my subclasses is the same size, or too similar, or even has the same variables that I might get a positive.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
super.touchesBegan(touches , with:event)
guard let touch = touches.first else { return }
let location = touch.location(in: self)
let touchedNodes = self.nodes(at: location)
for theNode in touchedNodes{
if let node = theNode as? MyPeg{
In my app I create mutiple SKSpriteNodes, gems. Code snippet 1
When I loop through nodes from the main scene in a tap gesture, Code snippet 2, the gems register in a perfect square shape even though they are not. I have highlighted all areas that the orange gem registers in a tap as white. Here is the screen shot http://98.7.37.117/gem.png
Since the gem is itself not a square, I'd like to know if there is a way refine its shape so it would only show up in the list of nodes in UITapGestureRecognizer if the orange part is tapped. I have even tried by assigning it a physicsBody. But that made no difference.
Code Snippet 1
class MyGem : SKSpriteNode{
init(iColor : Gems) {
fileName = "\(iColor)_gem"
let skTexture = SKTexture(imageNamed: fileName)
super.init(texture: skTexture, color: .clear, size: .zero)
self.isHidden = true
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
self.size = CGSize(width: myGV.gemSize.width, height: myGV.gemSize.height)
self.zPosition = theZ.gem
self.position = CGPoint(x: 0, y: 0 )
self.isUserInteractionEnabled = false
self.name = "gem"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Code Snippet 2
@objc func tappedView(_ sender:UITapGestureRecognizer) {
if sender.state == .ended{
var post = sender.location(in: sender.view)
post = self.convertPoint(fromView: post)
for node in self.nodes(at: post){
if let touchNode = node as? MyGem
print("touched gem")
highliteGem(theGem: touchNode, clearAll: false)
return
}
I have the code below which works just fine. getTwinklingGem returns type MyGem.
What I cannot figure out is if there is a proper syntax for writing the NOT into the if statement. Am still too new to Swift.
This works, but seems lengthy:
if let twinkling = getHighGem(), twinkling != nil
Is this the proper way to test for a nil return?
if let twinkling = getHighGem() as? MyGem
if let twinkling = getTwinklingGem() {
print ("not nil")
}
I have a subclass of SKSpriteNode called MyGem. There are multiple instances of this class at runtime. They are all in an array of MyGems. At a specific point I would like to find out which MyGem is twinkling.
The problem I am running into is if no MyGem is twinkling. What do I return? I can't return a nil.
'nil' is incompatible with return type 'MyGem'
So what do I return?
I thought of returning the index number of the MyGem in the array class, and then passing -1 if none were twinkling. But that seems kludgy.
func getHighGem() -> MyGem {
for gem in myGems {
if gem.twinkling == true {
return gem
}
}
return nil //this line causes the IDE error
}
As you can see in the last two lines of the code below, I specify a specific SKSpriteNode to get the correct (or is it, adjusted?) touch coordinates. The last line is just left in there to compare while I am debugging.
I was curious if there was already a method in Swift that translates any coordinates handed to it into physical screen coordinates?
It would just be easier than having to first find out: Is this item that I am tracking, owned by the main GameScene, or a SKSpriteNode that has been placed somewhere other than 0,0 on the GameScene?
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches , with:event)
var delta = CGPoint(x: 0, y: 0)
guard touches.first != nil else { return }
if let touch = touches.first,
let node = myGV.currentGem,
node.isMoving == true {
let touchLocation = touch.location(in: myGV.guessBar!)
let touchLocation2 = touch.location(in: self)
myGV is a structure where I store a handful of global variables.
The following are all sub-classes of SKSpriteNode: I have a class called guessingBar which holds 6 guessSlots. The former class has an array of the guessSlots for me to loop through.
I just don't know the syntax of how to access the array.
myGV holds multiple variables, so the SKSpriteNode guessBar can be found at:
myGV.guessBar
I expected to be able to read the array with:
myGV.guessBar.guessSlots[x] but as you can see from the debugger screenshot, I cannot.
In the screenshot you can see that everything is initialized. Am I missing some silly typo, or is the syntax escaping me?
http: //98.7.37.117/s.png