Hi all can anyone help me out with the solution to this problem...
I have a project where I have NSTimer fire about 20 times a sec and thus using only one image(loaded programatically)produces the same image on the iPhone screen about twenty times in a second and these images fall from the top of the screen to the bottom where they are removed(more or less simulating rain fall or rain droplets).
My problem is that looking at the animation, I noticed that there are very small delays and which looks like a break, pause or small vibrations. Thus the flow isn't smooth.
Can anyone help me with the solution please.
Thanks in advance
You can check the CADisplayLink class.
Just because you ask for a timer in the UI run loop to go off at a certain rate, doesn't mean you will get called at exactly that rate or at evenly spaced intervals. You should check the time and the elapsed time "dt" inside each timer callback, and change your animation position, y + dy * dt, etc., accordingly.
Timer's arn't designed to be used for animation.
The best thing to do, is to have a thread running in an infinite loop, where you check if it's time to animate again, or just always animate (giving you a higher frame rate), but using the time elapsed as a reference for the state you are drawing.
You really shouldn't be using a timer for this. Instead you should be using the built in UIView animation methods:
animateWithDuration:animations:
animateWithDuration:animations:completion:
animateWithDuration:delay:options:animations:completion:
Related
I'm just starting to play about in Scratch...
I seem to have a sprite of a cat with two 'costumes', which I guess are like frames.
I made this sequence:
...but when I click the green flag the cat moves to the right but the costumes don't switch.
If I make a simpler sequence:
...and manually change the costume in the drop-down then the costume does change.
What is the limitation here?
This is by design. By default, loops have a built-in delay of about 1/30 second. (There are ways to eliminate that delay, but that is off-topic here.) This was done to help inexperienced programmers witness the effect of a loop; possibly also to make execution speed more consistent (regardless of client's CPU power).
In your case, that means costume2 will be visible for 1/30 second before switching back to costume1.
Costume1 on the other hand, is instantly followed up by costume2.
Consequently, you will only see costume2.
There are various ways to fix that.
Change your script to repeat 5 { move 10 steps; next costume; } This gives both costumes an implicit 1/30 second delay. If this is still too short, add a delay (wait ... seconds). Note: next costume wraps around, so assuming the sprite has 2 costumes, it will flip back and forth between costume1 and costume2.
Too jerky? Use glide ... secs to ... instead of 'move and wait'.
Or just take smaller steps; swap costume once every few steps.
Make two separate scripts running in parallel, one for the movement, the other for switching costumes. That makes it easier to specify a different delay for each.
Try using a [wait] block: the change between costumes may be so fast that it seems like it is walking without changing costumes...
I'm repeatedly shrinking an image (and then render it to a new full sized image) by a small amount, and the result is that a stripe down the middle is not being shrunk. I'm assuming this has to do with the resize method cocos2d uses. If I increase the amount I scale down the image by the resize is too fast, and if I decrease the shrink size the bar down the middle gets even bigger! the following code is called 60 times a second. the picture below shows the result! So.. any suggestions on how to get rid of the bar?
[mySprite setScaleX:rtt.scaleX - .05];
I wasn't sure quite what you meant, but did you mean you're calling this line 60 times a second?
[mySprite setScaleX:rtt.scaleX - .05];
If so then your sprite's scale will become negative in a third of a second...
Every time you manipulate an image, you lose information.
A better approach would be to always resize from the original, and just change the resize amount each time, rather than continually resizing the result of the last resize operation.
I'm new to cocos2d engine, so hope this helps. If your shrinking an image, I would suggest using CCScaleBy. You can try something like this...
CCScaleBy *yourSprite = [CCScaleBy actionWithDuration: .01 scaleX: .95 scaleY: 1.0f];
This will scale your sprite down by 5% each time its called. Then you can have it replaced by the new image when it reaches what you would consider its smallest pixel point. The duration may need to be played with, but thought this would help.
SO I have a label labelscore and it increase of 1000 every time there is a collision between two images. I would like to see labelscore increase of 1000 like an animated score, a running score. How can I do this?
You can use an NSTimer to call a routine every 16.7 to 50 milliseconds. In the routine increment some value and update it to the label. Rinse and repeat until this value is equal to the score. This is the basic technique of an animation game loop.
You have the option to use a repeating timer and invalidate it when you're done with it. Or setting single-shot timers within each update routine for the next iteration. You could also use CADisplayLink as an alternative to NSTimer, which may provide smoother animation under some conditions.
I have, most of the time, 50+ FPS, but when I load resources(background tread) it drops to 30 FPS. I want to have constant FPS, 30 or even 20, it's not a problem for me. What is the best way to make FPS constant?
You should be using time-based redrawing, instead of frame based drawing. Michael Daley's book has some excellent info on this.
Also, try loading as many of your resources as possible in a spritesheet.
Not really sure if there is an established method, but frame rate in this case is the frequency at which you redraw. 20 FPS is a 50 millisecond redraw rate. One method would be to only redraw if the time between the last redraw and now is >=50 ms.
I want to do some sophisticated animations. But I only know how to animate a block of changes. Is there a way to chain animations, so that I could for example make changes A -> B -> C -> D -> E -> F (and so on), while the core-animation waits until each animation has finished and then proceeds to the next one?
In particular, I want to do this: I have an UIImageView that shows a cube.
Phase 1) Cube is flat on the floor
Phase 2) Cube rotates slightly to left, while the rotation origin is in bottom left.
Phase 3) Cube rotates slightly to right, while the rotation origin is in the bottom right.
These phases repeat 10 times, and stop at Phase 1). Also, the wiggling becomes lesser with time.
I know how to animate ONE change in a block, but how could I do such a repeating-thing with some sophisticated code in between? It's not the same thing over time. It changes, since the wiggling becomes lesser and lesser until it stops.
Assuming you're using UIView animation...
You can provide an animation 'stopped' method that gets called when an animation is actually finished (check out setAnimationDelegate). So you can have an array of animations queued up and ready to go. Set the delegate then kick off the first animation. When it ends it calls the setAnimationDidStopSelector method (making sure to check the finished flag to make sure it's really done and not just paused). You can also pass along an animation context which could be the index in your queue of animations. It can also be a data structure that contains counters so you can adjust the animation values through each cycle.
So then it's just a matter of waiting for one to be done then kicking off the next one taken off the queue.
The same method applies if you're using other types of animation. You just need to set up your data structures so it knows what to do after each one ends.
You'll need to setup an animation delegate inside of your animation blocks. See setAnimationDelegate in the UIView documentation for all the details.
In essence your delegate can be notified whenever an animation ends. Use the context parameter to determine what step in your animation is currently ending (Phase 1, Phase 2, etc)
This strategy should allow you to chain together as many animation blocks as you want.
I think the answer to your question is that you need to get more specification on what you want to do. You clearly have an idea in mind, but more specification of details will help you answer your own question.