IOS - multiple images going slowly upward animation - ios

i am new to IOS programming. what i want is i want to show multiple images and then they go upward continuously and then repeat again and again in sort of a loop. how can i do this ?
i have total 8 images which i want to show like this
i don't know how can i add 8 images and then they go upward direction verically continuously repeating. please help me in this. if there is any tutorial related to that and then please share

You should not do it this way. If you make your step value small enough for smooth movement it will be too slow.
You want to use UIView animation. Take a look at the the method animateWithDuration:animations: (and it's variations)
Your code might look like this:
#define K_AMOUNT_TO_MOVE
-(void)moveImages
{
[UIView animateWithDuration: 2.0
animations: ^
{
for(int i=0;i<images.count;i++)
{
UIImageView *MyImage = images[i];
MyImage.center = CGPointMake (MyImage.center.x, MyImage.center.y- K_AMOUNT_TO_MOVE);
}
}
];
}
There are variations on that basic method that take options that will auto-reverse the animation, make it repeat, change the timing to linear instead of the default ease-in, ease-out, etc. Take a look at the method animateWithDuration:delay:options:animations:completion: in the Xcode documentation.

Related

How to use timing function for slowly speed up scaling function with SpriteKit

I have a sprite that I'm trying to scale out. I'm using the scaleTo skaction to do this... I want it to slowly ease in. And this was my initial solution:
let scal = SKAction.scale(by: 100, duration: 10)
scal.timingMode = SKActionTimingMode.easeIn
The problem is that as it scales out, since it is scaling out so much it appears to slow down. So I need to use the timeingFunction in order to write a custom easeIn for the action.
https://youtu.be/CE-B27gSXJI
In the video, you can see that it appears that it starts off fast and slows down. It only appears this way because I'm going a scale, and the bigger you go the slower it will appear...
Problem: I have no clue how to do this with the timing function, and I haven't been able to find a good source to use as a reference?
Any help would be appreciated and thank you!!!
Have a look at the Sprite Kit Utils from Ray Wenderlich for an example on how one can write an easing function: https://github.com/raywenderlich/SKTUtils Specifically, look at SKTTimingFunctions.swift and SKTEffects.swift.
There are some neat functions to give you better control of your easing. You might even want to use the easing functions that are defined there without changes, most of them work pretty well. For reference on how each easing function behaves, you can look at http://easings.net
Hope this helps!
I'm going to mark the answer above correct but this ended up being my solution and I wanted to share as it is simple to implement.
I don't fully understand how this works but when you specify the function for the timingFunction you have to include "t in". Then you can use this t to manipulate the timing of the animation.
So if you look at the links above, you can get the desired affect by using what is contained in the functions in Ray's SKTTimingFunctions.swift.
The below code shows how I used it; my timing function starts of slow and then slowly picks up speed... Again see the links above and you can get an idea.
let scal = SKAction.scale(by: 100, duration: 10)
scal.timingFunction = { t in
return t*t*t*t*t
}

alternative to UIView setCenter

My app, which is a game, includes a CADisplayLink timer which calls a function that instructs about 20 calls to UIView setCenter: for the various objects on screen every frame.
Time profiling it, this accounts for about 30% of all activity in the game and drastically reduces performance on older devices (anything lower than 5th generation ipod touch or iphone).
Are there any lightweight, low-overhead alternatives I can use to move objects (specifically UIViews) around the screen every frame?
EDIT:
Just to clarify, the center property of these UIViews must be set EVERY FRAME. I have a number of tiles that represent the ground in my game. They zip across the screen, only to be replaced by new tiles. After fiddling with the code for a couple hours to change the UIViews to CAlayers, I have it working at absolutely no performance gain. There surely is a better way to do this.
Some code to give a general idea of what is going on:
for(Object* o in gameController.entities){
[o step:curTimeMS];
}
gameController is, as one would think, a class that takes care of the main game functions. It includes its list of entities, which are all the objects on-screen. The step method on each of these entities is a virtual function, so it is specific to each entity - the curTimeMS variable is simply a timestamp so the object can calculate its delta position. In essence, each entity updates its layer.position property every frame, moving it at an appropriate speed across the screen.
I would recommend SpriteKit. It is a very powerful game / 2d animation framework created by apple.. Cocos2D is also a very powerful framework of similar type. You can create a new SpriteKit game straight from XC
If you want to stay in house with just UIKit stuff, check out UIView block based animations. Here is the jist of it.
[UIView animateWithDuration:numberOfSecondsTakenToAnimate animations: ^{
// do you animation here. i.e.: move view frame, adjust color.
} completions: ^(BOOL complete) {
// when the animation is complete, code in this block is executed.
}];
I just remembered Core Graphics. It is used in tandem with UIViews to create simple 2d graphics and is very powerful and very fast. Here is the jist of that.
CGContextRef cntxt = UIGraphicsGetCurrentContext();
CGContextBeginPath(cntxt);
CGContextMoveToPoint(cntxt, <x>, <y>);
CGContextAddLineToPoint(cntxt, <x>, <y>);
CGContextClosePath(cntxt);
[[UIColor <color>] setFill];
[[UIColor <color>] setStroke];
CGContextDrawPath(cntxt, kCGPathFillStroke);
Note: things in < > are variables / values specified by you.
If you want to go all out, take the time to learn Open GL. Beware, I have heard that this is extremely hard to learn.
If you need performance, do not use UIView. It is not designed to be fast.
Instead, have a single UIView that takes up the whole screen, with a bunch of CALayer objects inside the one view. Move the layers around.
CALayer works by talking direct to the GPU, so it's very fast. Perhaps even faster than OpenGL. UIView is using CALayer internally so they both behave approximately the same. The only real difference is any change to the position of a CALayer will be animated by default. You can easily turn the animation off, although in a game you probably want animation.
Your other option, of course, is to use OpenGL. But that's a lot more work.
EDIT: here is some sample code for changing the position of a layer properly: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html#//apple_ref/doc/uid/TP40004514-CH3-SW8

How to move graphic in an arc path on iOS... as in a meter or clock face

This is the result of what I want to achieve:
(source: mouseaddict.com)
I have static images for my app, but i want to add motion to them.
Imagine a meter. It has a needle that is locked at the bottom (at 6:00 on a round-clock-style-face) and whose needle-top swivels from left to right in an arc. the arc (zero) starts with the needle pointed toward (roughly) the 9:30 position on a round-clock-style-face and the top-most part of that arc should end at roughly 2:30 on a round-clock-style-face.
I have several graphical elements 1) the round meter face (png) and 2) the verticaly oriented png file of a meter needle. I need to cause the needle to move within the round face in an arc'ing pattern.
So, assuming the two requirements above, what is the best way to swivel the needle within the meter using animation?
I have seen this: Speedometer -- but is this the best way? My main issue is that I want the needle locked at the bottom and move left-to-right only a small amount..as WELL as the fact that there is little (actually no) documentation on it. Things like "calculateDeviationAngle" are unexplained.
Also the Speedometer seems to move a large amount and the pivot point on that example would not work...(i dont think)
I would like to call this with a command like:
[self moveNeedleToPosition:degreeOrClockFaceNumber] and have it move from it's current position to a bit past the degreeOrClockFaceNumber and bounce back to rest at degreeOrClockFaceNumber.
TIA
I did the following: I broke the image up into several pieces. The outline (black) portion, the backgrounds and the needle. Each piece having the same exact "footprint" (shapes).
Assuming theImageView is the imageView for the needle (layered on top of the other two imageViews), I created the following function:
-(void) rotateNeedle:(UIImageView *)theImageView toAngle:(float) theAngle
{
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
theImageView.transform =CGAffineTransformMakeRotation((M_PI / 180) * (theAngle + 10));
}
completion:^(BOOL finished){
//
[UIView animateWithDuration:0.5
animations:^{
theImageView.transform = CGAffineTransformMakeRotation((M_PI / 180) * theAngle);
}];
}];
}
The first animation in the block performs the "shoot-past" portion of the animation...ie: moving 10 degrees past the actual value. The second animation in the completion block then "bounces" the needle back to the correct value. The speed of these animations create the physics effect. It works quite well for me.

How to keep iOS animation smooth with many subviews

I am trying out different looks of a little game I am writing to play with animation on iOS.
My goal is this to have a grid of tiles which based on gameplay changes the display of each tile to one of a set of images. I'd like each tile (up to 24x24) to flip around when its face changes. As the game progresses, more and more tiles need to be flipped at the same time. In the first implementation where I tried to flip them simultaneously the animation got very jerky.
I changed my approach to not flip them all at once, but just a few at a time, by scheduling the animation for each tile with a slightly increasing delay per tile, so that when say the 10th tile starts animating, the first one is already done. It takes little while longer for the whole process to finish, but also leads to a nice visual ripple-effect.
However, one problem remains: At the beginning of a game move, when the player picks a new color, it takes a few fractions of a second on the device, before the animation starts. This gets worse as the game progresses and more flips need to be scheduled per move, up to the point where the animation seems to hang and then completes almost instantly without any of the frames in between being actually discernible.
This is the code (in my UIView game grid subclass) that triggers the flipping of relevant tiles. (I removed an optimization that skips tiles, because it only matters in the early stages of the game).
float delay = 0.0f;
for (NSUInteger row=0; row<numRows; row++) {
for (NSUInteger col=0; col<numCols; col++) {
delay += 0.03f;
[self updateFlippingImageAtRow:row col:col delay:delay animated:YES];
}
}
The game grid view has an NSArray of tile subviews which are addressed using the row and col variables in the loop above.
updateFlippingImageAtRow:col:delay:animated is a method in my FlippingImageView (also a subclass of UIView) boils down to this (game logic omitted):
-(void)animateToShow:(UIImage*)image
duration:(NSTimeInterval)time
delay:(float)delay
completion:(void (^)(BOOL finished))completion
{
[UIView animateWithDuration:time
delay:delay
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:self
cache:YES];
self.frontImage = image;
}
completion:completion
];
}
Works fine, however, I conclude from the Instruments measuring which tells me that my time is spent in the animation block, that as the game goes on and the number of tiles to flip goes up, that the number of animations that get scheduled at the very beginning of the operation is a problem, and that the system then tries to catch up by dropping frames.
Any suggestions how to improve the performance of this? The exact timing of the animation is not really important.
You can think about doing this with CoreAnimation and CALayers instead of UIViews. It is incredebly powerful and optimized framework.
It's not an easy thing, you'll have to recode at least some of your classes (view hierarchy and hit tests are the first things that come to my mind), but it's worth a try and it's rather painless process, because CALayer is very similar to UIView.
Next step is OpenGL. It definitely can operate several hundreds of objects in realtime, but it requires much more work to do.
You might want to try using CoreAnimation instead. One way to do the flip animation would be:
Create a CABasicAnimation that animates the first half of the flip (rotation along the y axis).
In the delegate method animationDidStop:finished: you set the new image and then create a new animation that animates the second half.
You simply apply the animation to the layer property of your view.
Note that you can use setValue:forKey: to "annotate" an animation (remember what object the animation is about). When you add an animation to a layer it gets copied, not retained, so you can't identify it by simply comparing pointer values.

UIImage - maze type 2d grid - how to address each position programmatically?

What I am doing is very simple. I have a simple 2d Maze game - think puzzle game that I am working on. I am not needing to use OpenGL for this. I am wanting to use UIImage's. Imagine I have a wall tile (64x64 pixels) and I want to write code to duplicated this wall tile along the top and edges of the screen area- to in effect build a wall around the edges of the screen. play will take place inside this area. How would I go about doing this in code. From what I gather I would need to create a new UIImage each time I wanted to place a tile and move coordinates. Later on though, say I wanted to take the second tile along and replace it with say a bomb. Or maybe the 4th one along? My question really is.. in code how would I address this 2nd or 4th tile (when the number 2 or 4 could be random) and change its graphic? I hope I have explained this enough.. Also If I have updated some tiles, is there a call I should be making to hurry up the screen refresh so to speak?
As I understand, you can just create some UIImageView objects. Each one for one of your tiles. And then you'll be able to change frames with animation. For example. You have image you want to replace. I have no mac right now nearby, so, my code may not wark after just copy and paste)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5f];
[imageView setFrame:newFrame];
[UIView commitAnimations];
This code will move your image with animation.

Resources