Im starting to learn how to code and i have no clue how to save the score to stay as a high score. any help will be appreciated! i already tried and tried but i can't manage to get it right. at this point i don't know what to do.
class Game: SKScene, SKPhysicsContactDelegate {
let Ball = SKSpriteNode(imageNamed: "Red.png")
var QuitOption = SKLabelNode()
var ScoreLabel = SKLabelNode()
var timesecond = Int(60)
var locked = false
var loseOption = SKLabelNode()
var scorePoints = SKLabelNode()
var score = Int()
var highScore = SKLabelNode()
let whiteBall = SKSpriteNode(imageNamed: "fingerPointingDown.png")
struct PhysicsCategory {
static let Ball: UInt32 = 0b1
static let whiteBall: UInt32 = 0b10
}
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.whiteColor() // background for the display
self.physicsWorld.gravity = CGVectorMake(0, -9.8)
self.physicsWorld.contactDelegate = self
let SceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
SceneBody.friction = 0
self.physicsBody = SceneBody
scorePoints = SKLabelNode(fontNamed: "Noteworthy-Light")
scorePoints.text = "0"
scorePoints.fontColor = SKColor.blackColor()
scorePoints.fontSize = 35
scorePoints.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*1 - 120)
scorePoints.name = "Points"
scorePoints.hidden = true
addChild(scorePoints)
Ball.size = CGSize(width: 82, height: 82)
Ball.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.1 - 60)
Ball.physicsBody = SKPhysicsBody(circleOfRadius: 41)
Ball.physicsBody?.affectedByGravity = true
Ball.physicsBody?.density = 10
Ball.physicsBody?.restitution = 0.1
Ball.physicsBody?.linearDamping = 0
Ball.name = "Ball"
Ball.physicsBody?.usesPreciseCollisionDetection = true
Ball.physicsBody?.categoryBitMask = PhysicsCategory.Ball
Ball.physicsBody?.contactTestBitMask = PhysicsCategory.whiteBall
Ball.physicsBody?.collisionBitMask = PhysicsCategory.whiteBall
self.addChild(Ball)
QuitOption.text = "Quit"
QuitOption.fontName = "Noteworthy-Light"
QuitOption.fontColor = SKColor.purpleColor()
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.fontColor = SKColor.redColor()
ScoreLabel.fontSize = 35 // 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 + 160, y: self.frame.size.height/1 - 115) // position of ScoreLabelNode
ScoreLabel.name = "Score+"
ScoreLabel.hidden = false
self.addChild(ScoreLabel)
whiteBall.size = CGSize(width: 55, height: 55)
whiteBall.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.8 - 30)
whiteBall.name = "whiteBall"
whiteBall.physicsBody = SKPhysicsBody(circleOfRadius: 25)
whiteBall.physicsBody?.dynamic = false
whiteBall.physicsBody?.restitution = 0.1
whiteBall.physicsBody?.usesPreciseCollisionDetection = true
whiteBall.physicsBody?.categoryBitMask = PhysicsCategory.whiteBall
whiteBall.physicsBody?.contactTestBitMask = PhysicsCategory.Ball
whiteBall.physicsBody?.collisionBitMask = PhysicsCategory.Ball
self.addChild(whiteBall)
}
// 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 {
Ball.physicsBody?.allowsRotation = true
Ball.physicsBody?.velocity = CGVectorMake(0, 0)
Ball.physicsBody?.applyImpulse(CGVectorMake(0, 450))
}
}
if(!self.locked){
self.locked = true
var actionrun = SKAction.waitForDuration(0.5)
var actionwait = SKAction.runBlock({
self.timesecond--
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = "\(self.timesecond)"
if (self.timesecond == 0){
let myScene = WT(size: self.size)
myScene.scaleMode = self.scaleMode
let reveal = SKTransition.fadeWithDuration(1)
self.view?.presentScene(myScene, transition: reveal)
}
})
let loopAction = SKAction.repeatAction(SKAction.sequence([actionwait, actionrun]), count: 60)
ScoreLabel.runAction(loopAction, withKey: "scoreAction")
}
}
func didBeginContact(contact: SKPhysicsContact) {
let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collision == PhysicsCategory.Ball | PhysicsCategory.whiteBall {
score++
scorePoints.text = "Score: \(score)"
scorePoints.hidden = false
}
}
}
The simplest way is to use NSUserDefaults.
NSUserDefaults.standardUserDefaults().setInteger(highScore, forKey: "high_score")
NSUserDefaults.synchronize() // must be used to save
You can then load the score when needed
let highScore: Int = NSUserDefaults.standardUserDefaults().integerForKey("high_score")
You can access NSUserDefaults from anywhere, saving and loading as needed.
If you have more global player state, create an object for it and you could serialize the object by making it conform to NSCoding protocol.
You would need to implement the encode and decode functions, that save aand load your object's properties.
Related
I'm having a play with game programming in Swift/Xcode and am struggling getting collision to work.
I'm using Xcode 8 Beta 3 (because I couldn't use Xcode 7 on MacOS Sierra) so its using the new Swift 3.0 Syntax. The game has a little puppy (defined in a SK Scene file) that jumps and collects thrown items from the right. The thrown item is created in a function and removed when a new item is thrown.
I need contact with the thrown item comes into contact with the puppy. I've got physics turned on and the item bounces off the puppy but no contact is registered.
Heres my code. Appologies for the mess of code but its very first attempt at Swift and everything just thrown in for now. I can't see what I'm doing wrong :(
UPDATE: As cocoajoe suggested, I've tried setting the masks to 1 and have simplified the code to remove references to the gamescene.sks file and created everything programmatically but its still not working. I've updated the code below to reflect the latest version of the code...
import SpriteKit
import AVFoundation
class GameScene: SKScene, SKPhysicsContactDelegate {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder) is not used in this app")
}
override init(size: CGSize) {
super.init(size: size)
anchorPoint = CGPoint(x: 0.0, y: 0.0)
}
var isJumping = false
var gamePaused = false
var gameRunning = false
var playerScore = 0
var lastSpawnTime = 0
var lastTick = 0
var spawnDelay = 4
let PuppyCategory : UInt32 = 0x1 << 0
let ThrowableCategory : UInt32 = 0x1 << 1
let GroundCategory : UInt32 = 0x1 << 2
override func didMove(to view: SKView) {
physicsWorld.gravity = CGVector(dx: 0.0, dy: -9.8)
physicsWorld.contactDelegate = self
let background = SKSpriteNode(imageNamed: "bg")
background.anchorPoint = CGPoint(x: 0.0, y:0.0)
background.size = size
addChild(background)
// Set up Ground Object
let Ground = SKSpriteNode()
Ground.name = "Ground"
Ground.size = CGSize(width:frame.width, height: frame.height / 10)
Ground.position = CGPoint(x: frame.midX, y: Ground.frame.height / 2 )
Ground.zPosition = -20
Ground.color = SKColor.white()
// Set up the Physics
Ground.physicsBody = SKPhysicsBody(rectangleOf: Ground.size)
Ground.physicsBody!.categoryBitMask = GroundCategory
Ground.physicsBody!.contactTestBitMask = PuppyCategory | ThrowableCategory
Ground.physicsBody!.collisionBitMask = PuppyCategory | ThrowableCategory
Ground.physicsBody?.affectedByGravity = false
Ground.physicsBody?.allowsRotation = false
Ground.physicsBody?.isDynamic = false
Ground.physicsBody?.mass = 1.99999
// Initialise the Node
addChild(Ground)
// Create a Puppy
let Puppy = SKSpriteNode(imageNamed: "puppy1")
Puppy.name = "Puppy"
Puppy.position = CGPoint(x: frame.width / 10, y: frame.height / 2)
Puppy.size = CGSize(width: frame.width / 7, height: frame.height / 5)
Puppy.zPosition = 3
// Set up the Physics
Puppy.physicsBody = SKPhysicsBody(rectangleOf: Puppy.size)
Puppy.physicsBody!.categoryBitMask = PuppyCategory
Puppy.physicsBody!.contactTestBitMask = ThrowableCategory | GroundCategory
Puppy.physicsBody!.collisionBitMask = ThrowableCategory | GroundCategory
Puppy.physicsBody?.affectedByGravity = true
Puppy.physicsBody?.allowsRotation = false
Puppy.physicsBody?.isDynamic = true
Puppy.physicsBody?.mass = 1.99999
// Set up the Textures/Animation Frames
var TextureAtlas = SKTextureAtlas()
var TextureArray = [SKTexture]()
TextureAtlas = SKTextureAtlas(named: "puppy")
for i in 1...TextureAtlas.textureNames.count {
let Name = "puppy\(i).png"
TextureArray.append(SKTexture(imageNamed: Name))
}
Puppy.run(SKAction.repeatForever(SKAction.animate(with:TextureArray, timePerFrame: 0.1)))
// Add the Sprite
addChild(Puppy)
let gameMessage = SKSpriteNode(imageNamed: "TapToPlay")
gameMessage.name = "GameMessage"
gameMessage.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
gameMessage.zPosition = 30
gameMessage.setScale(0.0)
addChild(gameMessage)
let gameLogo = SKSpriteNode(imageNamed: "pjlogo")
gameLogo.name = "GameLogo"
gameLogo.size = CGSize(width: frame.width / 3, height: frame.height / 5)
gameLogo.position = CGPoint(x: frame.midX, y: (frame.maxY / 100) * 80)
gameLogo.zPosition = 30
addChild(gameLogo)
let scale = SKAction.scale(to: 1.0, duration: 1)
scene?.childNode(withName: "GameMessage")!.run(scale)
if let musicURL = Bundle.main.urlForResource("bgmusic", withExtension: "mp3") {
var backgroundMusic: SKAudioNode!
backgroundMusic = SKAudioNode(url: musicURL)
addChild(backgroundMusic)
}
startNewGame()
}
func puppyJump() {
if gameRunning {
let Puppy = childNode(withName: "Puppy")
if !isJumping {
Puppy?.physicsBody?.applyImpulse(CGVector(dx: 0,dy: 1400))
isJumping = true
}
}
}
func generateThrowable() {
print("new enemy")
let oldItem = childNode(withName: "throwableItem")
oldItem?.removeFromParent()
let throwableItem = SKSpriteNode(imageNamed: "puppy1")
throwableItem.name = "throwableItem"
throwableItem.position = CGPoint(x: frame.maxX, y: frame.midY)
throwableItem.zPosition = 3
throwableItem.setScale(0.1)
throwableItem.physicsBody = SKPhysicsBody(rectangleOf: throwableItem.size)
throwableItem.physicsBody!.categoryBitMask = ThrowableCategory
throwableItem.physicsBody!.contactTestBitMask = PuppyCategory | GroundCategory
throwableItem.physicsBody!.collisionBitMask = PuppyCategory | GroundCategory
throwableItem.physicsBody?.friction = 0.1
throwableItem.physicsBody?.restitution = 0.1
throwableItem.physicsBody?.mass = 0.01
throwableItem.physicsBody?.affectedByGravity = true
throwableItem.physicsBody?.allowsRotation = true
throwableItem.physicsBody?.isDynamic = true
addChild(throwableItem)
throwableItem.physicsBody?.applyImpulse(CGVector(dx: -7,dy: 4))
let throwableTrail = SKEmitterNode(fileNamed: "particleTrail.sks")
throwableTrail?.name = "throwableTrail"
throwableTrail?.targetNode = scene
throwableItem.addChild(throwableTrail!)
}
func startNewGame() {
let logo = childNode(withName: "GameLogo")
let gameMessage = childNode(withName: "GameMessage")
logo?.removeFromParent()
gameMessage?.removeFromParent()
let gameScore = SKLabelNode(fontNamed: "Arial")
gameScore.name = "GameScore"
gameScore.text = "Score:0"
gameScore.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.right
gameScore.fontSize = 20
gameScore.position = CGPoint(x: frame.maxX - 20, y: frame.maxY - 26)
gameScore.zPosition = 30
addChild(gameScore)
let pauseButton = SKLabelNode(fontNamed: "Arial")
pauseButton.name = "pauseButton"
pauseButton.text = "PAUSE"
pauseButton.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.left
pauseButton.fontSize = 20
pauseButton.position = CGPoint(x: 20, y: frame.maxY - 26)
pauseButton.zPosition = 30
addChild(pauseButton)
gameRunning = true
}
func didBeginContact(contact: SKPhysicsContact) {
print("contact")
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
// 2
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
// 3
if firstBody.categoryBitMask == PuppyCategory && secondBody.categoryBitMask == GroundCategory {
print("Hit bottom. First contact has been made.")
}
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
if gameRunning {
let gameScore = childNode(withName: "GameScore") as? SKLabelNode
gameScore?.text = "Score:\(playerScore)"
let currentTick:Int = Int(ceil(currentTime))
if lastTick < currentTick {
lastTick = currentTick
}
if (lastSpawnTime + spawnDelay) < currentTick {
// Time to Spawn new Bad Guy
generateThrowable()
lastSpawnTime = currentTick
}
}
}
}
I haven't checked other parts. (Your code still needs plenty of resources...)
But this line:
func didBeginContact(contact: SKPhysicsContact) {
needs to be changed as:
func didBegin(_ contact: SKPhysicsContact) {
in Swift 3. (Which is suggested by Xcode, with just typing didBegin.)
Please try.
So I am playing around with Swift and SpriteKit. I decided to create a simple game where a character will walk to a chest of coins and get all the treasure.
I am trying to detect when the two objects contact eachother, however nothing seems to be happening.
What I did:
1) I set the delegate:
SKPhysicsContactDelegate
2) Created the scene:
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.whiteColor()
physicsWorld.contactDelegate = self
let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
sceneBody.friction = 0
background.zPosition = -20
background.anchorPoint = CGPointZero
background.position = CGPointZero
backgroundRepeated.zPosition = -20
backgroundRepeated.anchorPoint = CGPointZero
backgroundRepeated.position = CGPointMake(background.size.width-1,0)
addChest()
addCharacter()
addChild(background)
addChild(backgroundRepeated)
}
3) Created the items:
func addChest() {
chestOfCoins.anchorPoint = CGPointZero
chestOfCoins.size = CGSize(width: 200,height: 200)
chestOfCoins.position = CGPoint(x: self.frame.width-1, y: 300)
chestOfCoins.zPosition = 20
chestOfCoins.physicsBody = SKPhysicsBody(rectangleOfSize: chestOfCoins.size)
chestOfCoins.physicsBody?.affectedByGravity = false
chestOfCoins.physicsBody?.dynamic = false
chestOfCoins.physicsBody?.categoryBitMask = physicsCategory.chests
chestOfCoins.physicsBody?.collisionBitMask = 0
chestOfCoins.physicsBody?.contactTestBitMask = physicsCategory.character
addChild(chestOfCoins)
}
func addCharacter() {
character.anchorPoint = CGPointZero
character.position = CGPoint(x: 300, y: 300)
character.zPosition = 20
character.size = CGSize(width: 200, height: 200)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.affectedByGravity = false
character.physicsBody?.dynamic = false
character.physicsBody?.categoryBitMask = physicsCategory.character
character.physicsBody?.contactTestBitMask = physicsCategory.chests
character.physicsBody?.collisionBitMask = 0
addChild(character)
}
4) created didBeginContact:
func didBeginContact(contact: SKPhysicsContact) {
var contactBody1: SKPhysicsBody
var contactBody2: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
contactBody1 = contact.bodyA
contactBody2 = contact.bodyB
} else {
contactBody1 = contact.bodyB
contactBody2 = contact.bodyA
}
if((contactBody1.categoryBitMask == 1) && (contactBody2.categoryBitMask == 2)) {
print("touched")
} else {
print("not these two")
}
}
FYI, this IF if((contactBody1.categoryBitMask == 1) && (contactBody2.categoryBitMask == 2)) does not output Either the main if block or the else.
5) I created the category physics :
struct physicsCategory {
static let none: UInt32 = 0 //0
static let character: UInt32 = 0b1 //1
static let chests: UInt32 = 0b10 //2
static let snake: UInt32 = 0b100 //4
}
Full GameScene.Swift:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
struct physicsCategory {
static let none: UInt32 = 0 //0
static let character: UInt32 = 0b1 //1
static let chests: UInt32 = 0b10 //2
static let snake: UInt32 = 0b100 //4
static let all: UInt32 = UInt32.max
}
let background = SKSpriteNode(imageNamed: "Backgrounds")
let backgroundRepeated = SKSpriteNode(imageNamed: "Backgrounds")
let chestOfCoins = SKSpriteNode(imageNamed: "chest")
let character = SKSpriteNode(imageNamed: "character")
let gameActions = NSUserDefaults.standardUserDefaults()
func addChest() {
chestOfCoins.anchorPoint = CGPointZero
chestOfCoins.size = CGSize(width: 200,height: 200)
chestOfCoins.position = CGPoint(x: self.frame.width-1, y: 300)
chestOfCoins.zPosition = 20
chestOfCoins.physicsBody = SKPhysicsBody(rectangleOfSize: chestOfCoins.size)
chestOfCoins.physicsBody?.affectedByGravity = false
chestOfCoins.physicsBody?.dynamic = false
chestOfCoins.physicsBody?.categoryBitMask = physicsCategory.chests
chestOfCoins.physicsBody?.collisionBitMask = 0
chestOfCoins.physicsBody?.contactTestBitMask = physicsCategory.character
addChild(chestOfCoins)
}
func addCharacter() {
character.anchorPoint = CGPointZero
character.position = CGPoint(x: 300, y: 300)
character.zPosition = 20
character.size = CGSize(width: 200, height: 200)
character.physicsBody = SKPhysicsBody(rectangleOfSize: character.size)
character.physicsBody?.affectedByGravity = false
character.physicsBody?.dynamic = false
character.physicsBody?.categoryBitMask = physicsCategory.character
character.physicsBody?.contactTestBitMask = physicsCategory.chests
character.physicsBody?.collisionBitMask = 0
addChild(character)
}
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.whiteColor()
physicsWorld.contactDelegate = self
let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
sceneBody.friction = 0
background.zPosition = -20
background.anchorPoint = CGPointZero
background.position = CGPointZero
backgroundRepeated.zPosition = -20
backgroundRepeated.anchorPoint = CGPointZero
backgroundRepeated.position = CGPointMake(background.size.width-1,0)
addChest()
addCharacter()
addChild(background)
addChild(backgroundRepeated)
}
func didBeginContact(contact: SKPhysicsContact) {
var contactBody1: SKPhysicsBody
var contactBody2: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
contactBody1 = contact.bodyA
contactBody2 = contact.bodyB
} else {
contactBody1 = contact.bodyB
contactBody2 = contact.bodyA
}
if((contactBody1.categoryBitMask == 1) && (contactBody2.categoryBitMask == 2)) {
print("touched")
} else {
print("not these two")
}
}
override func update(currentTime: NSTimeInterval) {
let startWalking = gameActions.boolForKey("Walking")
if (startWalking == true) {
chestOfCoins.position = CGPoint(x: chestOfCoins.position.x - 5, y: chestOfCoins.position.y)
background.position = CGPoint(x: background.position.x - 5, y: background.position.y)
backgroundRepeated.position = CGPoint(x: backgroundRepeated.position.x - 5, y: backgroundRepeated.position.y)
if (background.position.x < -background.size.width) {
background.position = CGPointMake(backgroundRepeated.position.x + backgroundRepeated.size.width, background.position.y)
}
if (backgroundRepeated.position.x < -backgroundRepeated.size.width) {
backgroundRepeated.position = CGPointMake(background.position.x + background.size.width, backgroundRepeated.position.y)
}
}
}
}
Question
Can anyone tell me why, when the screen starts scrolling and those two items come into contact nothing happens and tell me how to fix it?
One also seems to go behind even though I set the zPosition of both to the same
Here is a pic, Don't judge about images :(
set either your chest or your other thingies property to dynamic = true
two non-dynamic physics bodies wont register contacts
I'm creating a game where a player will control a falling sprite with the accelerometer X axis and an impulse is added when the user taps on the screen. In my current code when I run the game, it works okay and then once the player dies and tries again the sprite goes crazy and just flies of the screen. Can someone help please...
class PlayScene: SKScene, SKPhysicsContactDelegate {
var score = 0
var scoreLabel = SKLabelNode()
var gameOverLabel = SKLabelNode()
var labelHolder = SKSpriteNode()
var background = SKSpriteNode()
let playerGroup:UInt32 = 1
let objectGroup:UInt32 = 2
let gapGroup:UInt32 = 0 << 3
let boundary:UInt32 = 4
var movingObjects = SKNode()
var motionManager = CMMotionManager()
var destX:CGFloat = 0.0
var gameOver = 0
var currentX: CGFloat?
let greenPlayer = SKSpriteNode(imageNamed: "Image/Players/greenPlayer.png")
override func didMoveToView(view: SKView) {
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.contactDelegate = self
self.physicsBody!.friction = 0
self.physicsWorld.gravity = CGVectorMake(-0.0, -0.8)
self.addChild(labelHolder)
scoreLabel.fontName = "Helvetica"
scoreLabel.fontSize = 60
scoreLabel.text = "0"
scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), self.frame.size.height - 140)
scoreLabel.zPosition = 10
self.addChild(scoreLabel)
//self.physicsWorld.contactDelegate = self
self.addChild(movingObjects)
let backgroundTexture = SKTexture(imageNamed: "Image/TempBG.png")
background=SKSpriteNode(texture: backgroundTexture)
background.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
background.size.width = self.frame.width
background.zPosition = 0
self.addChild(background)
greenPlayer.physicsBody = SKPhysicsBody(circleOfRadius: greenPlayer.size.height/2)
greenPlayer.physicsBody?.dynamic = true
greenPlayer.physicsBody?.allowsRotation = false
greenPlayer.physicsBody?.categoryBitMask = playerGroup
greenPlayer.physicsBody?.collisionBitMask = objectGroup
greenPlayer.physicsBody?.contactTestBitMask = objectGroup
greenPlayer.physicsBody?.collisionBitMask = gapGroup
greenPlayer.physicsBody?.collisionBitMask = boundary
//self.greenPlayer.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.greenPlayer.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
greenPlayer.zPosition = 5
self.addChild(greenPlayer)
currentX = self.greenPlayer.position.x
//if motionManager.accelerometerAvailable == true {
motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue()!, withHandler:{ data, error in
if data!.acceleration.x < 0 {
self.destX = self.currentX! + CGFloat(data!.acceleration.x * 1000)
}
else if data!.acceleration.x > 0 {
self.destX = self.currentX! + CGFloat(data!.acceleration.x * 1000)
}
})
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("makeDodges"), userInfo: nil, repeats: true)
}
func makeDodges() {
if(gameOver == 0){
let gapWidth = greenPlayer.size.width * 3
let movementAmount = arc4random() % UInt32(self.frame.size.width / 2)
let dodgeOffSet = CGFloat(movementAmount) - (self.frame.size.width / 4)
let moveDodges = SKAction.moveByX(0, y: self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height / 100))
let removeDodges = SKAction.removeFromParent()
let moveAndRemoveDodges = SKAction.sequence([moveDodges, removeDodges])
let dodge1Texture = SKTexture(imageNamed: "Image/Dodge.png")
let dodge1 = SKSpriteNode(texture: dodge1Texture)
dodge1.position = CGPoint(x: CGRectGetMidX(self.frame) + dodge1.size.width/2 + gapWidth/2 + dodgeOffSet, y: CGRectGetMidY(self.frame) - self.frame.size.height)
dodge1.runAction(moveDodges)
dodge1.physicsBody = SKPhysicsBody(rectangleOfSize: dodge1.size)
dodge1.physicsBody?.dynamic = false
dodge1.physicsBody?.categoryBitMask = objectGroup
dodge1.zPosition = 10
movingObjects.addChild(dodge1)
let dodge2Texture = SKTexture(imageNamed: "Image/Dodge.png")
let dodge2 = SKSpriteNode(texture: dodge2Texture)
dodge2.position = CGPoint(x: CGRectGetMidX(self.frame) - dodge2.size.width/2 - gapWidth/2 + dodgeOffSet , y: CGRectGetMidY(self.frame) - self.frame.size.height)
dodge2.runAction(moveDodges)
dodge2.physicsBody = SKPhysicsBody(rectangleOfSize: dodge2.size)
dodge2.physicsBody?.dynamic = false
dodge2.physicsBody?.categoryBitMask = objectGroup
dodge2.zPosition = 10
movingObjects.addChild(dodge2)
let gap = SKNode()
gap.position = CGPoint(x: CGRectGetMidX(self.frame) + dodgeOffSet , y: CGRectGetMidY(self.frame) - self.frame.size.height)
gap.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(dodge1.size.height, gapWidth))
gap.runAction(moveAndRemoveDodges)
gap.physicsBody?.dynamic = false
gap.physicsBody?.collisionBitMask = gapGroup
gap.physicsBody?.categoryBitMask = gapGroup
gap.physicsBody?.contactTestBitMask = playerGroup
movingObjects.addChild(gap)
}
}
func didBeginContact(contact: SKPhysicsContact) {
if contact.bodyA.categoryBitMask == gapGroup || contact.bodyB.categoryBitMask == gapGroup {
score++
print(score)
scoreLabel.text = "\(score)"
} else {
if gameOver == 0 {
gameOver = 1
movingObjects.speed = 0
let scene:SKScene = GameScene(size: self.frame.size)
scene.scaleMode = .AspectFill
let transition:SKTransition = SKTransition.fadeWithDuration(2)
self.view?.presentScene(scene, transition: transition)
}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if(gameOver == 0) {
greenPlayer.physicsBody?.velocity = CGVectorMake(0, 0)
greenPlayer.physicsBody?.applyImpulse(CGVectorMake(0, 50))
} else {
score = 0
scoreLabel.text = "0"
movingObjects.removeAllChildren()
self.greenPlayer.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
greenPlayer.physicsBody?.velocity = CGVectorMake(0, 0)
labelHolder.removeAllChildren()
gameOver = 0
movingObjects.speed = 1
currentX = CGRectGetMidX(self.frame)
}
}
override func update(currentTime: CFTimeInterval) {
let action = SKAction.moveToX(destX, duration: 1)
self.greenPlayer.runAction(action)
}
}
You never stop and remove the old motion manager queue, so your old scene will never die, thus causing your problems.
Add motionManager.stopAccelerometerUpdates();motionManager = nil; at the point you want to destroy your old scene, If you are not destroying your old scene, and just resetting your data, then just add motionManager.stopAccelerometerUpdates(); to the point where you are going to reset your scene.
Before i get any help i want to clarify that Im not an expert as you'll see. I'm a complete beginner in programming. now with that said.
How can i manage to save the high score after the game ends? in the following code I'm using NSUserDefaults but I'm having a problem in it that i can't fix. once i run the game and i get a score of 30 once the countdown hits 0 for example and then i try to play it again and i get a 12 for example it automatically 12 is the new high score to 12 which is totatly wrong but i can't fix it.
class Game: SKScene, SKPhysicsContactDelegate {
let Ball = SKSpriteNode(imageNamed: "Red.png")
var QuitOption = SKLabelNode()
var ScoreLabel = SKLabelNode()
var timesecond = Int(60)
var locked = false
var loseOption = SKLabelNode()
var scorePoints = SKLabelNode()
var score = Int()
let whiteBall = SKSpriteNode(imageNamed: "fingerPointingDown.png")
var caseForScoreOne = SKLabelNode()
var caseForScoreTwo = SKLabelNode()
struct PhysicsCategory {
static let Ball: UInt32 = 0b1
static let whiteBall: UInt32 = 0b10
}
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.whiteColor() // background for the display
self.physicsWorld.gravity = CGVectorMake(0, -9.8)
self.physicsWorld.contactDelegate = self
let SceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
SceneBody.friction = 0
self.physicsBody = SceneBody
scorePoints = SKLabelNode(fontNamed: "Noteworthy-Light")
scorePoints.text = "0"
scorePoints.fontColor = SKColor.blackColor()
scorePoints.fontSize = 35
scorePoints.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*1 - 120)
scorePoints.name = "Points"
addChild(scorePoints)
Ball.size = CGSize(width: 82, height: 82)
Ball.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.1 - 60)
Ball.physicsBody = SKPhysicsBody(circleOfRadius: 41)
Ball.physicsBody?.affectedByGravity = true
Ball.physicsBody?.density = 10
Ball.physicsBody?.restitution = 0.1
Ball.physicsBody?.linearDamping = 0
Ball.name = "Ball"
Ball.physicsBody?.usesPreciseCollisionDetection = true
Ball.physicsBody?.categoryBitMask = PhysicsCategory.Ball
Ball.physicsBody?.contactTestBitMask = PhysicsCategory.whiteBall
Ball.physicsBody?.collisionBitMask = PhysicsCategory.whiteBall
self.addChild(Ball)
QuitOption.text = "Quit"
QuitOption.fontName = "Noteworthy-Light"
QuitOption.fontColor = SKColor.purpleColor()
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.fontColor = SKColor.redColor()
ScoreLabel.fontSize = 35 // 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 + 160, y: self.frame.size.height/1 - 115) // position of ScoreLabelNode
ScoreLabel.name = "Score+"
ScoreLabel.hidden = false
self.addChild(ScoreLabel)
whiteBall.size = CGSize(width: 55, height: 55)
whiteBall.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.8 - 30)
whiteBall.name = "whiteBall"
whiteBall.physicsBody = SKPhysicsBody(circleOfRadius: 25)
whiteBall.physicsBody?.dynamic = false
whiteBall.physicsBody?.restitution = 0.1
whiteBall.physicsBody?.usesPreciseCollisionDetection = true
whiteBall.physicsBody?.categoryBitMask = PhysicsCategory.whiteBall
whiteBall.physicsBody?.contactTestBitMask = PhysicsCategory.Ball
whiteBall.physicsBody?.collisionBitMask = PhysicsCategory.Ball
self.addChild(whiteBall)
caseForScoreOne = SKLabelNode(fontNamed: "Noteworthy-Light")
caseForScoreOne.fontColor = SKColor.blackColor()
caseForScoreOne.fontSize = 25
caseForScoreOne.position = CGPoint(x: self.frame.size.width/2 - 160, y: self.frame.size.height*1 - 175)
caseForScoreOne.name = "caseOne"
addChild(caseForScoreOne)
caseForScoreTwo = SKLabelNode(fontNamed: "Noteworthy-Light")
caseForScoreTwo.fontColor = SKColor.blackColor()
caseForScoreTwo.fontSize = 25
caseForScoreTwo.position = CGPoint(x: self.frame.size.width/2 + 160, y: self.frame.size.height/1 - 175)
caseForScoreTwo.name = "caseTwo"
addChild(caseForScoreTwo)
}
// 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 {
Ball.physicsBody?.allowsRotation = true
Ball.physicsBody?.velocity = CGVectorMake(0, 0)
Ball.physicsBody?.applyImpulse(CGVectorMake(0, 450))
}
}
if(!self.locked){
self.locked = true
var actionrun = SKAction.waitForDuration(0.5)
var actionwait = SKAction.runBlock({
self.timesecond--
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = "\(self.timesecond)"
if (self.timesecond == 0){
self.saveHighScore(0)
if self.score > self.highScore() {
self.saveHighScore(self.score)
self.caseForScoreTwo.text = "N.H.S = " + self.highScore().description
} else if (self.score > self.highScore()) {
self.caseForScoreOne.text = "N.H.S = " + self.score.description
}
}
})
let loopAction = SKAction.repeatAction(SKAction.sequence([actionwait, actionrun]), count: 60)
ScoreLabel.runAction(loopAction, withKey: "scoreAction")
}
}
func didBeginContact(contact: SKPhysicsContact) {
let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collision == PhysicsCategory.Ball | PhysicsCategory.whiteBall {
score++
scorePoints.text = "Score: \(score)"
}
}
func saveHighScore(high:Int) {
NSUserDefaults.standardUserDefaults().setInteger(high, forKey: "highscore")
}
func highScore() -> Int {
return NSUserDefaults.standardUserDefaults().integerForKey("highscore")
}
func resetHighScore() {
NSUserDefaults.standardUserDefaults().removeObjectForKey("highscore")
}
}
func saveHighScore(high:Int) {
if high > highScore() {
NSUserDefaults().setInteger(high, forKey: "highscore")
println("highscore saved")
} else {
println("not a highscore")
}
}
I'm a beginner in coding and I need help in the following code. I'm trying to make the "You Lose!" label appear after the timer hits zero, but when I try to do it; it doesn't show anything. Please help me!
class Game: SKScene {
let Ball = SKSpriteNode(imageNamed: "Red.png")
var QuitOption = SKLabelNode()
var ScoreLabel = SKLabelNode()
var timesecond = Int(60)
var locked = false
var loseOption = SKLabelNode()
var winOption = SKLabelNode()
let whiteBall = SKSpriteNode(imageNamed: "whiteDot")
let showMessage = SKLabelNode()
override func didMoveToView(view: SKView) {
backgroundColor = SKColor.whiteColor() // 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: 82, height: 82)
Ball.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.1)
Ball.physicsBody = SKPhysicsBody(circleOfRadius: 42)
Ball.physicsBody?.affectedByGravity = true
Ball.physicsBody?.density = 10
Ball.physicsBody?.restitution = 0.1
Ball.physicsBody?.linearDamping = 0
Ball.name = "Ball"
self.addChild(Ball)
QuitOption.text = "Quit"
QuitOption.fontName = "Noteworthy-Light"
QuitOption.fontColor = SKColor.redColor()
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.fontColor = SKColor.redColor()
ScoreLabel.fontSize = 35 // 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 + 160, y: self.frame.size.height/1 - 115) // position of ScoreLabelNode
ScoreLabel.name = "Score+"
ScoreLabel.hidden = false
self.addChild(ScoreLabel)
whiteBall.size = CGSize(width: 55, height: 55)
whiteBall.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.8)
whiteBall.name = "whiteBall"
self.addChild(whiteBall)
showMessage.fontName = "Noteworthy-Light"
showMessage.fontSize = 55
showMessage.fontColor = SKColor.whiteColor()
showMessage.text = "YOU LOSE!"
showMessage.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.7)
showMessage.zPosition = 100
showMessage.hidden = true
showMessage.name = "show Message"
self.addChild(showMessage)
}
// 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.previousLocationInNode(self)
// 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, 450))
}
}
if(!self.locked){
self.locked = true
var actionrun = SKAction.waitForDuration(0.5)
var actionwait = SKAction.runBlock({
self.timesecond--
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = "\(self.timesecond)"})
let loopAction = SKAction.repeatAction(SKAction.sequence([actionwait, actionrun]), count: 60)
ScoreLabel.runAction(loopAction, withKey: "scoreAction")
if (timesecond == 0){
showMessage.hidden = false
}
}
}
}
Your code:
if (timesecond == 0){
showMessage.hidden = false
}
... should be in the block that runs every second:
var actionwait = SKAction.runBlock({
self.timesecond--
if self.timesecond == 60 {self.timesecond = 0}
self.ScoreLabel.text = "\(self.timesecond)"
if (self.timesecond == 0){
showMessage.hidden = false
}
})
let loopAction = SKAction.repeatAction(SKAction.sequence([actionwait, actionrun]), count: 60)
ScoreLabel.runAction(loopAction, withKey: "scoreAction")