SpriteKit present scene new scene appears in wrong place - sprite-kit

I am trying to build game in spriteKit and I want it to start with a menu and when the user touches the play button the game scene should be presented, which happens, but the gameScene appears in the wrong place, see attached image. When I start the game directly on the gameScene it appears in the correct place.
The code that is commented is code I have tested, but with the same result.
class StartScene: SKScene {
var myScreenSize: Int = 0
let screenSize: CGRect = UIScreen.main.bounds
var currentScreenSize = 0
let playButton = SKSpriteNode(imageNamed: "dogbone")
let myLabel = SKLabelNode(fontNamed: "Baskerville-Bold")
override func didMove(to view: SKView) {
if screenSize.width == 812 && screenSize.height == 375 {
currentScreenSize = 1
} else if screenSize.width == 736 && screenSize.height == 414 {
currentScreenSize = 2
} else if screenSize.width == 667 && screenSize.height == 375 {
currentScreenSize = 3
} else if screenSize.width == 736 && screenSize.height == 414 {
currentScreenSize = 4
} else if screenSize.width == 568 && screenSize.height == 320 {
currentScreenSize = 5
} else if screenSize.width == 1366 && screenSize.height == 1024 {
currentScreenSize = 6
} else if screenSize.width == 834 && screenSize.height == 1112 {
currentScreenSize = 7
} else if screenSize.width == 1024 && screenSize.height == 768 {
currentScreenSize = 8
}
print("screen current \(currentScreenSize)")
print("screen \(myScreenSize)")
myLabel.fontColor = UIColor.black
myLabel.position.y = 230
myLabel.text = "HEJSAN"
addChild(myLabel)
//addChild(gameTitle)
//playButton.position.y = 230
playButton.position = CGPoint(x: frame.midX, y: frame.midY)
addChild(playButton)
}
/// Touches began
override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let pos = touch.location(in: self)
let node = self.atPoint(pos)
if node == playButton {
if let viewCurrent = view {
let transition: SKTransition = SKTransition.fade(withDuration: 1)
//let scene: SKScene = GameScene(size: self.size)
let scene = GameScene(size: CGSize(width: screenSize.width, height: screenSize.height))
// scene.scaleMode = .resizeFill
// scene.scaleMode = .aspectFill
// scene.scaleMode = .aspectFit
// scene.scaleMode = .fill
viewCurrent.presentScene(scene)
// scene.scaleMode = .aspectFill
// let skView = viewCurrent as! SKView
// skView.ignoresSiblingOrder = true
// skView.presentScene(scene)
// let skview = self.view?.scene?.view
// skview?.presentScene(scene)
//viewCurrent.presentScene(scene)
//self.view?.presentScene(scene, transition: transition)
//self.view?.presentScene(scene)
}
}
}
}
}
Image shows where the scene appears, in the lower left corner instead of full screen

Related

How to make shape not to go to GameOver? -SpriteKit

I am creating a game where there is a square shape and every time the player taps on the square, it goes to GameOver scene. All I want to do is when the square shape is tapped, it will be allotted different position of the screen to be tapped on the squares.
Here is my code:
let touch:UITouch = touches.first!
let positionInScene = touch.location(in: self)
let touchedNode = self.atPoint(positionInScene)
if let name = touchedNode.name
{
//The first ball that shows up
if name == "startball"
{
print("Touched", terminator: "")
addBall(ballSize)
self.addChild(score)
}
else if name == "shape"{
scoreCount += 1
addBall(ballSize)
audioPlayer.play()
}
}
else {
let scene = GameOver(size: self.size)
scene.setMyScore(0)
let skView = self.view! as SKView
skView.ignoresSiblingOrder = true
scene.scaleMode = .resizeFill
scene.size = skView.bounds.size
scene.setMessage("You Lost!")
scene.setEndGameMode(va)
gameTimer.invalidate()
shownTimer.invalidate()
print(" timers invalidated ", terminator: "")
ran = true
skView.presentScene(scene, transition: SKTransition.crossFade(withDuration: 0.25))
}
if firstTouch {
shownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GameScene.decTimer), userInfo: nil, repeats: true)
gameTimer = Timer.scheduledTimer(timeInterval: TIME_INCREMENT, target:self, selector: Selector("endGame"), userInfo: nil, repeats: false)
firstTouch = false
}
if touchCount > 5 {
for touch: AnyObject in touches {
let skView = self.view! as SKView
skView.ignoresSiblingOrder = true
var scene: Congratz!
scene = Congratz(size: skView.bounds.size)
scene.scaleMode = .aspectFill
skView.presentScene(scene, transition: SKTransition.doorsOpenHorizontal(withDuration: 1.0))
}
}
touchCount += 1
}
override func update(_ currentTime: TimeInterval) {
super.update(currentTime)
}
func endGame(){
shownTimer.invalidate()
gameTimer.invalidate()
let scene = GameOver(size: self.size)
scene.setMyScore(scoreCount)
if let skView = self.view {
skView.ignoresSiblingOrder = false
scene.scaleMode = .resizeFill
scene.size = skView.bounds.size
scene.setMessage("Times up")
skView.presentScene(scene, transition: SKTransition.crossFade(withDuration: 0.25))
}
}
override func addBall(_ size: Int) {
// Add the ball
let currentBall = SKShapeNode(circleOfRadius: CGFloat(size))
let viewMidX = view!.bounds.midX
let viewMidY = view!.bounds.midY
currentBall.fillColor = pickColor()
currentBall.position = randomBallPosition()
if scoreCount != 0{
if scoreCount == 1{
self.addChild(score)
self.addChild(timeLeftLabel)
self.childNode(withName: "welcome")?.removeFromParent()
}
self.childNode(withName: "ball")?.run(getSmaller)
self.childNode(withName: "ball")?.removeFromParent()
}
currentBall.name = "ball"
self.addChild(currentBall)
}
func addSquare(_ size: Int) {
// Add the square
let shape = SKShapeNode(rectOf: CGSize(width:CGFloat(size), height:CGFloat(size)))
shape.path = UIBezierPath(roundedRect: CGRect(x: 64, y: 64, width: 160, height: 160), cornerRadius: 50).cgPath
shape.fillColor = pickColor()
shape.position = randomBallPosition()
shape.name = "shape"
self.addChild(shape)
}
func randomBallPosition() -> CGPoint {
let xPosition = CGFloat(arc4random_uniform(UInt32((view?.bounds.maxX)! + 1)))
let yPosition = CGFloat(arc4random_uniform(UInt32((view?.bounds.maxY)! + 1)))
return CGPoint(x: xPosition, y: yPosition)
}
What I would suggest would be to make something like an enum for the different shapes, so you can keep track of what shape you're using.
enum GameShape: Int {
case circle = 0
case square = 1
}
Then create a GameShape property at the top of your GameScene:
var currentShape: GameShape = .circle
Then you could create some sort of updateShape method, which you could call in your touchesBegan method instead of just addBall
func updateShape(shapeSize: CGSize) {
switch currentShape {
case .circle:
addCircle(shapeSize)
case .square:
addSquare(shapeSize)
default:
break
}
// However you want to setup the condition for changing shape
if (condition) {
currentShape = .square
}
}
func addBall(_ size: CGSize) {
// Add the ball
}
func addSquare(_ size: CGSize) {
// Add the square
}
Now in your touchesBegan method, instead of calling addBall(size, you could call updateShape:
override func touchesBegan(_ touches: Set<UITouch>!, with event: UIEvent?) {
// Setup your code for detecting position for shape origin
updateShape(shapeSize)
}
EDIT - Your code is a mess. You really should take the time to make sure it's properly formatted when you submit it, otherwise it's really hard to help you. Indentation helps to see where a closure begins and ends. From what I can tell, it looks like you have two or more functions nested within your addBall method. This is not good. I tried my best to clean it up for you. You'll still need to write the code to make the shape a square, but I've lead you in the right direction to start to make that happen:
func addBall(_ size: CGSize) {
// Add the ball
let currentBall = SKShapeNode(circleOfRadius: CGFloat(size))
let viewMidX = view!.bounds.midX
let viewMidY = view!.bounds.midY
currentBall.fillColor = pickColor()
shape.path = UIBezierPath(roundedRect: CGRect(x: 64, y: 64, width: 160, height: 160), cornerRadius: 50).cgPath
shape.fillColor = pickColor()
currentBall.position = randomBallPosition()
shape.position = randomBallPosition()
self.addChild(shape)
if scoreCount != 0{
if scoreCount == 1{
self.addChild(score)
self.addChild(timeLeftLabel)
self.childNode(withName: "welcome")?.removeFromParent()
}
self.childNode(withName: "ball")?.run(getSmaller)
self.childNode(withName: "ball")?.removeFromParent()
}
currentBall.name = "ball"
shape.name = "ball"
self.addChild(currentBall)
}
func addSquare(_ size: CGSize) {
// Add the square
}
func randomBallPosition() -> CGPoint {
let xPosition = CGFloat(arc4random_uniform(UInt32((view?.bounds.maxX)! + 1)))
let yPosition = CGFloat(arc4random_uniform(UInt32((view?.bounds.maxY)! + 1)))
return CGPoint(x: xPosition, y: yPosition)
}
Now the above code assumes you have some property named shape because from what I could tell you never explicitly instantiated that, but you begin manipulating it.

How to change an SKSpriteNode image once a condition is met?

I'm trying to change the image of the SKSpriteNode in my shop scene when an upgrade is bought, I believe I'm on the right track with the variable, but I think I am doing it wrong. Thanks for the help in advanced, I've been trying for a while to figure it out with no luck.
// ShopScene.swift
// TheLastFlight
//
// Created by -Zachary Walensa- on 8/3/16.
// Copyright © 2016 -Zachary Walensa-. All rights reserved.
//
import Foundation
import SpriteKit
var coinUpgrade = defaults.integer(forKey: "coinUpgradeSaved")
var missileUpgrade = defaults.integer(forKey: "missileUpgradeSaved")
class ShopScene: SKScene {
var coinLabel = SKLabelNode(fontNamed: "The Bold Font")
var missileUpgrades = SKSpriteNode(imageNamed: "missile1")
override func didMove(to view: SKView) {
coinLabel.text = "Coins: \(coinNumber)"
coinLabel.fontSize = 100
coinLabel.fontColor = SKColor.black
coinLabel.zPosition = 1
coinLabel.position = CGPoint(x: self.size.width/2, y: self.size.height*0.1)
self.addChild(coinLabel)
let background = SKSpriteNode(imageNamed: "background")
background.size = self.size
background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
background.zPosition = 0
self.addChild(background)
let mainMenu = SKLabelNode(fontNamed: "The Bold Font")
mainMenu.text = "Main Menu"
mainMenu.fontSize = 100
mainMenu.fontColor = SKColor.darkGray
mainMenu.position = CGPoint(x: self.size.width*0.5, y: self.size.height*0.3)
mainMenu.zPosition = 1
mainMenu.name = "Main Menu"
self.addChild(mainMenu)
let Life = SKSpriteNode(imageNamed: "lifeButton")
Life.position = CGPoint(x: self.size.width*0.3, y: self.size.height*0.8)
Life.zPosition = 1
Life.name = "Life"
self.addChild(Life)
let coinUpgrades = SKSpriteNode(imageNamed: "coinUpgrade")
coinUpgrades.position = CGPoint(x: self.size.width*0.5, y: self.size.height*0.8)
coinUpgrades.zPosition = 1
coinUpgrades.name = "Coin"
self.addChild(coinUpgrades)
missileUpgrades.position = CGPoint(x: self.size.width*0.8, y: self.size.height*0.8)
missileUpgrades.zPosition = 1
missileUpgrades.name = "missile"
self.addChild(missileUpgrades)
/*let coinLabel = SKLabelNode(fontNamed: "The Bold Font")
coinLabel.text = "Coins: \(coinNumber)"
coinLabel.fontSize = 100
coinLabel.fontColor = SKColor.black
coinLabel.zPosition = 1
coinLabel.position = CGPoint(x: self.size.width/2, y: self.size.height*0.1)
self.addChild(coinLabel) */
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let pointOfTouch = touch.location(in: self)
let nodeITapped = atPoint(pointOfTouch)
if nodeITapped.name == "Main Menu" {
let sceneToMoveTo = MainMenuScene(size: self.size)
sceneToMoveTo.scaleMode = self.scaleMode
let myTrasition = SKTransition.fade(withDuration: 0.5)
self.view!.presentScene(sceneToMoveTo, transition: myTrasition)
}
if nodeITapped.name == "Life" {
if coinNumber >= 50 {
lifeNumber += 1
coinNumber -= 50
defaults.set(coinNumber, forKey: "coinNumberSaved")
defaults.set(lifeNumber, forKey: "lifeNumberSaved")
coinLabel.text = "Coins: \(coinNumber)"
}
}
if nodeITapped.name == "Coin" {
if coinNumber >= 600 {
coinNumber -= 600
defaults.set(coinNumber, forKey: "coinNumberSaved")
coinUpgrade = 1
defaults.set(coinUpgrade, forKey: "coinUpgradeSaved")
coinLabel.text = "Coins: \(coinNumber)"
}
}
if nodeITapped.name == "missile" {
if missileUpgrade == 2 {
missileUpgrade = 1
defaults.set(missileUpgrade, forKey: "missileUpgradeSaved")
if missileUpgrade == 1 {
missileUpgrade = 2
defaults.set(missileUpgrade, forKey: "missileUpgradeSaved")
}
}
else if missileUpgrade == 0 || coinNumber >= 1400 {
coinNumber -= 1400
defaults.set(coinNumber, forKey: "coinNumberSaved")
missileUpgrade = 2
defaults.set(missileUpgrade, forKey: "missileUpgradeSaved")
coinLabel.text = "Coins: \(coinNumber)"
missileUpgrades = SKSpriteNode(imageNamed: "missile")
}
}
}
}
}
There are a few ways to do this:
1) Create a Boolean variable that switches to true when the condition is met. Then in the update function, you can constantly check for if the condition is met:
var conditionIsMet = false
// Your code
//
//...
override func update(_ currentTime: CFTimeInterval) {
if conditionIsMet {
// Change your texture here
}
}
2) Where you get the trigger for when you want to change the texture, you can simply change the texture as part of the code/function that runs. That means that if you are trying to do this on a touch, you would add the code to change the texture there.
FYI: To change the texture just do something like this:
node.texture = SKTexture(imageNamed: "image name goes here")

SkNode name nil on TouchesBegan with Sprite Kit

I've got 4 SKNode's in my Scene.
In TouchesBegan method, one of them has nil as name, even if I've assigned it on instantiation.
After touching another node, that node shows the correct name.
What could be the problem?
I'm a newbie with Sprite Kit Framework.
Here are initializations.
var rightPortBorder = SKSpriteNode(color: UIColor.yellowColor(), size: CGSize(width: 10, height: UIScreen.mainScreen().bounds.height/5))
rightPortBorder.position = CGPoint(x: UIScreen.mainScreen().bounds.width-5, y: (UIScreen.mainScreen().bounds.size.height/2))
rightPortBorder.name = rightPortCategoryName
var rightPortBody = SKPhysicsBody(rectangleOfSize: rightPortBorder.size)
rightPortBody.friction = 0.0
rightPortBody.dynamic = false
rightPortBody.contactTestBitMask = portCategory
rightPortBorder.physicsBody = rightPortBody
rightPort = rightPortBorder
self.addChild(rightPortBorder)
var leftPortBorder = SKSpriteNode(color: UIColor.yellowColor(), size: CGSize(width: 10, height: UIScreen.mainScreen().bounds.height/5))
leftPortBorder.position = CGPoint(x: 5, y: (UIScreen.mainScreen().bounds.size.height/2))
leftPortBorder.name = leftPortCategoryName
var leftPortBody = SKPhysicsBody(rectangleOfSize: leftPortBorder.size)
leftPortBody.friction = 0.0
leftPortBody.dynamic = false
leftPortBody.contactTestBitMask = portCategory
leftPortBorder.physicsBody = leftPortBody
leftPort = leftPortBorder
self.addChild(leftPortBorder)
var topPortBorder = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: UIScreen.mainScreen().bounds.height/5, height: 10))
topPortBorder.position = CGPoint(x: (UIScreen.mainScreen().bounds.size.width/2), y: UIScreen.mainScreen().bounds.size.height-5)
topPortBorder.name = topPortCategoryName
var topPortBody = SKPhysicsBody(rectangleOfSize: topPortBorder.size)
topPortBody.friction = 0.0
topPortBody.dynamic = false
topPortBody.contactTestBitMask = portCategory
topPortBorder.physicsBody = topPortBody
topPort = topPortBorder
self.addChild(topPortBorder)
var bottomPortBorder = SKSpriteNode(color: UIColor.yellowColor(), size: CGSize(width: UIScreen.mainScreen().bounds.height/5, height: 10))
bottomPortBorder.position = CGPoint(x: (UIScreen.mainScreen().bounds.size.width/2), y: 5)
bottomPortBorder.name = bottomPortCategoryName
var bottomPortBody = SKPhysicsBody(rectangleOfSize: bottomPortBorder.size)
bottomPortBody.friction = 0.0
bottomPortBody.dynamic = false
bottomPortBody.contactTestBitMask = portCategory
bottomPortBorder.physicsBody = bottomPortBody
bottomPort = bottomPortBorder
self.addChild(bottomPortBorder)
And here's touches began method
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
var touch = touches.first as! UITouch
var touchLocation = touch.locationInNode(self)
if let body = physicsWorld.bodyAtPoint(touchLocation) {
if body.node!.name == rightPortCategoryName {
println("Began touch on right paddle")
resetAllFlagsTouch()
isFingerOnRightPort = true
}
else if body.node!.name == topPortCategoryName {
println("Began touch on top paddle")
resetAllFlagsTouch()
isFingerOnTopPort = true
}
else if body.node!.name == bottomPortCategoryName {
println("Began touch on bottom paddle")
resetAllFlagsTouch()
isFingerOnBottomPort = true
}
if body.node!.name == leftPortCategoryName {
println("Began touch on left paddle")
resetAllFlagsTouch()
isFingerOnLeftPort = true
}
}
}
I solved my problem editing the touchesBegan method: instead of getting the node from the world, I used the method locationInNode to get my node.
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
/* Called when a touch begins */
var touch = touches.first as! UITouch
var touchLocation = touch.locationInNode(self)
var node = self.nodeAtPoint(touchLocation)
if node.name == rightPortCategoryName {
println("Began touch on right paddle")
resetAllFlagsTouch()
isFingerOnRightPort = true
}
else if node.name == topPortCategoryName {
println("Began touch on top paddle")
resetAllFlagsTouch()
isFingerOnTopPort = true
}
else if node.name == bottomPortCategoryName {
println("Began touch on bottom paddle")
resetAllFlagsTouch()
isFingerOnBottomPort = true
}
if node.name == leftPortCategoryName {
println("Began touch on left paddle")
resetAllFlagsTouch()
isFingerOnLeftPort = true
}
}

Physics issue: ball is bouncing too high

I am working on game where a ball bounces and hits a platform and then bounces right back. Ideally the ball should bounce to exactly the height that it started at. However, in my game the ball slowly keeps bouncing higher and higher. I've looked at the documentation and tried to change all of the physics properties but nothing seems to work.
Any suggestions?
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let ballCategory:UInt32 = 0x1 << 0;
let circleCategory:UInt32 = 0x1 << 1;
let platformCategory:UInt32 = 0x1 << 2;
var ball = SKShapeNode(circleOfRadius: 20.0)
var circle = SKShapeNode(circleOfRadius: 200.0)
var platform = SKShapeNode(rectOfSize: CGSizeMake(10, 1))
var circleColor = 2
var ballColor = 3
var scoreLabel: SKLabelNode!
var score = 0
override func didMoveToView(view: SKView) {
setUpLabels()
self.physicsWorld.contactDelegate = self
backgroundColor = (UIColor.whiteColor())
ball.fillColor = SKColor.redColor()
ball.strokeColor = SKColor.clearColor()
ball.position = CGPoint(x: self.size.width/2, y: self.size.height/2+60)
ball.physicsBody = SKPhysicsBody(circleOfRadius: 20)
ball.physicsBody?.categoryBitMask = ballCategory
ball.physicsBody?.collisionBitMask = platformCategory
ball.physicsBody?.contactTestBitMask = platformCategory
ball.physicsBody?.dynamic = true
ball.physicsBody?.restitution = 1.0
ball.physicsBody?.affectedByGravity = true
ball.physicsBody?.linearDamping = 0.0
ball.physicsBody?.friction = 0.0
self.addChild(ball)
circle.fillColor = SKColor.clearColor()
circle.strokeColor = SKColor.redColor()
circle.lineWidth = 5.0
circle.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
circle.physicsBody = SKPhysicsBody(edgeLoopFromPath: circle.path)
circle.physicsBody?.categoryBitMask = circleCategory
self.addChild(circle)
platform.fillColor = SKColor.clearColor()
platform.strokeColor = SKColor.clearColor()
platform.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(10, 1))
platform.position = CGPoint(x: self.size.width/2, y: circle.position.y/2)
platform.physicsBody?.categoryBitMask = platformCategory
platform.physicsBody?.dynamic = false
platform.physicsBody?.friction = 0.0
self.addChild(platform)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
circleColor += 1
if circleColor%3 == 1 {
circle.strokeColor = UIColor.redColor()
}
if circleColor%3 == 2 {
circle.strokeColor = UIColor.greenColor()
}
if circleColor%3 == 3 {
circle.strokeColor = UIColor.yellowColor()
}
if circleColor%3 == 4 {
circle.strokeColor = UIColor.greenColor()
}
if circleColor%3 == 5 {
circle.strokeColor = UIColor.blueColor()
}
if circleColor%3 == 0 {
circle.strokeColor = UIColor.yellowColor()
}
}
func didBeginContact(contact: SKPhysicsContact) {
if ball.fillColor == circle.strokeColor {
score += 1
scoreLabel.text = String("Score \(score)")
}
if ball.fillColor != circle.strokeColor {
let transition = SKTransition.revealWithDirection(SKTransitionDirection.Down, duration: 1.0)
let scene = SecondScene(size: self.scene!.size)
scene.scaleMode = SKSceneScaleMode.AspectFill
self.scene!.view!.presentScene(scene, transition: transition)
}
ballColor = Int(arc4random_uniform(10))
if ballColor%3 == 1 {
ball.fillColor = UIColor.redColor()
}
if ballColor%3 == 2 {
ball.fillColor = UIColor.greenColor()
}
if ballColor%3 == 3 {
ball.fillColor = UIColor.yellowColor()
}
if ballColor%3 == 4 {
ball.fillColor = UIColor.greenColor()
}
if ballColor%3 == 5 {
ball.fillColor = UIColor.blueColor()
}
if ballColor%3 == 0 {
ball.fillColor = UIColor.yellowColor()
}
}
func setUpLabels () {
scoreLabel = SKLabelNode(fontNamed: "Arial")
scoreLabel.position = CGPoint(x: 60, y: self.size.height-30)
scoreLabel.text = String("Score \(score)")
scoreLabel.fontColor = UIColor.blackColor()
scoreLabel.fontSize = 25
self.addChild(scoreLabel)
}
override func update(currentTime: CFTimeInterval) {
}
}
Reduce restitution a little which take control of the bounciness of the physics body. Like this:
ball.physicsBody?.restitution = 0.9
In general numerical differential equation solvers that solve the ode for the next time step will introduce energy into the system, which is why you are seeing what you are seeing. You can mitigate this by introduce a damping force. In the case of SpriteKit this means changing the restitution or linear damping factors.
For more about the drift that occurs see: https://en.wikipedia.org/wiki/Energy_drift or http://www.cs.cmu.edu/~baraff/sigcourse/notesb.pdf.

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.