I want to pause my game for 2 seconds and continue again. I tried the following but it didn't work.
var duration = NSTimeInterval(2)
var wait=SKAction.waitForDuration(duration)
self.runAction(wait)
self is SKScene. Is there a different method to achieve this?
You can set the SKNode.isPaused property. This is a Boolean value that determines whether actions on the node and its descendants are processed.
This means that if you set self.paused = true in the SKScene, all of the child nodes of the scene will be paused. You can also do it to individual nodes like sprites.
For more information
https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKNode_Ref/index.html
Related
I am trying to make a survival game where each level the player has to survive the game for so long in order to get to advance to the next level. However, when I go from level to level, I cannot figure out how to update the score for each scene. I understand how to add and remove subviews, but that is not the problem. The problem is calling a variable in a different scene, and changing that variable from the new scene. I will leave some code here in order for reference. Thank you in advance.
In Level1.swift,
I declare the score var:
var Score = Int()
I then add to it when I want to, and represent it as shown as a label.
Score++
ScoreLabel.text = "\(Score)"
Then in Level2.swift
I declare the variable again
var ScoreLabel = UILabel()
And add to it as well whenever needed... However, the only thing that happens is a new label comes up and overlaps the score label already shown...
Score++
ScoreLabel.text = "\(Score)"
How do I keep a running score from scene to scene in swift?
1.This is where I declare the variable, I only do this in this scene
2.This is where I declare the change of scene, I haven't yet, but this is how I plan on changing each scene
3.This is where I add the subview of the label, I do this the same way in each scene
4.This is where I add to the variable, i call upon it this way in each scene
The UILabel is not part of your scene. It's an element of the container view. Therefore it is always visible and overtime you create a new one, it will be shown on top of the existing label.
The easiest way is to use global variables. Just place
var Score = Int()
var ScoreLabel = UILabel()
outside of the class definition (and add it only once to the container view).
Another option is to use an SKLabel and add it to the scene.
This stack overflow question is about a different issue, but shows a sample how to use an SKLabel for scoring information:
score label display value overwrites
I am thinking about using KVO for the Player's currentTime. But the currentTime is a method ([myPlayer currentTime]) instead of a property, would the KVO work in this case? If not, how could I track the progress of the video playing and set up a float number for the progressView?
Call the AVPlayer's addPeriodicTimeObserverForInterval:queue:usingBlock: to get periodic callbacks based on the current time. The current time is passed to your block as its parameter.
I've created this block of code to create an animation to make a selection visible. called in touchesBegan.
private func setSelectionAnim(atPoint point:CGPoint) {
selectAnim.removeActionForKey(ANIM_SELECT)
let action = SKAction.repeatActionForever( SKAction.animateWithTextures(WBTextures.Select(), timePerFrame: 0.33))
selectAnim.position = point
selectAnim.runAction(action, withKey: ANIM_SELECT)
}
WBTextures.Select() is an instance of a TexturePacker generated class and selecAnim is a SKNode() instantiated and added as a child to the GameScene in the init.
But if I cancel the the animation (when a target is selected ) with the following code:
private func stopSelectionAnim()
{
selectAnim.removeActionForKey(ANIM_SELECT)
}
The Problem is: that when i call stopSelectAnim() the last presented texture stays visible on screen. which after searching the SpriteKit Programming Guide
Canceling Running Actions To cancel actions that a node is running,
call its removeAllActions method. All actions are removed from the
node immediately. If a removed action had a duration, any changes it
already made to the node remain intact, but further changes are not
executed.
would be expected. After that a added the line selectAnim.removeFromParent() now the artifact disappears. But now the problem occurs that the next time setSelectionAnim(atPoint point:CGPoint) is called nothing happens. Logic if i deleted the node, but don't get a run time error ,so 'selectAnim' is not nil. Why does adding the extra line, solve the problem and introduces the next.
what is the best practice to interrupt an animation and still be able to enable it.
I've come up with a couple of ideas which none of I really like and fit into my scene setup.
re-instantiating and addChild' theselecAnimin the beginning of each call tosetSelectionAnim(atPoint point:CGPoint)`
create an action sequence with a runBlock() which checks a Bool whether to stop and if so how do I stop the animation with in a block
adding the animation to a new SKNode and add this as a child to the selecAnim node. ( I've tried this one but the animation did not show at all see code:
selectAnim.removeActionForKey(ANIM_SELECT)
let node = SKNode()
let action = SKAction.repeatActionForever( SKAction.animateWithTextures(WBTextures.Select(), timePerFrame: 0.33))
node.position = point
node.runAction(action, withKey: ANIM_SELECT)
selecAnim.addChild(node)
Do I miss the trivial solution or witch one is the best or do one of you please have a better solution.
In a space shooter, I add enemies through a separate LUA file. These enemies have timers that create shots. When changing scenes, I want to remove all instances of enemies, stop their timers and remove all shots.
I have been able to remove the individual enemies by adding them to the scene's display group, but I can't do that with the timers or the shots.
How do I do this?
While creating a timer, just do as follows:
declare the timer at the top of you scene to get it a global scope on the scene, as:
local timer_1
Then use the timer as:
timer_1 = timer.performWithDelay(1000,myFunction,-1)
Then you can stop it as:
if(timer_1)then
timer.cancel(timer_1)
end
Keep coding.................. :)
What i would do (and that's how i handle this kind of issue in my game actually) is create a table to keep track of the enemies, then make it so enemies are object oriented classes owning both the timers and the shots.
Example:
You could create an 'enemy' class (local myEnemy) which has an internal timer (myEnemy.timerID) and an internal table of shots fired (myEnemy.shots).
Even better, add a 'destroy' method to the enemy (myEnemy.destroy()) that stops the timers and destroys the shot, then when you change scene you just have to iterate through your table, call the destroy method on each enemy, and timers / shots will be destroyed automatically :)
I don't know if your code is object oriented already but in this kind of case it makes things a lot easier :)
Let me know if you need anymore info
Cheers
i keep seeing these methods,
– dynamicAnimatorDidPause: required method
– dynamicAnimatorWillResume: required method
But i've not found a way to call them. Ive set up an animator and called <UIDynamicAnimatorDelegate> in the .h, but I cannot seem to call pause on the self.animator for some reason.
Anyone have any tips for me?
Thanks!
Those are delegate methods, which means that you don't call them, they get called for you. You implement a delegate to get informed about certain events
The dynamic animator pauses by itself when all movement stops. Try adding a gravity effect with no collision boundaries. The animator should pause when all dynamic items fall offscreen.