SpriteKit, SKSpriteNode scale with bouncing - ios

I need to scale SKSpriteNode(with physicsBody) with bouncing.
I don't want to create 3(for example) SKAction for make it.
Does anybody know the scale method taking into account the restitution property of phisicsBody?
Thank you in advance
My variant below
class OpenPlayerScene : SKScene {
private var openFromFrame: CGRect?
private var logoImage: UIImage!
let ballCategory: UInt32 = 1
let wallCategory: UInt32 = 2
convenience init(size: CGSize, openFromFrame: CGRect, imageForOpen:UIImage!) {
self.init(size:size)
self.backgroundColor = SKColor.clearColor()
self.scaleMode = .AspectFit
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody?.categoryBitMask = wallCategory
self.openFromFrame = openFromFrame
self.logoImage = imageForOpen
}
override init(size: CGSize) {
super.init(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func initLogoNode (logoImage: UIImage!) {
let texture = SKTexture(image: logoImage!)
let size = openFromFrame?.size
let imageNode = SKSpriteNode(texture: texture, size: size!)
imageNode.name = "logoNode"
imageNode.physicsBody = SKPhysicsBody(rectangleOfSize: size!)
imageNode.physicsBody?.dynamic = true
imageNode.physicsBody?.restitution = 0.7
imageNode.physicsBody?.affectedByGravity = false
imageNode.physicsBody!.categoryBitMask = ballCategory
let startPosition = CGPointMake(openFromFrame!.origin.x + openFromFrame!.size.width / 2, self.size.height - (openFromFrame!.origin.y + openFromFrame!.size.height / 2))
imageNode.position = startPosition
self.addChild(imageNode)
}
override func didMoveToView(view: SKView) {
self.runAnimation()
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.runAnimation()
}
func runAnimation () {
if let oldNote = self.childNodeWithName("logoNode") {
oldNote.removeFromParent()
}
self.initLogoNode(self.logoImage)
if let imageNode = self.childNodeWithName("logoNode") {
let scaleValue = CGRectGetHeight(self.view!.frame) / CGRectGetHeight(imageNode.frame)
let scale = SKAction.scaleTo(scaleValue * 0.95, duration: 0.5)
let moveToX = SKAction.moveToX(275, duration: 0.5)
let group = SKAction.group([scale, moveToX])
let moveToX2 = SKAction.moveToX(225, duration: 1)
let scale2 = SKAction.scaleTo(scaleValue * 0.8, duration: 1)
let group2 = SKAction.group([scale2, moveToX2])
let moveToX3 = SKAction.moveToX(230, duration: 0.5)
let scale3 = SKAction.scaleTo(scaleValue * 0.82, duration: 0.5)
let group3 = SKAction.group([scale3, moveToX3])
let moveSequence = SKAction.sequence([group, group2, group3])
imageNode.runAction(moveSequence, completion: { () -> Void in
})
}
}
}

Related

Custom SKShapeNode is not appearing on scene when being called from update function

// SpawnBlock Init
class SpawnBlock : SKShapeNode {
var timer: Timer?
init(circleOfRadius radius: CGFloat) {
super.init()
self.alpha = 1
self.zPosition = 2
self.fillColor = UIColor.blue
self.strokeColor = UIColor.blue
self.physicsBody = SKPhysicsBody(circleOfRadius: radius)
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = Collisions.spawnBlock.rawValue
self.physicsBody?.contactTestBitMask = Collisions.block.rawValue
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// Spawn Functions
func spawnABlock() {
let spawnBlock = SpawnBlock(circleOfRadius: 10)
let randomPos = CGPoint(x: CGFloat(arc4random_uniform(UInt32(self.frame.width))), y: CGFloat(arc4random_uniform(UInt32(self.frame.height))))
print("\(randomPos)")
spawnBlock.timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: false, block: { (Timer) in
print("timer done")
spawnBlock.removeFromParent()
})
spawnBlock.position = randomPos
self.addChild(spawnBlock)
}
override func update(_ currentTime: TimeInterval) {
count += 1
print("\(count)")
if count == maxCount {
count = 0
spawnABlock()
}
}
When run in the simulator, the node count increases, the timer works and deinits the sprites, but they do not appear on the scene. Is there a piece I am missing or something?
override init() {
super.init()
}
convenience init(width: CGFloat) {
self.init()
self.init(circleOfRadius: width / 2)
print("initialsed")
self.alpha = 1
self.zPosition = 2
self.fillColor = UIColor.blue
self.strokeColor = UIColor.blue
self.physicsBody = SKPhysicsBody(circleOfRadius: width / 2)
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = Collisions.spawnBlock.rawValue
self.physicsBody?.collisionBitMask = Collisions.block.rawValue
self.physicsBody?.fieldBitMask = Collisions.noField.rawValue
}
Adding these code blocks in for the original initializing function spawns in the blocks.

SpriteKit - Adding enemy causes frame drop

My game is a side scroller using SpriteKit. The player stays at the same x-position and the obstacles are moving towards him. But whenever I add an enemy the frame rate drops for a short moment. I tried to change many things, like removing the enemy's dynamics or animation. But nothing works.
Here's some code:
func addZombie() {
let zombie = Zombie()
zombie.position = CGPoint(x: screenWidth + zombie.size.width * 0.5, y: screenHeight * 0.5)
zombies.append(zombie)
addChild(zombie)
}
The above method creates the enemies. It's called by using:
func generateZombies() {
let wait = SKAction.waitForDuration(2.5)
let run = SKAction.runBlock {
self.addZombie()
}
runAction(SKAction.repeatActionForever(SKAction.sequence([wait, run])))
}
I also tried NSTimer, but nothing works. Please help me.
Zombie():
class Zombie: SKSpriteNode {
var textureArrayWalking = [SKTexture]()
init() {
let mySize = CGSize(width: Player().size.width, height: Player().size.height * (4/3))
super.init(texture: nil, color: UIColor.greenColor(), size: mySize)
orderTextureAtlases()
texture = textureArrayWalking[0]
zPosition = 1
physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: (2/3) * self.size.width, height: self.size.height))
physicsBody?.restitution = 0.0
physicsBody?.categoryBitMask = enemyCategory
physicsBody?.collisionBitMask = groundCategory
physicsBody?.contactTestBitMask = playerCategory | bulletCategory | groundCategory
physicsBody!.allowsRotation = false;
walk()
}
func walk() {
runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(textureArrayWalking, timePerFrame: 0.07)), withKey: walkingActionKeyZombie)
}
func orderTextureAtlases() {
let textureAtlasWalking = SKTextureAtlas(named: "ZombieWalking")
for index in 0..<textureAtlasWalking.textureNames.count {
let name = "ZombieWalking_JeromeWalk_\(index)"
let tex = SKTexture(imageNamed: name)
tex.filteringMode = .Nearest
textureArrayWalking.append(tex)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

ios - Swift 2.2 - SpriteKit - sublassing SKSpriteNode class

For a puzzle game project on iOS, I try to subclass the SKSpriteNode class from SpriteKit with the following code:
class SKPuzzle: SKSpriteNode {
var name2:String = "";
}
I need to add other variables in SKSpriteNode like another name (name2) in this case. Here is the use I made of the class in a class type SKScene:
class GameScene: SKScene {
let background = SKSpriteNode(imageNamed: "BW")
var selectedNode = SKPuzzle()
override init(size: CGSize) {
super.init(size: size)
let imageNames = [sheet.Puzzle13() , sheet.Puzzle19(),sheet.Puzzle30(),
sheet.Puzzle11(), sheet.Puzzle29(), sheet.Puzzle35() ]
for i in 0..<imageNames.count {
let imageName = imageNames[i]
let sprite = SKPuzzle(texture: imageName)
sprite.name = kAnimalNodeName
sprite.name2 = "\(i)"
let offsetFraction = (CGFloat(i) + 1.0)/(CGFloat(imageNames.count) + 1.0)
sprite.position = CGPoint(x: size.width * offsetFraction, y: size.height / 2)
sprite.zPosition = 1
background.addChild(sprite)
}
}
I have the sprite object from the subclass SKPuzzle wich contains the new variable name2.
sprite.name2 = "\(i)"
The problem I have is the variable selectedNode (created with)
var selectedNode = SKPuzzle()
used later in the program contain always a nil value for the data name and name2. When I click on the jigsaw parts of the game, I get the following error:
fatal error: unexpectly found nil while unwrapping an optional value in the following function:
func panForTranslation(translation : CGPoint) {
let position = selectedNode.position
if selectedNode.name! == kAnimalNodeName {
selectedNode.position = CGPoint(x: position.x + translation.x * 2, y: position.y + translation.y * 2)
}
}
selectedNode seems containing only nil values. The code is working fine when I just use the SKSpriteNode but failed with my SKPuzzle class.
Here is the whole code of the program:
import SpriteKit
import UIKit
private let kAnimalNodeName = "puzzle"
private let kdancing = "dancing"
class SKPuzzle: SKSpriteNode {
var name2:String = "";
}
class GameScene: SKScene {
let background = SKSpriteNode(imageNamed: "BW")
var selectedNode = SKPuzzle()
var selectedVideo = SKVideoNode()
override init(size: CGSize) {
super.init(size: size)
// 1
self.background.name = kdancing
self.background.anchorPoint = CGPointZero
background.zPosition = 0
self.addChild(background)
//background.play()
// 2
let sheet = Statiques()
let sprite_dancing1 = SKSpriteNode(texture: sheet.Dancing1())
let sprite_dancing2 = SKSpriteNode(texture: sheet.Dancing2())
sprite_dancing1.name = kdancing
sprite_dancing2.name = kdancing
sprite_dancing1.position = CGPoint(x: 837, y: 752)
sprite_dancing1.zPosition = 1
sprite_dancing2.position = CGPoint(x: 1241, y: 752)
sprite_dancing2.zPosition = 1
background.addChild(sprite_dancing1)
background.addChild(sprite_dancing2)
let imageNames = [sheet.Puzzle13() , sheet.Puzzle19(), sheet.Puzzle30(), sheet.Puzzle11(), sheet.Puzzle29(), sheet.Puzzle35() ]
for i in 0..<imageNames.count {
let imageName = imageNames[i]
let sprite = SKPuzzle(texture: imageName)
sprite.name = kAnimalNodeName
sprite.name2 = "\(i)"
let offsetFraction = (CGFloat(i) + 1.0)/(CGFloat(imageNames.count) + 1.0)
sprite.position = CGPoint(x: size.width * offsetFraction, y: size.height / 2)
sprite.zPosition = 1
background.addChild(sprite)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let positionInScene = touch.locationInNode(self)
selectNodeForTouch(positionInScene)
}
}
override func didMoveToView(view: SKView) {
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: Selector("handlePanFrom:"))
self.view!.addGestureRecognizer(gestureRecognizer)
}
func handlePanFrom(recognizer : UIPanGestureRecognizer) {
if recognizer.state == .Began {
var touchLocation = recognizer.locationInView(recognizer.view)
touchLocation = self.convertPointFromView(touchLocation)
self.selectNodeForTouch(touchLocation)
} else if recognizer.state == .Changed {
var translation = recognizer.translationInView(recognizer.view!)
translation = CGPoint(x: translation.x, y: -translation.y)
self.panForTranslation(translation)
recognizer.setTranslation(CGPointZero, inView: recognizer.view)
} else if recognizer.state == .Ended {
}
}
func degToRad(degree: Double) -> CGFloat {
return CGFloat(degree / 180.0 * M_PI)
}
func selectNodeForTouch(touchLocation : CGPoint) {
// 1
let touchedNode = self.nodeAtPoint(touchLocation)
if touchedNode is SKPuzzle {
// 2
if !selectedNode.isEqual(touchedNode) {
selectedNode.removeAllActions()
selectedNode.runAction(SKAction.rotateToAngle(0.0, duration: 0.1))
//selectedNode = touchedNode as! SKSpriteNode
// 3
if touchedNode.name! == kAnimalNodeName {
let sequence = SKAction.sequence([SKAction.rotateByAngle(degToRad(-4.0), duration: 0.1),
SKAction.rotateByAngle(0.0, duration: 0.1),
SKAction.rotateByAngle(degToRad(4.0), duration: 0.1)])
selectedNode.runAction(SKAction.repeatActionForever(sequence))
}
}
}
}
func panForTranslation(translation : CGPoint) {
let position = selectedNode.position
if selectedNode.name! == kAnimalNodeName {
selectedNode.position = CGPoint(x: position.x + translation.x * 2, y: position.y + translation.y * 2)
}
}
}
Thanks by advance for your help, I'm beginning to code with Swift on iOS.
When selectedNode is created by SKPuzzle(), name is nil.
You have to set selectedNode.name to some value in init method.

JoyStick only moves when Camera Controls = true Xcode, SWIFT, SpriteKit, SceneKit

Hey I have a 3D game thats not really a game yet. But it has a SceneKit 3D scene and a overlayskscene for the HUD/Controls. the "base" is the base of the joystick and the ball is the handle the problem is that the joystick does not move at all unless the scnView.allowsCameraControl = true. I find that weird. and this is my entire view controller code so nothings left out and if you want you can literally copy and paste it into Xcode to see what I'm talking about. Any help?
Code:
import iAd
import UIKit
import GameKit
import SceneKit
import StoreKit
import SpriteKit
import QuartzCore
import Foundation
import AVFoundation
import AudioToolbox
class GameViewController: UIViewController, ADBannerViewDelegate, SKPhysicsContactDelegate, SKSceneDelegate, SCNSceneRendererDelegate, SCNPhysicsContactDelegate{
var stickActive:Bool = false
let base = SKSpriteNode(imageNamed:"VirtualJoystickBase")
let ball = SKSpriteNode(imageNamed:"VirtualJoyStickHandle")
let ship = SKSpriteNode(imageNamed:"Ship")
var ButtonA = SKSpriteNode(imageNamed:"GreenAButton")
var ButtonO = SKSpriteNode(imageNamed:"CircleButton")
var ButtonY = SKSpriteNode(imageNamed:"YellowYButton")
var ButtonSquare = SKSpriteNode(imageNamed:"BlueSquareButton")
let FieldScene = SCNScene(named: "art.scnassets/TesingCampusField.dae")!
let GuyScene = SCNScene(named: "art.scnassets/Guy.dae")!
let overlayScene = SKScene(size: CGSizeMake(100, 100))
override func viewDidLoad() {
super.viewDidLoad()
let scnView = self.view as! SCNView
scnView.overlaySKScene = overlayScene
scnView.backgroundColor = UIColor.whiteColor()
scnView.scene = FieldScene
scnView.delegate = self
scnView.overlaySKScene!.delegate = self
scnView.overlaySKScene!.anchorPoint = CGPointMake(0, 0)
scnView.overlaySKScene!.physicsWorld.contactDelegate = self
scnView.overlaySKScene!.physicsWorld.gravity = CGVectorMake(0.0, 0.0)
scnView.allowsCameraControl = true
scnView.showsStatistics = false
let Guy1: SCNNode = GuyScene.rootNode.childNodeWithName("Bob_014", recursively: true)!
FieldScene.rootNode.addChildNode(Guy1)
//----Positioning-the-Base-of-the-Joystick-----------
base.size = CGSize(width: 14, height: 24)
base.position = CGPointMake(15, 19)
base.zPosition = 0
overlayScene.addChild(base)
//----Positing-the-Ball/Joystick-----------
ball.size = CGSize(width: 10, height: 17)
ball.position = base.position
ball.zPosition = 1
overlayScene.addChild(ball)
//----A-Button--Creation -------------------
ButtonA.size = CGSize(width: 6, height: 9)
ButtonA.anchorPoint = CGPointMake(-13.3, -0.5)
ButtonA.zPosition = 0
overlayScene.addChild(ButtonA)
//----B-Button--Creation -------------------
ButtonO.size = CGSize(width: 6, height: 9)
ButtonO.anchorPoint = CGPointMake(-14.4, -1.7)
ButtonO.zPosition = 0
overlayScene.addChild(ButtonO)
//----C-Button--Creation -------------------
ButtonSquare.size = CGSize(width: 6, height: 9)
ButtonSquare.anchorPoint = CGPointMake(-12.2, -1.7)
ButtonSquare.zPosition = 0
overlayScene.addChild(ButtonSquare)
//----C-Button--Creation -------------------
ButtonY.size = CGSize(width: 6, height: 9)
ButtonY.anchorPoint = CGPointMake(-13.3, -2.7)
ButtonY.zPosition = 0
overlayScene.addChild(ButtonY)
//---Setting-Up-Ships-Position/PhysicsBody---------------------
ship.position = CGPointMake(0, 100)
ship.size = CGSize(width: 80, height: 80)
ship.physicsBody?.dynamic = true
ship.physicsBody?.allowsRotation = true
ship.physicsBody?.affectedByGravity = true
ship.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Ship"), size: ship.size)
ship.physicsBody!.friction = 0
ship.physicsBody!.restitution = 0
ship.physicsBody!.linearDamping = 0
ship.physicsBody!.angularDamping = 0
//--------------------------
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
GuyScene.rootNode.addChildNode(cameraNode)
cameraNode.position = SCNVector3(x: 0, y: 5, z: 15)
//-----------------------------------------------
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = SCNLightTypeOmni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
FieldScene.rootNode.addChildNode(lightNode)
//-----------------------------------------------
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = SCNLightTypeAmbient
ambientLightNode.light!.color = UIColor.darkGrayColor()
FieldScene.rootNode.addChildNode(ambientLightNode)
//----------------------------------------------
}
func YButtonPressed() {
let YButtonPressed = SKTexture(imageNamed: "YellowYButtonPressed")
let OrignalButtonY = SKTexture(imageNamed:"YellowYButton")
let YButtonPressedAnimation = SKAction.animateWithTextures([YButtonPressed, OrignalButtonY], timePerFrame: 0.2)
let RunYButtonPressedAnimation = SKAction.repeatAction(YButtonPressedAnimation, count: 1)
ButtonY.runAction(RunYButtonPressedAnimation)
}
func OButtonPressed() {
let OButtonPressed = SKTexture(imageNamed: "CircleButtonPressed")
let OrignalButtonO = SKTexture(imageNamed:"CircleButton")
let OButtonPressedAnimation = SKAction.animateWithTextures([OButtonPressed, OrignalButtonO], timePerFrame: 0.2)
let RunOButtonPressedAnimation = SKAction.repeatAction(OButtonPressedAnimation, count: 1)
ButtonO.runAction(RunOButtonPressedAnimation)
}
func SquareButtonPressed() {
let SquareButtonPressed = SKTexture(imageNamed: "BlueSquareButtonPressed")
let OrignalButtonSquare = SKTexture(imageNamed:"BlueSquareButton")
let SquareButtonPressedAnimation = SKAction.animateWithTextures([SquareButtonPressed, OrignalButtonSquare], timePerFrame: 0.2)
let RunSquareButtonPressedAnimation = SKAction.repeatAction(SquareButtonPressedAnimation, count: 1)
ButtonSquare.runAction(RunSquareButtonPressedAnimation)
}
func AButtonPressed() {
let AButtonPressed = SKTexture(imageNamed: "GreenAButtonPressed")
let OrignalButtonA = SKTexture(imageNamed:"GreenAButton")
let AButtonPressedAnimation = SKAction.animateWithTextures([AButtonPressed, OrignalButtonA], timePerFrame: 0.2)
let RunAButtonPressedAnimation = SKAction.repeatAction(AButtonPressedAnimation, count: 1)
ButtonA.runAction(RunAButtonPressedAnimation)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if (CGRectContainsPoint(base.frame, location)) {
print("stickActive = true")
stickActive = true
} else {
print("stickActive = false")
stickActive = false
}
}
for touch: AnyObject in touches {
let location1 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location1) == self.ButtonA {
AButtonPressed()
print("AButtonPressed")
}
}
for touch: AnyObject in touches {
let location2 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location2) == self.ButtonO {
OButtonPressed()
print("OButtonPressed")
}
}
for touch: AnyObject in touches {
let location3 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location3) == self.ButtonY {
YButtonPressed()
print("YButtonPressed")
}
}
for touch: AnyObject in touches {
let location4 = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location4) == self.ButtonSquare {
SquareButtonPressed()
print("SquarButtonPressed")
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location) == self.ball {
if (stickActive == true) {
let v = CGVector(dx: location.x - base.position.x, dy: location.y - base.position.y)
let angle = atan2(v.dy, v.dx)
//println( deg + 180)
let length:CGFloat = base.frame.size.height / 2
let xDist:CGFloat = sin(angle - 1.57879633) * length
let yDist:CGFloat = cos(angle - 1.57879633) * length
if (CGRectContainsPoint(base.frame, location)) {
ball.position = location
} else {
ball.position = CGPointMake( base.position.x - xDist, base.position.y + yDist)
}
ship.zRotation = angle - 1.57879633
let calcRotation : Float = Float(angle - 1.57879633) + Float(M_PI_2);
let intensity : CGFloat = 200.0 // put your value
let xVelocity = intensity * CGFloat(cosf(calcRotation))
let yVelocity = intensity * CGFloat(sinf(calcRotation))
let vector : CGVector = CGVectorMake(xVelocity, yVelocity)
//Apply force to spaceship
ship.physicsBody?.applyForce(vector)
// ends stackActive
}
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self.overlayScene)
if self.overlayScene.nodeAtPoint(location) == self.ball {
if (stickActive == true) {
let move:SKAction = SKAction.moveTo(base.position, duration: 0.05)
move.timingMode = .EaseOut
ball.runAction(move)
}
}
}
}
//====================================================================
override func shouldAutorotate() -> Bool {
return true
}
//====================================================================
override func prefersStatusBarHidden() -> Bool {
return true
}
//====================================================================
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}
//====================================================================
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
}
there's an issue in SceneKit where the SpriteKit overlay isn't automatically redrawn when changes are made in the 2D scene but the 3D scene is left untouched. In other words, the 2D overlay is only redrawn when the 3D view needs to be redrawn.
You can set the playing property of the SCNView to YES to fix this. Alternatively you can call -setNeedsDisplay whenever you make a change to the overlay scene.

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