SKLabelNode upside down possible? - ios

I'm developing a game in xcode 6 with swift. I have a scorelabel var scoreLabel: SKLabelNode!. Now in one of my methods I show my label:
scoreLabel = SKlabelNode(fontNamed: "TrebuchetMS-Bold")
scoreLabel.text = "\(score)"
scoreLabel.fontSize = 30
scoreLabel.fontColor = SKColor .redColor()
scoreLabel.position = CGPoint(x:780, y:180)
addChild(scoreLabel)
That shows my score as for example: 2500.
Is it possible to show this upside down?
2
5
0
0
Sorry, I wrote this as list, because I wasn't able to write upside down here.
Thanks for answers.

Use the SKLabelNodePlus label for this. Here is the link: https://github.com/MKargin0/SKLabelNodePlus
Then, just invert the label by writing myLabel.xScale = -1. Its as simple as that!

You can create a custom class to loop through each character in the string and create a separate SKLabelNode for each character.
class SKVerticalLabelNode : SKNode
{
var fontName : String = "" {
didSet {
self.updateLabelProperties()
}
}
var fontSize : CGFloat = 10.0 {
didSet {
self.updateLabelProperties()
}
}
var fontColor : UIColor = UIColor.whiteColor() {
didSet {
self.updateLabelProperties()
}
}
var text : String = "" {
didSet {
self.updateLabelProperties()
}
}
func updateLabelProperties () {
self.removeAllChildren()
let length = countElements(text)
var yPosition : CGFloat = 0
for character in reverse(text) {
let label = SKLabelNode(fontNamed: self.fontName)
label.fontColor = self.fontColor
label.fontSize = self.fontSize
label.text = String(character)
label.position = CGPointMake(0, yPosition)
yPosition += label.frame.size.height
addChild(label)
}
}
}
It can be used like this
let scoreLabel = SKVerticalLabelNode()
scoreLabel.fontName = "TrebuchetMS-Bold"
scoreLabel.text = "2500"
scoreLabel.fontSize = 30
scoreLabel.fontColor = UIColor.redColor()
scoreLabel.position = CGPoint(x:180, y:180)
addChild(scoreLabel)

Related

Smiley Rating Bar swift

If we had to do this Smiley Rating Bar on iOS...how we can do?
In the link-example, use a gif, but let's avoid this
If I had to do it ... I would use 5 images of faces for the background with their respective descriptions.
For the face that moves in its position X would use UIPanGestureRecognizer:
class ViewController: UIViewController , UIGestureRecognizerDelegate , UITextFieldDelegate{
#IBOutlet weak var image1: UIImageView!
var panGesture = UIPanGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.draggedView(_:)))
image1.isUserInteractionEnabled = true
image1.addGestureRecognizer(panGesture)
}
func draggedView(_ sender:UIPanGestureRecognizer){
self.view.bringSubview(toFront: image1)
let translation = sender.translation(in: self.view)
image1.center = CGPoint(x: image1.center.x + translation.x, y: image1.center.y)
sender.setTranslation(CGPoint.zero, in: self.view)
}
}
The question I have is how do I move the image1 to detect what is going on "above" the images below. Like this:
So...any help I will appreciate
I have done the same thing, Please use
https://github.com/gali8/G8SliderStep/tree/master/G8SliderStep Library .Please replace the Draw labels and Draw Images method with following in G8SliderStep.swift File.
#objc internal func drawLabels() {
guard let ti = tickTitles else {
return
}
if _stepTickLabels == nil {
_stepTickLabels = []
}
if let sl = _stepTickLabels {
for l in sl {
l.removeFromSuperview()
}
_stepTickLabels?.removeAll()
for index in 0..<ti.count {
let title = ti[index]
let lbl = UILabel()
lbl.font = unselectedFont
lbl.text = title
lbl.textAlignment = .center
lbl.sizeToFit()
var offset: CGFloat = 0
if index+1 < (steps%2 == 0 ? steps/2+1 : steps/2) {
offset = trackLeftOffset/2
}
else if index+1 > (steps%2 == 0 ? steps/2+1 : steps/2) {
offset = -(trackRightOffset/2)
}
if index == 0 {
offset = trackLeftOffset
}
if index == steps {
offset = -trackRightOffset
}
let x = offset + CGFloat(Double(index) * stepWidth) - (lbl.frame.size.width / 2)
var rect = lbl.frame
rect.origin.x = x
rect.origin.y = bounds.midY - (bounds.size.height / 2) - rect.size.height + 80
lbl.frame = rect
self.addSubview(lbl)
_stepTickLabels?.append(lbl)
}
}
}
#objc internal func drawImages() {
guard let ti = tickImages else {
return
}
if _stepTickImages == nil {
_stepTickImages = []
}
if let sl = _stepTickImages {
for l in sl {
l.removeFromSuperview()
}
_stepTickImages?.removeAll()
for index in 0..<ti.count {
let img = ti[index]
let imv = UIImageView(image: img)
imv.contentMode = .scaleAspectFit
imv.sizeToFit()
var offset: CGFloat = 0
if index+1 < (steps%2 == 0 ? steps/2+1 : steps/2) {
offset = trackLeftOffset/2
}
else if index+1 > (steps%2 == 0 ? steps/2+1 : steps/2) {
offset = -(trackLeftOffset/2)
}
if index == 0 {
offset = trackLeftOffset
}
if index == steps {
offset = -trackRightOffset
}
let x = offset + CGFloat(Double(index) * stepWidth) - (imv.frame.size.width / 2)
var rect = imv.frame
rect.origin.x = x
rect.origin.y = bounds.midY - (bounds.size.height / 2)
imv.frame = rect
self.insertSubview(imv, at: 2) //index 2 => draw images below the thumb/above the line
_stepTickImages?.append(imv)
}
}
}
Please get selected and unselected emoticons image from your personal resource, and pass those image in array as done in given example.In your view controller in viewDidLoad please write this code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
sliderStepBar.stepImages = [UIImage(named:"terrible")!, UIImage(named:"bad")!, UIImage(named:"okay")!, UIImage(named:"good")!,UIImage(named:"great")!, ]
sliderStepBar.tickTitles = ["Terrible", "Bad", "Okay", "Good", "Great"]
sliderStepBar.tickImages = [#imageLiteral(resourceName: "unselectterrible"), #imageLiteral(resourceName: "unselectbad"), #imageLiteral(resourceName: "unselectokay"),#imageLiteral(resourceName: "unselectgood"),#imageLiteral(resourceName: "unselectgreat")]
sliderStepBar.minimumValue = 4
sliderStepBar.maximumValue = Float(sliderStepBar.stepImages!.count) + sliderStepBar.minimumValue - 1.0
sliderStepBar.stepTickColor = UIColor.clear
sliderStepBar.stepTickWidth = 40
sliderStepBar.stepTickHeight = 40
sliderStepBar.trackHeight = 5
sliderStepBar.value = 5
}
Enjoy the Smiley Rating.
Happy Coding.
I have created the same, Check the below image
Overview
Easy customization(Font, Colors, Images, Ticks, Height, Width, Rounded)
#IBInspectable
Tappable
Draggable
Swift 5.0 above
Xcode 11 above
Orientation support
Manual drag & drop the class
Find the GIT URL for code
SmileyRating

In SpriteKit when sound is being played it messes with accelerometer

I have an issue whereby I am moving the character based on the accelerometer data using the following code in the update function as follows:
let currentX = self.player.position.x
if motionManager.isAccelerometerAvailable == true {
motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler: {
data, error in
self.destX = currentX + CGFloat((data?.acceleration.x)! * 40)
print(CGFloat((data?.acceleration.x)!))
})
}
player.position.x = destX
Originally I was moving the player using SKAction.moveTo but have removed this for testing purposes.
This works ok but the problem is, I have a sound that is being played upon collision of an invisible object and when this is enabled it sends the accelerometer all funny. There is no specific pattern to it but after a little while the player usually sticks to either side of the screen or just hovers in the middle and the accelerometer doesn't have any effect on the movement.
I am playing the sound using
let playSound = SKAction.playSoundFileNamed("phaserDown3.mp3", waitForCompletion: false)
At the top of the file and then calling run on a collision.
The full code is in here http://pastebin.com/f6kWTnr7 and I have made a little video of the issue here https://youtu.be/tcGYyrKE4QY - as you will see, in this case when the score is at around 15 it sticks to the left for a little bit, then returns to normal then sticks to the right. It isn't always at score 15, it can be sooner or even later there is no consistency at all.
Any input will be greatly appreciated, thank you in advance
Take a look at this updated scene, some of the major changes are I combined your 3 separate blocks into 1 SKNode so that I only have to move the single SKNode, and I set it up where you score at the end of a contact, not the beginning. You can also see that the blocks now die when done scrolling, and your background is more efficient with its scrolling. If you have any other questions on the changes, feel free to ask.
//
// GameScene.swift
// SpriteKitSimpleGame
//
// Created by James Leist on 28/11/2016.
// Copyright © 2016 James Leist. All rights reserved.
//
import SpriteKit
import CoreMotion
var motionManager = CMMotionManager()
enum BodyType:UInt32 {
case player = 1
case score = 2
case dontCollide = 4
case sides = 8
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var killNodes = [SKNode]()
//let player = SKSpriteNode(imageNamed: "Airplane")
let player = SKSpriteNode(color: .green, size: CGSize(width:32,height:32))
var bg1:SKSpriteNode!
var bg2:SKSpriteNode!
let block = SKNode()
let blockHeight = 50
var currentScore = 0
var scoreLabel:SKLabelNode!
let playSound = SKAction.playSoundFileNamed("phaserDown3.mp3", waitForCompletion: false)
let move = SKAction.move(by:CGVector(dx:0,dy:-4 * 60),duration:1) //this means we move 4 every 1/60 of a second
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
backgroundColor = SKColor.white
addScrollingBG()
createRandomBlock()
addRandomBlocks1()
// sideRestraints()
scoreLabel = SKLabelNode(fontNamed: "Copperplate-Bold")
scoreLabel.text = String(currentScore)
scoreLabel.fontSize = 80
scoreLabel.position = CGPoint(x: frame.size.width - 60, y: frame.size.height - 60)
scoreLabel.zPosition = 20
self.addChild(scoreLabel)
player.name = "Player"
player.zPosition = 15
player.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
// player.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Airplane"), size: CGSize(width: player.size.width, height: player.size.height))
player.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: player.size.width, height: player.size.height))
player.physicsBody?.affectedByGravity = false
player.physicsBody!.categoryBitMask = BodyType.player.rawValue
player.physicsBody!.contactTestBitMask = BodyType.score.rawValue | BodyType.sides.rawValue
player.physicsBody!.collisionBitMask = 0
addChild(player)
startAccelerometer()
}
func startAccelerometer()
{
if motionManager.isAccelerometerAvailable == true {
motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler: {
[weak self] data, error in
guard let strongSelf = self else {return}
var destX = UInt32(strongSelf.player.position.x + CGFloat((data?.acceleration.x)! * 40))
// Called before each frame is rendered */
if destX <= 0 {
destX = 0
}
else if destX >= UInt32(strongSelf.frame.size.width) {
destX = UInt32(strongSelf.frame.size.width)
}
strongSelf.player.position.x = CGFloat(destX)
print(CGFloat((data?.acceleration.x)!))
})
}
}
func addScrollingBG() {
bg1 = SKSpriteNode(imageNamed: "bgPlayScene")
bg1 = SKSpriteNode(color:.blue,size:self.size)
bg1.anchorPoint = CGPoint.zero
bg1.position = CGPoint(x: 0, y: 0)
// bg1.size = CGSize(width: frame.size.width, height: frame.size.height)
bg1.zPosition = 0
addChild(bg1)
bg2 = SKSpriteNode(imageNamed: "bgPlayScene")
bg2 = SKSpriteNode(color:.purple,size:self.size)
bg2.anchorPoint = CGPoint.zero
bg2.position = CGPoint(x: 0, y: bg1.size.height)
// bg2.size = CGSize(width: frame.size.width, height: frame.size.height)
bg2.zPosition = 0
self.addChild(bg2)
setupBackgroundAnimation()
}
func setupBackgroundAnimation()
{
let reset = SKAction.customAction(withDuration: 1,actionBlock:
{
node,time in
guard let sNode = node as? SKSpriteNode else {return}
sNode.position = sNode.position.y <= -sNode.size.height ?
CGPoint(x: sNode.position.x, y: sNode.position.y + sNode.size.height * 2) : sNode.position
})
let scroll = SKAction.repeatForever(SKAction.group([move,reset]))
bg1.run(scroll)
bg2.run(scroll)
}
func createRandomBlock()
{
block.position = CGPoint(x:0,y:size.height + CGFloat(blockHeight))
//let partialBlock = SKSpriteNode(imageNamed: "block")
let partialBlock = SKSpriteNode(color:.yellow, size:CGSize(width: 1, height: blockHeight))
let blockLeft1 = partialBlock.copy() as! SKSpriteNode
blockLeft1.name = "left"
blockLeft1.anchorPoint = CGPoint.zero
blockLeft1.size = CGSize(width: 1, height: blockHeight)
blockLeft1.zPosition = 5;
blockLeft1.position = CGPoint.zero
block.addChild(blockLeft1)
let leftBody = SKPhysicsBody(rectangleOf: blockLeft1.size)
leftBody.affectedByGravity = false
leftBody.categoryBitMask = BodyType.sides.rawValue
leftBody.contactTestBitMask = 0
leftBody.collisionBitMask = 0
leftBody.isDynamic = false
blockLeft1.physicsBody = leftBody
let blockRight1 = partialBlock.copy() as! SKSpriteNode
blockRight1.color = .green
blockRight1.anchorPoint = CGPoint.zero
blockRight1.name = "right"
blockRight1.size = CGSize(width: 1, height: blockHeight)
blockRight1.zPosition = 5;
blockRight1.position = CGPoint(x:size.width,y:0)
block.addChild(blockRight1)
let rightBody = SKPhysicsBody(rectangleOf: blockRight1.size)
rightBody.affectedByGravity = false
rightBody.categoryBitMask = BodyType.sides.rawValue
rightBody.contactTestBitMask = 0
rightBody.collisionBitMask = 0
rightBody.isDynamic = false
blockRight1.physicsBody = rightBody
let scoreBody = SKPhysicsBody(rectangleOf:CGSize(width:Int(frame.size.width),height:blockHeight))
scoreBody.affectedByGravity = false
scoreBody.categoryBitMask = BodyType.score.rawValue
scoreBody.contactTestBitMask = 0
scoreBody.collisionBitMask = 0
scoreBody.isDynamic = false
block.physicsBody = scoreBody
}
func addRandomBlocks1() {
let randomLeftWidth : UInt32 = arc4random_uniform(UInt32(size.width) - 50)
let randomRightWidth : UInt32 = arc4random_uniform((UInt32(size.width) - randomLeftWidth) - 50)
guard let newBlock = block.copy() as? SKNode else {return} //ifw e do not have a node return
if let leftBlock = newBlock.childNode(withName:"left") as? SKSpriteNode
{
leftBlock.xScale = CGFloat(randomLeftWidth)
}
if let rightBlock = newBlock.childNode(withName:"right") as? SKSpriteNode
{
rightBlock.xScale = -CGFloat(randomRightWidth)
}
let addRandom = SKAction.customAction(withDuration: 0, actionBlock:
{
[unowned self] node,time in
if Int(node.position.y) < -self.blockHeight
{
node.removeFromParent()
self.addRandomBlocks1()
}
})
newBlock.run(SKAction.repeatForever(SKAction.group([move,addRandom])))
addChild(newBlock)
}
override func update(_ currentTime: CFTimeInterval) {
}
override func didFinishUpdate()
{
killNodes.forEach{$0.removeFromParent()}
}
func didBegin(_ contact: SKPhysicsContact) {
//This will organize the bodies so that the lowest category is A
let bodies = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? (A:contact.bodyA,B:contact.bodyB) : (A:contact.bodyB,B:contact.bodyA)
switch (bodies.A.categoryBitMask,bodies.B.categoryBitMask)
{
case let (a, b) where ((a & BodyType.player.rawValue) | (b & BodyType.sides.rawValue)) > 0:
killNodes.append(bodies.A.node!)
let label = SKLabelNode(text: "Gameover")
label.position = CGPoint(x:self.size.width/2,y:self.size.height/2)
addChild(label)
default:()
}
}
func didEnd(_ contact: SKPhysicsContact) {
//This will organize the bodies so that the lowest category is A
let bodies = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? (A:contact.bodyA,B:contact.bodyB) : (A:contact.bodyB,B:contact.bodyA)
switch (bodies.A.categoryBitMask,bodies.B.categoryBitMask)
{
case let (a, b) where ((a & BodyType.player.rawValue) | (b & BodyType.score.rawValue)) > 0:
currentScore += 1
run(playSound, withKey:"phaser")
scoreLabel.text = String(currentScore)
default:()
}
}
}

How to apply dynamicBehavior on multiple objects simultaneously

I'm trying to use DynamicBehaviors on Label objects I have just created from a Array. For this I use the "For In" loop. All objects get created as expected, but only the last get dynamic.
Maybe I should use the UIDynamicItemGroup, but after many tries, I still don't figure out how to use it.
As you are maybe wondering, I'm new to object oriented programming so I hope it will not be a waste of time for you.
Below the code I have actually.
Thanks in advance.
import UIKit
class ViewController: UIViewController {
var tests:[String] = ["test1","test2","test3","test4","test5","test6","test7","test8","test9","test10","test11"]
var viewLabelArray:UIView!
var label:UILabel!
var color:UIColor!
var animator:UIDynamicAnimator!
var dynamicBehavior:UIDynamicBehavior!
var collisionBehavior:UICollisionBehavior!
var countLabel = 0
override func viewDidLoad() {
super.viewDidLoad()
let size:CGFloat = 50.0
var positionX:CGFloat = 60.0
var positionY:CGFloat = 100.0
for test in tests {
label = UILabel(frame:CGRect(x: positionX, y: positionY, width: size, height: size))
label.center = CGPoint(x: positionX, y: positionY)
label.layer.cornerRadius = size * 0.5
label.layer.masksToBounds = true
label.backgroundColor = color
label.textAlignment = .center
label.textColor = UIColor.white
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
label.text = test
self.view.addSubview(label)
countLabel = countLabel + 1
if countLabel == 4 || countLabel == 8 {
positionX = positionX - 140
positionY = positionY + 100
} else {
positionX = positionX + 60
}
let gravity = UIGravityBehavior(items: [label])
let direction = CGVector(dx: 0.0, dy: 1.0)
gravity.gravityDirection = direction
let bounce = UIDynamicItemBehavior(items: [label])
bounce.elasticity = 1
let boundries = UICollisionBehavior(items: [label])
boundries.translatesReferenceBoundsIntoBoundary = true
animator = UIDynamicAnimator(referenceView: self.view)
animator.addBehavior(bounce)
animator.addBehavior(boundries)
animator.addBehavior(gravity)
}
}
}
I modified some line of your code and it's perfectly working for me.
Thanks to Alexander Momchliov
var animatorArray = [UIDynamicAnimator]()
for (i,test) in tests.enumerated() {
//code
let bounce = UIDynamicItemBehavior(items: [label])
bounce.elasticity = 1
let boundries = UICollisionBehavior(items: [label])
boundries.translatesReferenceBoundsIntoBoundary = true
animatorArray.append(UIDynamicAnimator(referenceView: self.view))
animatorArray[i].addBehavior(gravity)
animatorArray[i].addBehavior(bounce)
animatorArray[i].addBehavior(boundries)
}
Screenshot:

How to use CollisionBehavior properly to bring items to collide with each other

Probably an easy one for you.
I simply want to use the collisionMode the right way. My code seems ok (no bug), but items collide only with the boundaries of the view. Not with each other.
I'm wondering if "translatesReferenceBoundsIntoBoundary" would be overwriting the collisionMode.
Maybe I should use the "addBoundary(withIdentifier:NSCopying, from: CGPoint, to:CGPoint)" method instead of "translateReferenceBoundsIntoBoundary" but didn't find how to implement the NSCopying class.
Below my code for details.
Thanks in advance.
import UIKit
class ViewController: UIViewController {
var tests:[String] = ["test1","test2","test3","test4","test5","test6","test7","test8","test9","test10","test11"]
var label:UILabel!
var color:UIColor!
var dynamicBehavior:UIDynamicBehavior!
var collisionBehavior:UICollisionBehavior!
var animatorArray = [UIDynamicAnimator]()
var countLabel = 0
override func viewDidLoad() {
super.viewDidLoad()
let size:CGFloat = 50.0
var positionX:CGFloat = 60.0
var positionY:CGFloat = 100.0
for test in tests {
label = UILabel(frame:CGRect(x: positionX, y: positionY, width: size, height: size))
label.center = CGPoint(x: positionX, y: positionY)
label.layer.cornerRadius = size * 0.5
label.layer.masksToBounds = true
label.backgroundColor = color
label.textAlignment = .center
label.textColor = UIColor.white
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 1
label.text = test
self.view.addSubview(label)
countLabel = countLabel + 1
if countLabel == 4 || countLabel == 8 {
positionX = positionX - 140
positionY = positionY + 100 }
else { positionX = positionX + 60}
for (i,_) in tests.enumerated() {
let gravity = UIGravityBehavior(items: [label])
let direction = CGVector(dx: 0.0, dy: 1.0)
gravity.gravityDirection = direction
let bounce = UIDynamicItemBehavior(items: [label])
bounce.elasticity = 1.0
let collisions = UICollisionBehavior(items: [label])
collisions.translatesReferenceBoundsIntoBoundary = true
collisions.collisionMode = UICollisionBehaviorMode.everything
animatorArray.append(UIDynamicAnimator(referenceView: self.view))
animatorArray[i].addBehavior(bounce)
animatorArray[i].addBehavior(collisions)
animatorArray[i].addBehavior(gravity)
}
}
}
}
Each of your labels is being added to a separate instance of UIDynamicAnimator with separate instances of all the behaviors in your for-loop. You can make just one property of the animator and each of your behaviors and add each of your labels to the same animator and behaviors. This way the animator is in charge of ALL of the labels, instead of just one.

Swift - How to change background color when a certain amount of points are gained

I have been working on a game that when the player gets 10 points the background will change into another color that I put in the string, the same will happen for 20 points, 30 points and so on. My question is how can I make the background fade into different colors when the player gets over 10 points /20 points /30 points. I don't want the colors to be random as I want to put my own color codes/hex values, also I don't want the colors to change when a button is pressed. I just want it to change when the player gets the over a certain amount of points.
A good example of this would be the game "Don't Touch The Spikes" every 5 points you gain the background fades into a different one.
Note: I made the game in the GameScene and not using the GameViewController as it I made the project into a game file so:
import Foundation
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var movingGround: PPMovingGround!
var hero: PPHero!
var wallGen: PPWallGen!
var isStarted = false
var isGameOver = false
override func didMoveToView(view: SKView) {
//backgroundColor = UIColor.greenColor()
backgroundColor = UIColor(red: 223/255.0, green: 86/255.0, blue: 94/255.0, alpha: 1.0)
addMovingGround()
addHero()
addWallGen()
addTapToStartLabel()
addStageLabel()
addPointsLabels()
addPhysicsWorld()
loadHighscore()
}
func addLevelLabel() {
}
func addMovingGround() {
movingGround = PPMovingGround(size: CGSizeMake(view!.frame.width, kMLGroundHeight))
movingGround.position = CGPointMake(0, view!.frame.size.height/2)
addChild(movingGround)
}
func addHero() {
hero = PPHero()
hero.position = CGPointMake(70, movingGround.position.y + movingGround.frame.size.height/2 + hero.frame.size.height/2)
addChild(hero)
}
func addWallGen() {
wallGen = PPWallGen(color: UIColor.clearColor(), size: view!.frame.size)
wallGen.position = view!.center
addChild(wallGen)
}
func addTapToStartLabel() {
let tapToStartLabel = SKLabelNode(text: "Tap to start!")
tapToStartLabel.name = "tapToStartLabel"
tapToStartLabel.position.x = view!.center.x
tapToStartLabel.position.y = view!.center.y + 40
tapToStartLabel.fontName = "Helvetica"
tapToStartLabel.fontColor = UIColor.whiteColor()
tapToStartLabel.fontSize = 22.0
addChild(tapToStartLabel)
tapToStartLabel.runAction(blinkAnimation())
}
func addStageLabel() {
let stageLabel = PPStageLabel(num: 1)
stageLabel.name = "stageLabel"
stageLabel.position.x = view!.center.x
stageLabel.position.y = view!.center.y - 120
stageLabel.fontColor = UIColor.whiteColor()
stageLabel.fontName = "Helvetica"
stageLabel.fontSize = 40
addChild(stageLabel)
let stageTextLabel = SKLabelNode(text: "Stage")
stageTextLabel.fontColor = UIColor.whiteColor()
stageTextLabel.fontSize = 14.0
stageTextLabel.fontName = "Helvetica"
stageTextLabel.position = CGPointMake(3.0,-15.0)
stageLabel.addChild(stageTextLabel) }
func addPointsLabels() {
let pointsLabel = PPPointsLabel(num: 0)
pointsLabel.name = "pointsLabel"
pointsLabel.position.x = view!.center.x
pointsLabel.position.y = view!.center.y + 120
pointsLabel.fontColor = UIColor.whiteColor()
pointsLabel.fontName = "Helvetica"
pointsLabel.fontSize = 40
addChild(pointsLabel)
let highscoreLabel = PPPointsLabel(num: 0)
highscoreLabel.name = "highscoreLabel"
highscoreLabel.position = CGPointMake(view!.frame.size.width - 40, view!.frame.size.height - 30)
highscoreLabel.fontColor = UIColor.whiteColor()
highscoreLabel.fontName = "Helvetica"
highscoreLabel.fontSize = 24
addChild(highscoreLabel)
let highscoreTextLabel = SKLabelNode(text: "Highscore: ")
highscoreTextLabel.fontColor = UIColor.whiteColor()
highscoreTextLabel.fontSize = 14.0
highscoreTextLabel.fontName = "Helvetica"
highscoreTextLabel.position = CGPointMake(-70.0,3.5)
highscoreLabel.addChild(highscoreTextLabel)
}
func addPhysicsWorld() {
physicsWorld.contactDelegate = self
}
func loadHighscore() {
let defaults = NSUserDefaults.standardUserDefaults()
let highscoreLabel = childNodeWithName("highscoreLabel") as! PPPointsLabel
highscoreLabel.setTo(defaults.integerForKey("highscore"))
}
// MARK - Game Lifecycle
func start() {
isStarted = true
let tapToStartLabel = childNodeWithName("tapToStartLabel")
tapToStartLabel?.removeFromParent()
hero.stop()
movingGround.start()
wallGen.startGenWallsEvery(1)
}
func gameOver() {
isGameOver = true
// everything stops
hero.fall()
wallGen.stopWalls()
movingGround.stop()
hero.stop()
// create game over label
let gameOverLabel = SKLabelNode(text: "Game Over!")
gameOverLabel.fontColor = UIColor.whiteColor()
gameOverLabel.fontName = "Helvetica"
gameOverLabel.position.x = view!.center.x
gameOverLabel.position.y = view!.center.y + 80
gameOverLabel.fontSize = 22.0
addChild(gameOverLabel)
gameOverLabel.runAction(blinkAnimation())
// save current points label value
let pointsLabel = childNodeWithName("pointsLabel") as! PPPointsLabel
let highscoreLabel = childNodeWithName("highscoreLabel") as! PPPointsLabel
let stageLabel = childNodeWithName("stageLabel") as! PPStageLabel
if highscoreLabel.number < pointsLabel.number {
highscoreLabel.setTo(pointsLabel.number)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(highscoreLabel.number, forKey: "highscore")
}
}
func restart() {
let newScence = GameScene(size: view!.bounds.size)
newScence.scaleMode = .AspectFill
view!.presentScene(newScence)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if isGameOver {
restart()
}else if !isStarted {
start()
}else{
hero.flip()
}
}
override func update(currentTime: CFTimeInterval) {
if wallGen.wallTrackers.count > 0 {
let wall = wallGen.wallTrackers[0] as PPWall
let wallLocation = wallGen.convertPoint(wall.position, toNode: self)
if wallLocation.x < hero.position.x {
wallGen.wallTrackers.removeAtIndex(0)
let pointsLabel = childNodeWithName("pointsLabel") as! PPPointsLabel
pointsLabel.increment()
}
}else if
wallGen.wallTrackers.count > 0 {
let wall = wallGen.wallTrackers[0] as PPWall
let wallLocation = wallGen.convertPoint(wall.position, toNode: self)
if wallLocation.x < hero.position.x {
wallGen.wallTrackers.removeAtIndex(0)
let stageLabel = childNodeWithName("stageLabel") as! PPStageLabel
stageLabel.increment()
}
}
}
// MARK: - SKPhysicsContactDelegate
func didBeginContact(contact: SKPhysicsContact) {
if !isGameOver {
gameOver()
}
}
// MARR: - Animations
func blinkAnimation() -> SKAction {
let duration = 0.4
let fadeOut = SKAction.fadeAlphaTo(0.0, duration: duration)
let fadeIn = SKAction.fadeAlphaTo(1.0, duration: duration)
let blink = SKAction.sequence([fadeOut, fadeIn])
return SKAction.repeatActionForever(blink)
}
}
I think you can't animate SKView.First Declare the variables
var isStarted = false
var isGameOver = false
var lastChangedBackground = 0
var background = SKSpriteNode()
To do what you want you could add an SKNode as child of your SKScene and let it be the background and create a variable lastChangedBackground in the didMoveToView() function. The lastChangedBackground will let the background change its color only once when it get to a certain value of points.
Then you can add to your update function something like this:
override func didMoveToView(view: SKView) {
//backgroundColor = UIColor.greenColor()
//backgroundColor = SKSpriteNode()
var background = SKSpriteNode(color: UIColor(red: 223/255.0, green: 86/255.0, blue: 94/255.0, alpha: 1.0),size: view.bounds.size)
background.position = view.center
self.addChild(background)
addMovingGround()
addHero()
addWallGen()
addTapToStartLabel()
addStageLabel()
addPointsLabels()
addPhysicsWorld()
loadHighscore()
}
override func update(currentTime: CFTimeInterval) {
if wallGen.wallTrackers.count > 0 {
let wall = wallGen.wallTrackers[0] as PPWall
let wallLocation = wallGen.convertPoint(wall.position, toNode: self)
if wallLocation.x < hero.position.x {
wallGen.wallTrackers.removeAtIndex(0)
let pointsLabel = childNodeWithName("pointsLabel") as! PPPointsLabel
pointsLabel.increment()
//Here points should receive pointsLabel value
//if pointsLabel.num % 10 == 0 then points is 10, 20, 30...
if pointsLabel.num % 10 == 0 && pointsLabel.num != lastChangedBackground{
lastChangedBackground = points
if (lastChangedBackground == 10) {
background.runAction(SKAction.colorizeWithColor(SKColor.blueColor(), colorBlendFactor: 0.5, duration: 1))
}
else if(lastChangedBackground == 20){
background.runAction(SKAction.colorizeWithColor(SKColor.greenColor(), colorBlendFactor: 0.5, duration: 1))
}
else if(lastChangedBackground == 30){
background.runAction(SKAction.colorizeWithColor(SKColor.redColor(), colorBlendFactor: 0.5, duration: 1))
}
for wall in wallGen.wallTrackers {
wall.runAction(SKAction.colorizeWithColor(background.color, colorBlendFactor: 0.5, duration: 1))
}
}
}
}else if
wallGen.wallTrackers.count > 0 {
let wall = wallGen.wallTrackers[0] as PPWall
let wallLocation = wallGen.convertPoint(wall.position, toNode: self)
if wallLocation.x < hero.position.x {
wallGen.wallTrackers.removeAtIndex(0)
let stageLabel = childNodeWithName("stageLabel") as! PPStageLabel
stageLabel.increment()
}
}
}

Resources