Switching ViewController Scenes - ios

I'm trying to present a ViewController after a button is pressed on an SKScene. How can I make this work?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let node = self.nodes(at: location)
if node[0].name == "newGameButton" {
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
let gameScene = GameScene(size: self.size)
self.view!.presentScene(QuestionViewController, transition: transition)
}
}

Related

GameScene won't display correctly after transition from MainMenuScene in Swift

I'm making a game and at the moment I have a MenuScene and a GameScene. If I play the GameScene on its own, everything is displaying correctly. If I set the MenuScene as default and then press start the GameScene is out of position. As if it has been dragged slightly to the bottom left corner.
My Code for the transition:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "newGameButton" {
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
let gameScene = GameScene(size: self.size)
gameScene.scaleMode = scaleMode
self.view?.presentScene(gameScene, transition: transition)
}
}
}
From searching the issue I see others had the same problem, because they didn't set the scene mode. But I have this "gameScene.scaleMode = scaleMode", I also tried "gameScene.scaleMode = .aspectFill"
My settings for both scenes are the same in the attributes inspector, so not sure what I'm doing wrong. Is it programmable error or settings error. I have added photos. Any help appreciated. Thank you.
I managed to fix it. I changed the Transition code.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if let location = touch?.location(in: self) {
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "newGameButton" {
//let gameScene = GameScene(size: self.size)
let gameScene = GameScene(fileNamed: "GameScene")!
let transition = SKTransition.flipHorizontal(withDuration: 0.5)
gameScene.scaleMode = scaleMode
self.view?.presentScene(gameScene, transition: transition)
}
}
}
Now the scene is displaying correctly. Hopefully won't lead to any other issues.

Touching moving Sprites in SpriteKit

I'm creating a SpriteKit game that involves touching falling targets. Currently, the targets are too difficult to catch on first touch (touchesBegan:), and only seem to be touchable by positioning your finger ahead of time (touchesMoved:). Is there a technique for dampening touches or widening the touch location to make the first touch more effective? My code looks something like this right now:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let positionInScene = touch.location(in: self)
print(positionInScene)
guard let touchedNode = self.nodes(at: positionInScene).first as? SKSpriteNode else { return }
if let dot = touchedNode.name {
if dot == "dot" {
removeTarget(touchedNode)
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let positionInScene = touch.location(in: self)
print(positionInScene)
guard let touchedNode = self.nodes(at: positionInScene).first as? SKSpriteNode else { return }
if let dot = touchedNode.name {
if dot == "dot" {
removeTarget(touchedNode)
}
}
}
Are your entities too small? With the given info, I recreated a small scene in a playground, and all is working as expected. If I have a presented child node, defined as
let circle = SKShapeNode(circleOfRadius: 20)
And I have defined both the physicsWorld of the SKScene, and physicsBody of the SKNode, with the given touchesBegan, there is no problem in detecting a collision.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let location = touches.first?.location(in: self)
if self.atPoint(location) === circle {
print("TOUCH")
}
}
}

Repeat action on a SpriteNode

I would like to repeatedly show one of the two games cards, whenever the user touches the deckOfCards.
I got it working once so far, but when I tap on the deckOfCards again, the card does not change. Trying this with 10 or more card names, didn't work either.
class GameScene: SKScene {
let cardname = ["card2", "ace"]
let randomNumber = Int(arc4random_uniform(13))
var deckOfCards = SKSpriteNode()
var yourCard = SKSpriteNode()
override func didMove(to view: SKView) {
deckOfCards = self.childNode(withName: "deckOfCards") as! SKSpriteNode
yourCard = self.childNode(withName: "yourCard") as! SKSpriteNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view?.endEditing(true)
for touch: AnyObject in touches {
let location = touch.location(in: self)
let node : SKNode = self.atPoint(location)
if node.name == "deckOfCards" {
yourCard.texture = SKTexture(imageNamed: "\(cardname[randomNumber])")
}
}
}
randomNumber is a constant outside of touchesBegan. It never changes. Put it inside touchesBegan.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view?.endEditing(true)
for touch: AnyObject in touches {
let location = touch.location(in: self)
let node = self.atPoint(location)
let randomNumber = Int(arc4random_uniform(13))
if node.name == "deckOfCards" {
yourCard.texture = SKTexture(imageNamed: "\(cardname[randomNumber])")
}
}
}

Detecting a touch with Swift/SKScene

I'm trying to figure out how to detect a touch anywhere on the screen with a subclass of SKScene so that I can transition. How do I do so?
Thanks
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let location = touch.location(in: self)
print(location)
//if your touch location = a button or anything it transitions to a new scene
if location = //Startbutton {
let transition = SKTransition.reveal(with: .down, duration: 0.75)
let gameScene = GameScene(size: size)
gameScene.scaleMode = scaleMode
view?.presentScene(gameScene, transition: transition)
Prints the users touch location... hope that helps a bit m8

Get Property of SKSpriteNode in Touches

I am trying to read a property off of a SKSpriteNode in the touchesBegan method but the property does not exist. Where as it does on the created object elsewhere.
let enemy = enemy(imageName: "enemy.png",force: "12")
addChild(enemy)
enemy.name = "enemy"
print (enemy.force) // 12
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else {
return
}
let touchLocation = touch.location(in: self)
let touchedNode = self.atPoint(touchLocation) as! SKSpriteNode
if(touchedNode.name == "enemy"){
print(enemy.force) //Force property does not exist
}
}
Knowing that SKSpriteNode don't have a force property, you should use your class name that inherits SKSpriteNode properties (used to make enemy..)
An example could be this:
class Enemy : SKSpriteNode {
var force: Int = 0
...
}
Then in your game scene do:
...
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let touchLocation = touch.location(in: self)
let touchedNode = self.atPoint(touchLocation)
if(touchedNode.name == "enemy" && touchNode is Enemy){
// Yes, I'm absolutely sure this is an enemy node..
let enemy = touchedNode as! Enemy
print(enemy.force)
}
}

Resources