I want to animate a 20 wagon train in iphone. The train will move left to right. Each wagon will have a different animation. I was confused how to do it. Because the images are large and 20 images at one time would cause memory warnings.
Can anyone suggest how to go about it. Should I use cocos2d for this?
Thanks!
I would do that in cocos2d.
I would create a 'Wagon'-class and then start by initiate two of them (just because I think that two wagons will fill the screen). And then start moving the wagons. Each time a wagon is completely out of the screen I would release it. When it's time for the next wagon I would initiate that and so on.
How many frames does the animations have, and how big are they? Maybe you'll have to make one atlas per wagon. You can always call:
[[CCTextureCache sharedTextureCache] removeUnusedTextures];
and:
[[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
Cocos2D is best!
Create sprites, set actions to it and IMHO!!!
If you want to do using UIImageViews, look for
UIImageView.animationImages
UIImageView.animationDuration
UIImageView.animationRepeatCount
and
[UIView beginAnimations:(NSString *)animationID context:(void *)context];
[UIView setAnimationDuration:(NSTimeInterval)duration]
// make the changes in your view which you want to occur in given duration
[UIView commitAnimations];
But again, this will definitely give you a hard time, better go for Cocos2D.
Related
I have a UITextView that changes it's frame with the animateWithDuration:animations method:
[UIView animateWithDuration:1.5 animations:^{
[_textView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - keyboardSize.height-25)];
}];
Is there any callback that helps me track the height of the UITextView as it animates?
There is no accurate way.
That's because the frame is just set directly. The animation takes care of the transition, but actually there is no transition.
There are some ways of estimating what is the current frame size and for me, the best is the simple math solution using a timer, when the animation started and the animation duration.
But, again, it's probably for the best if you just go another way, as this is certainly going to impact on your code cost and precision.
It's my first post and I don't really know anything that well, just learning and trying to help.
This depends on what you want to do with this thing.
If you want somehow accurate information about your frame, use the presentationLayer. This is a semi-accurate representation of what's actually on the screen. Note that this is in the coordinates of the view (bounds), so you need to convert it to the superview's coordinate system to get the current frame.
CGRect currentTextViewFrame = [_textView.superview convertRect:[_textView.layer.presentationLayer frame] fromView:_textView];
Note however this will be about one drawing loop or more off. If you are trying to base another animation off this it may be problematic and can cause flickering or other delay-induced effects. Also, at least the official documentation says this may not always be very fast and you may want to make the animation yourself if you need this information often due to performance reasons.
[_textView.layer.presentationLayer frame].size.height;
Credit belongs to this anwser.
Im trying to make an animation of falling object that goes up when you touch the screen. That is not a problem if i want to use a linear velocity for this object, but i would better like it if it accelerated towards ground and when user touches screen it starts accelerating to the opposite direction. So lets suppose we have an object that goes 10px/s towards ground and when user touches screen i want it to have a = -5px/s^2 which means that even after touching screen, the object would still go down for another 2 seconds. Any idea how to do this in a "nice way" (right now im rewriting UIImageViews.frame every time with new CGRect but thats not really good way to do it i guess)?
Thanks
You can always use UIView animations:
[UIView animateWithDuration:1.0
delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
// put the co-ordinates you want your object to FINISH on in here
}
completion:^(BOOL finished){
}];
Any idea how to do this in a "nice way" (right now im rewriting
UIImageViews.frame every time with new CGRect but thats not really
good way to do it i guess)?
Use Core Animation. It's very easy to get started, and very powerful once you've gotten started. You can specify your own timing function, so you can give the appearance of acceleration. There's no reason for you to redraw your image view manually... Core Animation will do this for you more easily, and better.
Hope there are some GLKViewController experts out there because I have some problems :)
Just a quick description of my app. I have a UINavigationController in which I push different screens.
At some point, I get to my game screen which is a subclass of UINavigationController. In this screen, in viewDidLoad I manually create a EAGLContext, GLKView and instantiate a new GLKViewController (to handle my update&draw calls).
I am setting a preferred fps of 30.
The problem is that the first 3-4 update calls come with the correct DT, but then I have 2-3 frames with 1 second between them. I measure the DT using controller.timeSinceLastUpdate.
So I get like:
dt=0.33
dt=0.33
dt=0.33
dt=1.07
dt=1.05
dt=0.33
dt=0.33
After this, I get valid only DT times. I have no idea why those frames have that kind of delay. I measured the time it takes me in the update & draw method, and it's nowhere near 1 second.
Also, I'm not loading any textures/creating any geometry. Everything is done at loading since it is a rather small game.
Also, if I pop the game screen controller and then push back another instance of the game screen, this new GLKViewController will only call my update method aproximately every 1 second.
Did anybody have a problem with the framerate when using GLKViewController?
Thanks,
The problem is that you don't know what else the device is doing between your refreshes :)
You might only spent 0.1s working on the next frame but if there is a memory warning then other bits of your app will also take time to process. I guess that the gl controller will do it's best to keep to the preferred frame rate but if lots is going on in the background then there's not much it can do about it.
As long as you make sure that your code is rendering as fast as possible and isn't spiking in the same way as the framerate then it's not your render path. From your question it sounds like you've already tested that.
The other thing you might want to do is to watch out for other notifications that might be passed into your app (i.e. memory warnings).
Finally, is there a pattern to the slow frames - do they coincide with a new image being loaded or a file access? Have you done as much as possible beforehand? EDIT - rereading your question makes me think that you've already done this, sorry!
Sorry I can't be any more use :(
Ok, so I finally figured it out. It turns out that it's not even related to the GLKViewController (surprise surprise!).
It had something to do with the way I'm displaying the game screen view controller, like this:
GameAreaViewController* gameController = [[GameAreaViewController alloc] init];
[UIView beginAnimations:#"animation" context:nil];
[self.navigationController pushViewController: gameController animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView setAnimationDuration:0.7f];
[UIView commitAnimations];
SAFE_DEL(gameController);
If I use an animation duration of 0.3f, then I don't get any lag. At 0.5f sometimes I get it and at 0.7 I was always getting it.
I would love if someone could give me a short breakdown on what's the best way in terms of memory usage for animating UIImageViews (translation, without sprites).
More specifically, I need to animate multiple objects on screen at the same time (let's say up to 15-20);
Also, I have to be able to interrupt the animation due to collision between some of these objects.
The kind of animation I need is a simple translation. If it's possible, I would concat this translation with rotations and scalings (secondary).
I'd prefer not to use OpenGL because I think that this kind ow work doesn't require it.
Thanks guys.
CoreAnimation can do this handily. The code below will animate the translation of a view. It's also possible to stop the animation half-way and get its current state for feeding into your collision detection algorithm, but you'll have to read up a bit on Core Animation for that.
[UIView beginAnimations:nil context:nil];
view.center = CGPointMake (view.center.x + 50, view.center.y);
[UIView commitAnimations];
I have a block of UIView animation code that looks like this:
[UIView beginAnimations:#"pushView" context:nil];
[UIView setAnimationDelay:0];
[UIView setAnimationDuration:.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:#selector(animationWillStart)];
view.frame = CGRectMake(0, 0, 320, 416);
[UIView commitAnimations];
The code basically mimics the animation of a ModalView presentation and is tied to a button on my interface. When the button is pressed, I get a long (.5 sec) delay (on iPod Touch...twice as fast on iPhone 3GS) before the animationWillStart: actually gets called. My app has lots going on besides this, but I've timed various points of my code and the delay definitely occurs at this block. In other words, a timestamp immediately before this code block and a timestamp when animationWillStart: gets called shows a .5 sec difference.
I'm not too experienced with Core Animation and I'm just trying to figure out what the cause of the delay is...Memory use is stable when the animation starts and CoreAnimation FPS seems to be fine in Instruments. The view that gets animated does have upwards of 20 total subviews, but if that were the issue wouldn't it cause choppiness after the animation starts, rather than before? Any ideas?
Try it with a single subview or with no subviews at all to make sure the delay is not caused by so many children.
Profile the code in Instruments to see where exactly the code lags. You might get down to some internal Core Animation function call that will hint you what’s going on.
Try the code without the “lot that’s going on” to make sure you’re not stepping on Core Animation’s toes with your other code.
Or, in short: experiment and measure, because conjectures seldom work when optimizing.
In your pasted block, you specify the selector animationWillStart (no colon), but later in your question, you refer to animationWillStart: (with colon). These selectors are not equivalent, so is it possible that your intended selector is never being called on account of this animation, and is being called 0.5 seconds later on account of some other animation?