Nodes cannot be pressed after camera moves with nodes - swift

I was able to make my control buttons move with the camera, however after the player moves they no longer work. I thought their location moves with the node, so that in touches began the location would still work when being touched. Should I also update the location after the player has stopped moving? The camera node moves with the player.
override func didMove(to view: SKView) {
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// Make sure you can get teh player from the scene file
if let somePlayer = self.childNode(withName: "player") as? SKSpriteNode {
player = somePlayer
// Set physics
player.physicsBody?.isDynamic = false
} else {
print("No player")
}
let widthHalf:CGFloat = self.view!.bounds.width / 2
let heightHalf:CGFloat = self.view!.bounds.height / 2
cameraNode.addChild(buttonNorth)
buttonNorth.position = CGPoint(x: -widthHalf + 80, y: -heightHalf + 100)
cameraNode.addChild(buttonSouth)
buttonSouth.position = CGPoint(x: -widthHalf + 80, y: -heightHalf + 40)
buttonSouth.yScale = -1
cameraNode.addChild(buttonWest)
buttonWest.position = CGPoint( x: -widthHalf + 30, y: -heightHalf + 70)
cameraNode.addChild(buttonEast)
buttonEast.position = CGPoint( x: -widthHalf + 130, y: -heightHalf + 70)
buttonNorth.xScale = 0.4
buttonNorth.yScale = 0.4
buttonSouth.xScale = 0.4
buttonSouth.yScale = 0.4
buttonSouth.zRotation = CGFloat(Double.pi)
buttonEast.xScale = 0.4
buttonEast.yScale = 0.4
buttonEast.zRotation = CGFloat(Double.pi)
buttonWest.xScale = 0.4
buttonWest.yScale = 0.4
addChild(cameraNode)
camera = cameraNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ) {
let location = touch.location(in: self)
if (buttonNorth.frame.contains(location)) {
currentState = MoveStates.n
buttonNorth.texture = SKTexture(imageNamed: "Directional_Button_Lit")
isPressing = true
} else if (buttonSouth.frame.contains(location)) {
currentState = MoveStates.s
buttonSouth.texture = SKTexture(imageNamed: "Directional_Button_Lit")
isPressing = true
} else if (buttonEast.frame.contains(location)) {
currentState = MoveStates.e
buttonEast.texture = SKTexture(imageNamed: "Directional_Button2_Lit")
isPressing = true
} else if (buttonWest.frame.contains(location)) {
currentState = MoveStates.w
buttonWest.texture = SKTexture(imageNamed: "Directional_Button2_Lit")
isPressing = true
}
}
}

The problem was in my touchesBegan
I had this:
let location = touch.location(in: self)
but since I I had the nodes move with the camera I needed:
let location = touch.location(in: self.camera!)

Related

In swift for spritekit, how would I change the textures of nodes when they are placed?

I’m currently working on a matching game and when the user touches the nodes (Fruit match cards) I want them to display different images when a user clicks the nodes (Fruit match cards).
This is my current code:
import Foundation
import SpriteKit
class EasyScreen: SKScene {
override func didMove(to view: SKView) {
var background = SKSpriteNode(imageNamed: "Easy Screen Background")
let timerText = SKLabelNode(fontNamed: "Arial")
timerText.fontSize = 40
timerText.fontColor = SKColor.white
timerText.position = CGPoint(x: 20, y: 400)
timerText.zPosition = 1
var counter:Int = 120
timerText.run(
SKAction.repeatForever(
SKAction.sequence(
[
SKAction.run {
counter -= 1
timerText.text = " Time: \(counter)"
print("\(counter)")
if counter <= 0 {
let newScene = TryAgainScreen(fileNamed: "Try Again Screen")
newScene?.scaleMode = .aspectFill
self.view?.presentScene(newScene)
}
},
SKAction.wait(forDuration: 1)
]
)
)
)
background.position = CGPoint(x: 0, y: 0)
background.size.width = self.size.width
background.size.height = self.size.height
background.anchorPoint = CGPoint(x: 0.5,y: 0.5)
let matchCardOne = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardTwo = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardThree = SKSpriteNode(imageNamed: "Fruit Match Card")
let matchCardFour = SKSpriteNode(imageNamed: "Fruit Match Card")
matchCardOne.name = "FruitMatchCard1"
matchCardTwo.name = "FruitMatchCard2"
matchCardThree.name = "FruitMatchCard3"
matchCardFour.name = "FruitMatchCard4"
matchCardOne.size = CGSize(width: 150, height: 300)
matchCardTwo.size = CGSize(width: 150, height: 300)
matchCardThree.size = CGSize(width: 150, height: 300)
matchCardFour.size = CGSize(width: 150, height: 300)
matchCardOne.zPosition = 1
matchCardTwo.zPosition = 1
matchCardThree.zPosition = 1
matchCardFour.zPosition = 1
matchCardOne.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardTwo.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardThree.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardFour.anchorPoint = CGPoint(x: 0.5, y: 0.5)
matchCardOne.position = CGPoint(x: -125, y: 60)
matchCardTwo.position = CGPoint(x: -125, y: -260)
matchCardThree.position = CGPoint(x: 70, y: 60)
matchCardFour.position = CGPoint(x: 70 , y: -260)
addChild(background)
addChild(matchCardOne)
addChild(matchCardTwo)
addChild(matchCardThree)
addChild(matchCardFour)
addChild(timerText)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view?.isMultipleTouchEnabled = false
let touch = touches.first
let positionInScene = touch!.location(in: self)
let touchedCardOneNode = self.atPoint(positionInScene)
if let name = touchedCardOneNode.name {
if name == "FruitMatchCard1" {
let newTexture = SKTexture(imageNamed: "Apple")
FruitMatchCard1.init(texture: newTexture)
}
}
let touchTwo = touches.first
let positionInSceneTwo = touch!.location(in: self)
let touchedCardTwoNode = self.atPoint(positionInScene)
if let name = touchedCardTwoNode.name {
if name == "FruitMatchCard2" {
FruitMatchCard2.init(imageNamed: "Banana")
}
}
let touchThree = touches.first
let positionInSceneThree = touch!.location(in: self)
let touchedCardThreeNode = self.atPoint(positionInScene)
if let name = touchedCardThreeNode.name {
if name == "FruitMatchCard3" {
FruitMatchCard3.init(imageNamed: "Apple")
}
}
let touchFour = touches.first
let positionInSceneFour = touch!.location(in: self)
let touchedCardFourNode = self.atPoint(positionInScene)
if let name = touchedCardFourNode.name {
if name == "FruitMatchCard4" {
FruitMatchCard4.init(imageNamed: "Banana")
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
}
I’m trying to change the textures of the nodes in this part of the code. Inside the “if name == “FruitMatchCard” { } “ part of the code. However, when I launch the Xcode simulator the node’s textures aren't changing.
Any advice on how I can do this? Thanks!
Your fundamental problem is that when someone taps a card, you are creating a new card with the new texture and not doing anything with it. Take the following code you have:
FruitMatchCard2.init(imageNamed: "Banana")
This code creates a match card, but you don't do anything with the card.
To change the texture of the card, you must get the sprite node of the tapped card and change its texture. I see in your code you have the following variable:
let touchedCardTwoNode = self.atPoint(positionInScene)
This variable has the card that was touched. Set its texture to the texture you want to use.
touchedCardTwoNode.texture = SKTexture(imageNamed: "Banana")
My SpriteKit is a bit rusty so I can't guarantee that example will compile, but it gives you an idea of what you need to do to change the texture when tapping a card.

SKAction not running when button is held

I am working/practicing with SpriteKit and making a directional pad for controls. It works to move the character, except for the SKAction. I have the actions in the Actions.sks file that based off what button is pressed determines the action that is called. When I press the button the character moves fine, but when I hold it the character glides and the walking animation is stuck on the first frame until I release. What I am trying to do is have the character move if the button is pressed, and continue moving(with walking animation) when the button is held. I am trying to make it look like the gameboy era games.
class GameScene: SKScene {
var player = SKSpriteNode()
var playerSpeed: CGFloat = 0
var previousTimeInterval:TimeInterval = 0
let buttonNorth = SKSpriteNode(imageNamed: "Directional_Button")
let buttonSouth = SKSpriteNode(imageNamed: "Directional_Button")
let buttonEast = SKSpriteNode(imageNamed: "Directional_Button2")
let buttonWest = SKSpriteNode(imageNamed: "Directional_Button2")
var moveAtEndOfRelease:Bool = true
var isPressing = false
var currentState = MoveStates.n
override func didMove(to view: SKView) {
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// Make sure you can get teh player from the scene file
if let somePlayer = self.childNode(withName: "player") as? SKSpriteNode {
player = somePlayer
// Set physics
player.physicsBody?.isDynamic = false
} else {
print("No player")
}
let widthHalf:CGFloat = self.view!.bounds.width / 2
let heightHalf:CGFloat = self.view!.bounds.height / 2
self.addChild(buttonNorth)
buttonNorth.position = CGPoint(x: -widthHalf + 80, y: -heightHalf + 100)
self.addChild(buttonSouth)
buttonSouth.position = CGPoint(x: -widthHalf + 80, y: -heightHalf + 40)
buttonSouth.yScale = -1
self.addChild(buttonWest)
buttonWest.position = CGPoint( x: -widthHalf + 30, y: -heightHalf + 70)
self.addChild(buttonEast)
buttonEast.position = CGPoint( x: -widthHalf + 130, y: -heightHalf + 70)
buttonNorth.xScale = 0.4
buttonNorth.yScale = 0.4
buttonSouth.xScale = 0.4
buttonSouth.yScale = 0.4
buttonSouth.zRotation = CGFloat(Double.pi)
buttonEast.xScale = 0.4
buttonEast.yScale = 0.4
buttonEast.zRotation = CGFloat(Double.pi)
buttonWest.xScale = 0.4
buttonWest.yScale = 0.4
}
override func update(_ currentTime: TimeInterval) {
//player.position = CGPoint(x: player.position.x + playerSpeedx, y: player.position.y + playerSpeedy)
if (isPressing) {
moveOnRelease()
}
}
func move(facing: Facing, x: CGFloat, y: CGFloat) {
let walkAnimation = SKAction(named: "walk\(facing)")!
let moveAction = SKAction.moveBy(x: x, y: y, duration: 1)
let group = SKAction.group([walkAnimation, moveAction])
// Run the actions
player.run(group)
}
func moveSide(facing: Facing, x: CGFloat) {
let walkAnimation = SKAction(named: "walk\(facing)")!
let moveAction = SKAction.moveBy(x: x, y: 0, duration: 1)
let group = SKAction.group([walkAnimation, moveAction])
// Run the actions
player.run(group)
}
func moveUpDown(facing: Facing, y: CGFloat) {
let walkAnimation = SKAction(named: "walk\(facing)")!
let moveAction = SKAction.moveBy(x: 0, y: y, duration: 1)
let group = SKAction.group([walkAnimation, moveAction])
// Run the actions
player.run(group)
}
func moveOnRelease() {
switch (currentState) {
case .n:
moveUpDown(facing: .Back, y: 1)
case .s:
moveUpDown(facing: .Front, y: -1)
case .e:
moveSide(facing: .Right, x: 1)
case .w:
moveSide(facing: .Left, x: -1)
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in (touches ) {
let location = touch.location(in: self)
if (buttonNorth.frame.contains(location)) {
currentState = MoveStates.n
buttonNorth.texture = SKTexture(imageNamed: "Directional_Button_Lit")
isPressing = true
} else if (buttonSouth.frame.contains(location)) {
currentState = MoveStates.s
buttonSouth.texture = SKTexture(imageNamed: "Directional_Button_Lit")
isPressing = true
} else if (buttonEast.frame.contains(location)) {
currentState = MoveStates.e
buttonEast.texture = SKTexture(imageNamed: "Directional_Button2_Lit")
isPressing = true
} else if (buttonWest.frame.contains(location)) {
currentState = MoveStates.w
buttonWest.texture = SKTexture(imageNamed: "Directional_Button2_Lit")
isPressing = true
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if (moveAtEndOfRelease == true) {
buttonNorth.texture = SKTexture(imageNamed: "Directional_Button")
buttonSouth.texture = SKTexture(imageNamed: "Directional_Button")
buttonEast.texture = SKTexture(imageNamed: "Directional_Button2")
buttonWest.texture = SKTexture(imageNamed: "Directional_Button2")
//moveOnRelease()
isPressing = false
}
}
}
The reason it is stuck on the first frame is because the action is being called on every update i believe. You could check to see if the animation is already running, if so do not run it again.
To do this, for each run action give it a name.
So player.run(group) could be
player.run(group, withKey: "moveside"). Then, you can check to see if the action is already running or not like this if (player.action(forKey: "moveside") == nil). Finally, add in code to remove all other actions (like current movement or animations).
Putting it altogether:
if (player.action(forKey: "moveside") == nil) {
player.removeAllActions()
player.run(group, withKey: "moveside")
}

How to force on touch.location to work only in special place on screen?

that is my first question here so - Hello Word.
I have a small problem with my code. I want to force on this program to make balls appear only if you will touch over and equal y: 650 point and boxes to appear only if you will touch under y: 650 point. x position makes here no role.
That is my code:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let location = touch.location(in: self)
let objects = nodes(at: location)
if objects.contains(editLabel) {
editingMode = !editingMode
} else {
if editingMode {
let size = CGSize(width: GKRandomDistribution(lowestValue: 16, highestValue: 128).nextInt(), height: 16)
let box = SKSpriteNode(color: RandomColor(), size: size)
box.zRotation = RandomCGFloat(min: 0, max: 3)
box.position = location
box.physicsBody = SKPhysicsBody(rectangleOf: box.size)
box.physicsBody!.isDynamic = false
addChild(box)
} else {
let ball = SKSpriteNode(imageNamed: "ballRed")
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 2.0)
ball.physicsBody!.contactTestBitMask = ball.physicsBody!.collisionBitMask
ball.physicsBody!.restitution = 0.4
ball.position = location
ball.name = "ball"
addChild(ball)
}
}
}
}
Looking forward for help :)
For me this worked:
ball.position = location
if (location.y < 500) {
ball.position.y = 500
}

How to track two different collisions in SpriteKit Swift

I have seen many methods on the internet, but I'm still very confused on how this is done. Ive legitimately have spent 3 hours yesterday on trying to acomplish this, but anyway the question I have is I have 3 main SKSpriteNodes in my game: man, ground, and arrow. Im trying to make it so that when the man jumps he is only able to jump once until returning back to the ground. My plan is to have it so that when the jump button is pressed a condition is changed and won't be changed back till the man hits the ground again. Im also trying to make it so that when an arrow contacts him it will be a game over and run a line of code. This is the code I have so far
//
// GameScene.swift
// arrow jump
//
// Created by Joy Cafiero on 3/29/16.
// Copyright (c) 2016 3rd Dimension Studios inc. All rights reserved.
//
import SpriteKit
var timer = NSTimer()
var condition = 1
var arrow = SKSpriteNode()
var man = SKSpriteNode()
var bg = SKSpriteNode()
var ground = SKSpriteNode()
var buttonRight = SKSpriteNode()
var buttonLeft = SKSpriteNode()
var buttonJump = SKSpriteNode()
let moveGrounRight = SKAction.moveByX(200, y: 0, duration: 1)
let repeatMoveGroundRight = SKAction.repeatActionForever(moveGrounRight)
let moveGrounLeft = SKAction.moveByX(-200, y: 0, duration: 1)
let repeatMoveGroundLeft = SKAction.repeatActionForever(moveGrounLeft)
let runningMan1 = (SKTexture (imageNamed: "running man1.png"))
let runningMan2 = (SKTexture (imageNamed: "running man2.png"))
let runningMan3 = (SKTexture (imageNamed: "running man3.png"))
let runningMan4 = (SKTexture (imageNamed: "running man4.png"))
let runningMan5 = (SKTexture (imageNamed: "running man5.png"))
let runningMan6 = (SKTexture (imageNamed: "running man6.png"))
let nuetralMan = (SKTexture (imageNamed: "running man nuetral.png"))
let jumpingMan1 = (SKTexture (imageNamed: "jumping man1"))
let jumpingMan2 = (SKTexture (imageNamed: "jumping man2"))
let jumpingMan3 = (SKTexture (imageNamed: "jumping man3"))
let animation = SKAction.animateWithTextures([ runningMan1, runningMan2, runningMan3, runningMan4, runningMan5, runningMan6], timePerFrame: 0.15)
let jumpingAnimation = SKAction.animateWithTextures([jumpingMan1, jumpingMan2, jumpingMan3], timePerFrame: 0.1)
let nuetralAnimation = SKAction.animateWithTextures([nuetralMan], timePerFrame: 0.05)
let repeatAnimation = SKAction.repeatActionForever(animation)
let manGroup:UInt32 = 1
let groundGroup:UInt32 = 2
let arrowGroup:UInt32 = 0x1 << 3
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.physicsWorld.gravity = CGVectorMake(0, -5)
man = SKSpriteNode(texture: nuetralMan)
man.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
man.size = CGSize(width: man.size.width * 2, height: man.size.height * 2)
man.zPosition = 15
man.physicsBody = SKPhysicsBody(rectangleOfSize: man.size)
man.physicsBody?.dynamic = true
man.physicsBody?.allowsRotation = false
man.physicsBody?.categoryBitMask = manGroup
man.physicsBody?.contactTestBitMask = groundGroup
self.addChild(man)
let bgTexture = (SKTexture(imageNamed: "wild west landscape.png"))
bg = SKSpriteNode(texture: bgTexture)
bg.size = CGSize(width: self.frame.width, height: self.frame.height)
bg.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) + 100)
bg.zPosition = -1
self.addChild(bg)
let groundtexture = (SKTexture(imageNamed: "sandy ground.png"))
ground = SKSpriteNode(texture: groundtexture)
ground.size = CGSize(width: CGRectGetMaxX(self.frame), height: ground.size.height)
ground.position = CGPointMake(CGRectGetMidX(self.frame), 0)
ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.width, ground.size.height-255))
ground.physicsBody?.dynamic = false
ground.zPosition = 20
ground.physicsBody?.categoryBitMask = groundGroup
ground.physicsBody?.contactTestBitMask = manGroup
self.addChild(ground)
timer = NSTimer.scheduledTimerWithTimeInterval(7, target: self, selector: Selector("timerUpdate"), userInfo: nil, repeats: true)
buttonRight.color = SKColor.redColor()
buttonRight.position = CGPointMake(200, 200)
buttonRight.size = CGSize(width: 100, height: 100)
buttonRight.zPosition = 25
self.addChild(buttonRight)
buttonLeft.color = SKColor.redColor()
buttonLeft.position = CGPointMake(100, 200)
buttonLeft.size = CGSize(width: 100, height: 100)
buttonLeft.zPosition = 25
self.addChild(buttonLeft)
buttonJump.color = SKColor.greenColor()
buttonJump.position = CGPointMake(CGRectGetMaxX(self.frame) - 200, 200)
buttonJump.size = CGSize(width: 100, height: 100)
buttonJump.zPosition = 25
self.addChild(buttonJump)
}
func timerUpdate() {
let random = Int(arc4random_uniform(3))
var timeIncrease:NSTimeInterval = 0
var randomArrow = [self.frame.height / 20 + CGRectGetMidY(self.frame) - 65, self.frame.height / 20 + self.frame.height / 20 + CGRectGetMidY(self.frame) - 65, self.frame.height / 20 + self.frame.height / 20 + self.frame.height / 20 + CGRectGetMidY(self.frame) - 65, self.frame.height / 20 + self.frame.height / 20 + self.frame.height / 20 + CGRectGetMidY(self.frame) - 65]
timeIncrease = timeIncrease + 7
let arrowTexture = (SKTexture(imageNamed: "arrow.png"))
let movingArrow = SKAction.moveByX(-self.frame.size.width, y: 0, duration: NSTimeInterval(self.frame.size.width/100)-5+timeIncrease)
let removeArrows = SKAction.removeFromParent()
let repeatmoveArrows = SKAction.sequence([movingArrow, removeArrows])
arrow = SKSpriteNode(texture: arrowTexture)
arrow.size = CGSize(width: arrow.size.width, height: arrow.size.height)
arrow.position = CGPointMake(CGRectGetMaxX(self.frame), randomArrow[random])
arrow.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(arrowTexture.size().width - 100, arrow.size.height / 2))
arrow.physicsBody?.dynamic = false
arrow.zPosition = 10
arrow.physicsBody?.categoryBitMask = arrowGroup
arrow.physicsBody?.contactTestBitMask = manGroup
arrow.runAction(repeatmoveArrows)
arrow.physicsBody?.categoryBitMask = arrowGroup
arrow.physicsBody?.contactTestBitMask = manGroup
self.addChild(arrow)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if buttonRight.containsPoint(location) {
man.xScale = 1
man.runAction(repeatMoveGroundRight, withKey: "MoveRight")
man.runAction(repeatAnimation, withKey: "Run")
}
if buttonLeft.containsPoint(location) {
man.xScale = -1
man.runAction(repeatMoveGroundLeft, withKey: "MoveLeft")
man.runAction(repeatAnimation, withKey: "Run")
}
if buttonJump.containsPoint(location) {
if(condition == 1) {
man.physicsBody?.velocity = CGVectorMake(0, 0)
man.physicsBody?.applyImpulse(CGVectorMake(0, 400))
man.runAction(jumpingAnimation)
}
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if buttonRight.containsPoint(location) {
man.removeActionForKey("MoveRight")
man.removeActionForKey("Run")
man.texture = nuetralMan
}
if buttonLeft.containsPoint(location) {
man.removeActionForKey("MoveLeft")
man.removeActionForKey("Run")
man.texture = nuetralMan
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if buttonRight.containsPoint(location) {
man.removeActionForKey("MoveRight")
man.removeActionForKey("Run")
man.texture = nuetralMan
}
if buttonLeft.containsPoint(location) {
man.removeActionForKey("MoveLeft")
man.removeActionForKey("Run")
man.texture = nuetralMan
}
}
func didBeginContact(contact: SKPhysicsContact) {
condition = 1
man.texture = nuetralMan
print("contact")
}
func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
}

Stopping the countUp speed rate

I just started to learn Swift and Sprite Kit. I need assistance with the following code.
I have a countUp that when the ball is touched the countUp starts but my problem is that every time I tap the ball the rate of speed in the countUp increases. I want the CountUp to be stable. Any help will be appreciated.
class Game: SKScene {
var Ball = SKSpriteNode(imageNamed: "Red.png")
var QuitOption = SKLabelNode()
var ScoreLabel = SKLabelNode()
var timescore = Int()
var timesecond = Int()
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.blackColor() // background for the display
self.physicsWorld.gravity = CGVectorMake(0, -9.8)
let SceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
SceneBody.friction = 0
self.physicsBody = SceneBody
Ball.size = CGSize(width: 120, height: 120)
Ball.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.7)
Ball.physicsBody = SKPhysicsBody(circleOfRadius: 60)
Ball.physicsBody?.affectedByGravity = true
Ball.physicsBody?.restitution = 0.5
Ball.physicsBody?.linearDamping = 0
Ball.name = "Ball"
self.addChild(Ball)
QuitOption.text = "Quit"
QuitOption.fontName = "Noteworthy-Light"
QuitOption.fontColor = SKColor.greenColor()
QuitOption.fontSize = 35
QuitOption.position = CGPoint(x: self.frame.size.width/2 - 160, y: self.frame.size.height*1 - 110)
QuitOption.name = "Quit"
addChild(QuitOption)
ScoreLabel = SKLabelNode(fontNamed: "Noteworthy-Light")
ScoreLabel.fontSize = 50 // The + will move it to the right side and - to the left side for more accuracy.
ScoreLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/4 + 400) // position of ScoreLabelNode
ScoreLabel.name = "Score+"
ScoreLabel.hidden = false
self.addChild(ScoreLabel)
}
// Making the ball jump after user touches ball
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
var touch = touches.first as! UITouch
var location = touch.locationInNode(self)
var node = self.nodeAtPoint(location)
if (node.name == "Quit"){
let myScene = GameScene(size: self.size)
myScene.scaleMode = scaleMode
let reveal = SKTransition.fadeWithDuration(1)
self.view?.presentScene(myScene, transition: reveal)
}
if (node.name == "Ball"){
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
Ball.physicsBody?.allowsRotation = true
Ball.physicsBody?.velocity = CGVectorMake(0, 0)
Ball.physicsBody?.applyImpulse(CGVectorMake(0, 100))
}
}
var actionwait = SKAction.waitForDuration(0.5)
var actionrun = SKAction.runBlock({
self.timescore++
self.timesecond++
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = " \(self.timescore/60):\(self.timesecond)"})
ScoreLabel.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun])))
}
}
I guess that's happening because you are running same block over and over again after every touch. To ensure you run block only once, you can use some Bool indicator and after the first run, set its value appropriately, like this:
if(!self.locked){
self.locked = true // at start, this value should be false
var actionrun = SKAction.runBlock({
self.timescore++
self.timesecond++
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = " \(self.timescore/60):\(self.timesecond)"})
ScoreLabel.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun])))
}
}
Something as an addition to this topic and for future readers could be found here.