I am building a simple ios gaming app where I have to move a few objects on screen, and these moving objects react to swipe gestures and change their direction based on that. I am not using spritekit or any other gaming framework for this, and the way I am moving the objects is by triggering an NSTimer that fires 60 times a second. I am not using any threads explicitly so I guess the timer is executed by the main thread ? The code block that the timer triggers updates the location of objects based on their speed (defined as pixels per time unit in x/y direction). It is working fine and I am almost at the end of my project, but while testing the app I've realized that although the movement of objects seem pretty good most of the times, however sometimes the movement is a little rough/patchy.
My question is that is it the right way to do something like this, how can I improve the performance ? will using something like GCD can help with the issue of jittery movement ? (I haven't looked into GCD in detail but I am willing to spend time on it if I know that will help)
Thanks for any help !
and the way I am moving the objects is by triggering an NSTimer that fires 60 times a second
I would recommend not doing that. Various forms of animation are built in (View animation, Layer animation, CADisplayLink, UIKit Dynamics), and of course there's always Sprite Kit. Use the tools you are given for this purpose. Don't reinvent the unicycle when you already have a Ducati at your disposal.
I am developing an IOS Chess app using SpriteKit in Swift2. While playing the game against computer player, human move is not displayed until computer thinking ends. After computer thinking ends, both (human move and computer move) moves are displayed together.
Expected functionality: Once human plays his/her move, the move must be displayed on screen. Only after displaying the human move, computer thinking must start.
I initially had the call to computer thinking logic inside touchesBegan function. It didn't work as expected. Then I moved the call into touchesEnded function. The issue remained. Now I have placed the call inside update function. The issue still remains.
I couldn't find an answer for this issue. Is there any away to address this?
Thanks,
ArtBajji
If the problem is that the "computer" reacts to quickly after a human move, you could use a dispatch_after block implemented in your touchesEnded.
let delay = 0 //time in seconds
dispatch_after(delay, dispatch_get_main_queue()) {
//computer starts thinking
}
How can I turn Fire animation from Timeline to ActionScript 3 Code?
If I use fire animation on timeline for my game, characters position and level details would reset.
Do you have any advice about how can I handle this issue?
My experience on flash is too low, sorry for this kind of question
Thanks
Make a Fire movieclip that contains all the fire timepline animation. Then simply call it's play() function to play it.
I need guidance in how to animate small 2d things such as, for example, a character that simply remains blinking. Are SpriteKit and cocos2d "too much" to implement this sort of things? I'm not planning to make a game, I just want to mix standard iOS controls with artwork performing simple animations like the mentioned, but maybe I'll need to make more elaborate animations in a near future (a character running, for example). Should I use Core Animation framework for this? Or maybe another and better alternative?
I'll support iOS 7.0+
Thanks in advance
Core Animation is best here, since you're specifically wanting to cause a user interface element to blink (rather than building a game with a board and sprites). Use Core Animation to set up a repeating animation to change its alpha value.
Use of timings (like Ease-In-Ease-Out) can even add a "Mac sleep light" breathing effect. Using this versus iZabala's (admittedly functional) approach means you're letting the system decide if every single frame of this animation can be run in a given moment. If it's too busy to animate and keep the UI responsive, Core Animation will drop frames as needed.
You can also group animations (so if you have a "bank of buttons with blinking indicators", you can run them all in the same animation group with the same timing so they don't get out of sync with each other and look like a sparkly Christmas tree).
You can use the class NSTimer to call a function each X time. For example, if you want something to blink you can do something like this:
NSTimer* myTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
selector: #selector(blink) userInfo: nil repeats: YES];
-(void) blink { //supose that myObject is an UIView in this example
if(myObject.hidden){
myObject.hidden=NO;
}
else {
myObject.hidden=YES;
}
}
You can do the same using position to move, alpha or transparency to fade out, fade in... play with the properties the object has.
This seems like such a basic concept but there is really no good answer.
I currently have a pretty basic setup, in my game's scene, I have an enum gameState which is currently either inGame or gamePaused.
I have my button set up, and I have it so pressing simply toggles gameState.
Then, to make it work, I have two separate update methods: One for when gamePaused, one for when inGame.
This works for 95% of my game, as the updates in my game can be pretty readily started and stopped without any issues. There are some issues I cannot tackle though.
First and foremost are actions. I use SKActions for a bit of my project (some movement, scaling, fading...) and this method does NOT pause them. This can be catastrophic in certain points. Secondly, this doesn't handle particles, physics, and a few other things that are not directly associated to my update methods.
The only clue I have is self.view.paused = YES, but that isn't going to work either.
First off, this DOES fix my actions, particles, and physics problem... kinda. But This question suggests that SKActions aren't actually PAUSED by this, but actually STOPPED completely. Is this true? If it is, then it won't work smoothly either because my actions are thrown out of whack.
Also, pausing the view seems to do what it says: stop everything. EVERYTHING. Newbie question here, but how am I supposed to get any code to run at that point? It's all cut off. Is this where I need subViews? I have never used a subView yet, but it sounds like its what I want in this case.
Simply put, there are a lot of unanswered questions for me, and I don't know how to proceed. I'm hoping there's some 'standard procedure' for pausing in Sprite Kit, but with pausing the view halting actions I truly have no idea where to proceed.
Should I move away from using actions? Is my idea of a pause subView sound?
I don't want to babble, all I want to know is how you go about pausing in your average Sprite Kit project. Additional info provided upon request.
Pausing a node will pause (not stop) the node's actions, and i suppose pause will also be applied to all children of the paused node in the same way. All other unpaused nodes will continue to run their actions to completion.
You should have a "game layer" node with all game nodes in them that you want to pause, and then just pause that "game layer" node. Then have a "pause game menu" node where you add all the pause menu stuff you need which will continue to function normally even if the game layer is paused.
Be very sure you do not use performSelector or NSTimer or GCD or any other scheduling methods besides actions or the scene's update: method because those will not adhere to a node's paused state.
Pausing the view effectively freezes everything in it, pausing the scene according to some will not pause the update: calls - but I have not verified this myself. If this were the case you can always check inside the update method whether a given node that you send a message to is paused and if so, decide not to send certain messages to that node.
I just called a map function on all children of the scene and set the paused property to true
self.children.map{($0 as SKNode).paused = false}
By setting it to true you can easily undo the freeze.
EDIT:
Better use a for-loop to iterate over the children.
for node in self.children as [SKNode] {
node.paused = false
}
I can tell you what I did in my game:
Pause the SKView on -applicationWillResignActive: (or equivalent, using NSNotifications),
Un-pause the SKView on -applicationDidBecomeActive: (or equivalent, using NSNotifications),
For the actual game scene only, I set a boolean flag _isPaused when resigning active, and if it is true I just skip the -update: method (frame updates). (I also show the "paused" menu when the user resumes the app).
...But my game is a simple puzzle game, and there's no long actions that should continue past the pause/resume. I can not confirm right now that all actions are aborted, but I think it's not the case.
I also used self.children.map{($0 as SKNode).paused = false} and it does work if you create a var layer of type SKSpriteNode and add it on top of the scene. But I also have an NSTimer I'm using to spawn sprites on the scene. Everything currently on the scene is paused, but sprites keep appearing and moving across the screen. It is not pausing the spawning.
I tried pausing the NSTimer when I call the above code by setting repeats to false, then setting it to true when I remove the layer but it doesn't work. I also tried self.scene?.view?.paused = true but that freezes everything and the layer I create does not even appear onscreen.
You need to set the delegate for the View!
func PauseGame(){
self.scene.view.paused = true
}
fun playGame(){
self.scene.pause = false
}
This function is work perfectly if you are not using the NSTimer to call a function. If you use NSTimer your view will pause perfectly but when you play the game again by play game functionality you see that all the functions that use the NSTimer function that runs in the back end and your screen full with your sprite-kits. So when you use NSTimer in the function you have to first pause the NSTimer functions also after that this function work perfectly.
//For Pause
func pauseGame() {
scene?.view?.paused = true
}
//For play.
func playGame() {
scene?.view?.paused = false
}