Friday, 30 September 2011

Not that easy to create a "flight control" type game as first thought

I was reading this article by Mike Nachbaur which was quite amazing. From short video below you can see the car running on the track.

Demo Video:


This reminds me of the Starter Kit - Line Drawing Game and thought I can just extend the idea a bit and create some sort of prototype quickly. As looks like the only difference is: Mike's demo has the race track hard coded. All I have to do is merge it with some "touch" code, right?

Wrong! May be it's just I am not up to that level yet, as after a few tests, it's definitely not as easy as I first thought!

At first, spent some time studying "bezier curve" as Mike's code used lots of those curves to draw the race track. Later realise it's not required as can achieve same result using straight lines.

Also did some research and found a few other resources on the net, specially this article which talks about setting up the path in touchesBegan and touchesMoved.

With the following code, I was able to freely draw some line and make the car follow the path (Note: car image from Mike's project). Sounds like a good start?

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch) {
        thePath = CGPathCreateMutable();
        CGPoint tapPoint = [touch locationInView:self.view];
        CGPathMoveToPoint(thePath, NULL, tapPoint.x, tapPoint.y);
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    if (touch) {
        CGPoint tapPoint = [touch locationInView:self.view];
        CGPathAddLineToPoint(thePath, NULL, tapPoint.x, tapPoint.y);   
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    
    CAShapeLayer *centerline = [CAShapeLayer layer];
centerline.path = thePath;
centerline.strokeColor = [UIColor whiteColor].CGColor;
centerline.fillColor = [UIColor clearColor].CGColor;
centerline.lineWidth = 2.0;
centerline.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:6], [NSNumber numberWithInt:2], nil];
[self.view.layer addSublayer:centerline];
    
    CALayer *car = [CALayer layer];
car.bounds = CGRectMake(0, 0, 44.0, 20.0);
car.position = CGPointMake(0, 0);
car.contents = (id)([UIImage imageNamed:@"carmodel.png"].CGImage);
[self.view.layer addSublayer:car];
    
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.path = thePath;
anim.rotationMode = kCAAnimationRotateAuto;
anim.repeatCount = 1;
anim.duration = 5;
    anim.removedOnCompletion = YES;
    anim.calculationMode = kCAAnimationPaced; // For constant velocity animation along the path
    
[car addAnimation:anim forKey:@"race"];
    
    CGPathRelease(thePath);
    thePath=nil;
}

Demo of my test project:


However after that I found quite a few problems. For example: using CAKeyframeAnimation you can only specify a "duration" for it to finish running through the whole path. As the path length changes all the time, it's impossible to control that. So if the user draws a longer path, it will run in faster speed...

Also found that when the image is moving as part of CAKeyframeAnimation, you can't "touch" or "move" it any more until the animation ends!

So, based on what I found so far, it's not that easy at all!

[Update 13/May/2014]
Please see line drawing tutorial on Ray Wenderich site for more details about how to create a line drawing game using Sprite Kit.

No comments:

Post a Comment