I'm new to Xcode and I've been playing around with making a SpriteKit game in Swift.
In every tutorial or Stack overflow topic I've looked at, the touchesBegan function has an override before it, but when I copy that code into GameScene.swift, I get an error, "override can only be specified on class members," with an auto-fix of deleting "override."
So instead of this:override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {...}
it wants me to have this:func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {...}
I'm not sure why this is happening, and I don't know if it will affect how the function works.
My current code in GameScene.swift is:
import SpriteKit
class GameScene: SKScene {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(size: CGSize) {
super.init(size: size)
backgroundColor = SKColor.blackColor()
let stars = Stars()
var starNode:SKNode!
starNode = stars.createStars(CGFloat(30), direction: 1, scaleX: self.frame.width, scaleY: self.frame.height)
addChild(starNode)
func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
//Nothing here yet
}
}
}
Is there something else I am missing?
Thanks!
You must close the second init with a } after addChild(starNode). Your code should read:
import SpriteKit
class GameScene: SKScene {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(size: CGSize) {
super.init(size: size)
backgroundColor = SKColor.blackColor()
// let stars = Stars()
var starNode:SKNode!
starNode = stars.createStars(CGFloat(30), direction: 1,
scaleX: self.frame.width, scaleY: self.frame.height)
addChild(starNode)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
//Nothing here yet
}
}
Related
Hi I am making a game where a node should move to the touch location and I have asked before and it is still not working. Here is my code, hopefully you can help me. I have a file called Player.swift with this code inside it:
import SpriteKit
class Player: SKSpriteNode {
let playerTexture = SKTexture(imageNamed: "head")
init() {
super.init(texture: playerTexture, color: .clear, size: playerTexture.size())
}
// Satisfy the NSCoder required init.
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}}
and then I have the gamescene.swift file with this inside of it:
import SpriteKit
class GameScene: SKScene {
let player = Player()
override func didMove(to view: SKView) {
addChild(player)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
player.position = touch.location(in: self)
}
}
}
Are you sure your touch event is registered? Just put a print("moved") in the touches moves function to be sure.
I have a subclass of SKLabelNode that's instanced three or four times, each with a name, and a destination:
//
import SpriteKit
class MenuButton: SKLabelNode {
var goesTo = SKScene()
override init() {
super.init()
print("test... did this get called? WTF? HOW/WHY/WHERE?")
}
convenience init(text: String, color: SKColor, destination: SKScene){
self.init()
self.text = text
self.color = color
goesTo = destination
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let nextScene = goesTo
// .....?????????????????
// HOW DO I GET THIS TO FIND ITS SCENE...
// THEN ITS VIEW, THEN PRESENT this nextScene????
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I'm at a loss as to how to get at the view I need to call the scene change on.
Every SKNode has a scene property which returns the scene where the node lives.
And every SKScene as a view property, so
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let nextScene = goesTo
self.scene?.view?.presentScene(nextScene)
}
In my GameScene, when I update variables using 'touchesBegan()' it works fine, but when I pass 'pressesBegan()' from the GameViewController to the GameScene, the code gets excited, but the changes get ignored.
GameViewController:
class GameViewController: UIViewController {
...
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
let scene = GameScene(fileNamed: "GameScene")
scene?.pressesBegan(presses, withEvent: event)
}
GameScene:
class GameScene: SKScene {
var test = true
...
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
test = false
print(test)
}
override func update(currentTime: CFTimeInterval) {
print(test)
}
}
This code will result in "false" then "true" in the console.
Every time you call pressesBegan, you are creating a new Gamescene, you need to do
override func pressesBegan(presses: Set<UIPress>, withEvent event: UIPressesEvent?) {
if let skView = self.view as? SKView
{
skView.scene?.pressesBegan(presses, withEvent: event)
}
}
If a "sprite" is created with "SKSpriteNode()", I guess we can override "touchesBegan" function to receive its touch events. However, how can we do that when the Sprite Kit scene editor is used?
Following is the class used as the "custom class":
class Card : SKSpriteNode
{
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// To check it worked:
print("Yup, all working")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("Card : touch event")
}
}
I can not get the touchesBegan function to fire. It isn't being called when a user touched the node.
import SpriteKit
class SimpleButton: SKSpriteNode {
//called when the user taps the button
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
println("touches began")
}
//called when the user finishes touching the button
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
println("touches ended")
}
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
println("touches moved")
}
}
The answer is, You need to enable touches using the userInteractionEnabled parameter.
let imageTexture = SKTexture(imageNamed: "a_button")
let sprite: SimpleButton = SimpleButton(texture: imageTexture)
sprite.userInteractionEnabled = true // <--- This is required, it defaults to false.
sprite.position = CGPoint(x:CGRectGetMidX(self.frame) - 200, y:CGRectGetMidY(self.frame));
sprite.color = UIColor.blackColor()
sprite.colorBlendFactor = 1.0
self.addChild(sprite)