tags:

views:

235

answers:

2

This community has been tremendous help for me in many respects. First time question (for me), and it's an easy one. I'm working through the iPhone SDK learning curve, at a good rate... but every once in a while, I come across a problem that, despite it's simplicity, is easier to ask and work on something else, then to spend another hour on reading.

I have a 2D game where a vehicle is moving around on the surface rotating to face the direction of travel. I've determined that Core Animation is my best approach. The vehicle is an image. It's interactive to user input (touch).

Am I on the right track? UIView (to act as Responder) containing a CALayer tree that includes the image (from a file). The current file is a GIF. It made it easy to make the frame transparent, leaving only the vehicle image.

From the UIView subclass, how do I load the gif image into a layer?

Sounds simple, so I thought...

Cheers.

A: 

Is there a reason you can't simply subclass UIImageView to handle your touch methods? It would seem to me that instantiating an image view with your image and having the overridden UIResponder methods handle where the vehicle is moving and whatever else you need would be a lot easier than manually managing your CALayer tree.

You can do this with something like the following:

UIImage *vehicleImage = [UIImage imageNamed:@"vehicle.gif"];
VehicleImageView *vehicleView = [[[VehicleImageView alloc]
                                  initWithImage:vehicleImage] autorelease];

Then have VehicleImageView subclass UIImageView:

@interface VehicleImageView : UIImageView
// Your stuff
@end

@implementation VehicleImageView
// Your stuff

// UIResponder methods
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    // Custom implementation
}

// Other touch methods...
@end

You do seem to be on the right track, though, in that you do need a UIResponder somewhere in your vehicle's view/view hierarchy for touch methods.

More info:

Tim
I've looked into simply using a UIImageView and made assumptions to its limitations. The need for CA (to me) came from this requirement:The vehicle travels from CGPoint to CGPoint while it's "towing" other vehicles (like a train).When arriving to a waypoint, it can't simply turn and point to the next... it needs to calculate an arc to track until its bearing is lined up with the next waypoint... to which it travels. This ensures that the "trailing" vehicles don't "jack-knife".I don't know if UIViews can cater to this type of motion. THIS was the reason for me to look into the CA/CG APIs.
Serge
Hm. You could probably look into the Quartz 2D Bezier curve functionality available on the iPhone, but you're right - I'm not sure that UIViews support that kind of transition natively (I'm not that deeply versed in Core Animation or Quartz). I'm sure you could do the math on your own and just animate changes to the view's animatable properties, but it's probably less trouble to look into the Core Animation/Graphics APIs.
Tim
A: 

You're on the right track with Core Animation. CAKeyFrameAnimation has a path property which you'll use extensively. The following sample code (untested) uses straight line paths, but it's also possible to use curved paths:

UIImage *carImage = [UIImage imageNamed:@"car.png"];
carView = [[UIImageView alloc] initWithImage:carImage];

[mapView addSubview:carView];

CAKeyframeAnimation *carAnimation = [CAKeyframeAnimation 
    animationWithKeyPath:@"position"];

carAnimation.duration = 5.0;

// keep the car at a constant velocity
carAnimation.calculationMode = kCAAnimationPaced;

// Rotate car relative to path
carAnimation.rotationMode = kCAAnimationRotateAuto;

// Keep the final animation
carAnimation.fillMode = kCAFillModeForwards;
carAnimation.removedOnCompletion = NO;

CGMutablePathRef carPath = CGPathCreateMutable();
CGPathMoveToPoint(carPath, NULL, 0.0, 0.0);

CGPathAddLineToPoint(carPath, NULL, 100.0, 100.0);
CGPathAddLineToPoint(carPath, NULL, 100.0, 200.0);
CGPathAddLineToPoint(carPath, NULL, 200.0, 100.0);

carAnimation.path = carPath;
CGPathRelease(carPath);

[carView.layer addAnimation:carAnimation forKey:@"carAnimation"];
Nathan de Vries
That certainly helped, and it tests ok. It also gave me a little direction into reading up on QuartzCore. Thanks for the help!
Serge