I created a game involving falling balls. Every time the player taps a ball, they're supposed to get a point. I set up the score label, but it just stays at 0.
Is there something wrong with my code?
I use a GameElements.swift file as an extension. Here is the file:
extension GameScene {
//1st Ball//
func createPlayer() -> SKNode {
let playerNode = SKNode()
playerNode.position = CGPoint(x:self.size.width / 2, y:440)
let sprite = SKSpriteNode(imageNamed: "Ball")
sprite.name = "ballPoints"
playerNode.addChild(sprite)
playerNode.physicsBody = SKPhysicsBody(circleOfRadius: 120)
playerNode.physicsBody?.dynamic = true
playerNode.physicsBody?.allowsRotation = false
playerNode.physicsBody?.restitution = 3
playerNode.physicsBody?.friction = 0
playerNode.physicsBody?.angularDamping = 0
playerNode.physicsBody?.linearDamping = 0
playerNode.physicsBody?.usesPreciseCollisionDetection = true
playerNode.physicsBody?.categoryBitMask = CollisionBitMask.Player
playerNode.physicsBody?.categoryBitMask = 0
return playerNode
}
}
Here is the GameScene.swift file:
class GameScene: SKScene {
var foreground: SKNode!
var hud: SKNode!
var firstBall: SKNode!
var scoreLabel: SKLabelNode!
private var score = 0
override func didMoveToView(view: SKView) {
scoreLabel = SKLabelNode(fontNamed:"Geared-Slab")
scoreLabel.fontColor = UIColor.blackColor()
scoreLabel.position = CGPoint( x: self.frame.midX, y: 3 * self.frame.size.height / 4 )
scoreLabel.fontSize = 100.0
scoreLabel.zPosition = 100
scoreLabel.text = String(score)
self.addChild(scoreLabel)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if(firstBall.containsPoint(location)) {
firstBall.physicsBody?.velocity = CGVectorMake(0, 600)
firstBall.physicsBody?.applyImpulse(CGVectorMake(0, 1100))
}
if
let touch : UITouch! = touches.first,
let tappedSprite = nodeAtPoint(touch!.locationInNode(self)) as? SKSpriteNode,
let scoreLabel = childNodeWithName("scoreLabel") as? SKLabelNode
where tappedSprite.name == "ballPoints" {
score += 1
scoreLabel.text = "Score: \(score)"
}
}
}
override init(size:CGSize) {
super.init(size: size)
foreground = SKNode()
addChild(foreground)
//1st Ball//
firstBall = createPlayer()
foreground.addChild(firstBall)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I know this is a lot of code, but I want experts to be able to test the code themselves. For background, I was following this tutorial: https://www.youtube.com/watch?v=0gOi_2Jwt28 up until a certain point.
First of all let's create a class for the Ball
class Ball: SKSpriteNode {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let scene = self.scene as! GameScene
scene.score += 1
}
}
Then inside createPlayer()
let's replace this
let sprite = SKSpriteNode(imageNamed: "Ball")
with this
let sprite = Ball(imageNamed: "Ball")
sprite.userInteractionEnabled = true
Let's remove the touchesBegan
from GameScene
.
This code is working as expected for me
class GameScene: SKScene {
var scoreLabel: SKLabelNode!
var ball: Ball!
private var score = 0 {
didSet {
scoreLabel.text = "\(score)"
print(score)
}
}
override func didMoveToView(view: SKView) {
let ball = Ball()
ball.position = CGPoint(x:frame.midX, y: frame.midY)
addChild(ball)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// this is called when you tap outside of the Ball
// use self.ball to make the ball to jump
}
}
class Ball: SKSpriteNode {
init() {
let texture = SKTexture(imageNamed: "ball")
super.init(texture: texture, color: .clearColor(), size: texture.size())
userInteractionEnabled = true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let scene = self.scene as! GameScene
scene.score += 1
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}