rendered paste body// This code was written by Lucas Newman and is released into the public domain.
#import "FlipACoinApp.h"
#import "FCCoinView.h"
@implementation FlipACoinApp
// UIApplication
- (void)applicationDidFinishLaunching:(GSEventRef)event;
{
// create the content view
window = [[UIWindow alloc] initWithContentRect:[UIHardware fullScreenApplicationContentRect]];
[window setContentView:[[UIView alloc] initWithFrame:[window bounds]]];
[[window contentView] setBackgroundColor:(CGColorRef)[(id)GSColorCreateWithDeviceWhite(0.0, 1.0) autorelease]];
// enable perspective transforms
LKTransform sublayerTransform = LKTransformIdentity;
sublayerTransform.m34 = 1.0 / -420.0;
[[(UIView *)[window contentView] _layer] setSublayerTransform:sublayerTransform];
// create the coin view
coinView = [[[FCCoinView alloc] initWithFrame:CGRectInset([window bounds], 60.0, 60.0)] autorelease];
[coinView setBackgroundColor:(CGColorRef)[(id)GSColorCreateWithDeviceWhite(0.0, 0.0) autorelease]];
[[window contentView] addSubview:coinView];
[window orderFront:nil];
[window makeKey:nil];
// create heads and tails images for animating
CGContextRef bitmapContext = (CGContextRef)[(id)CGBitmapContextCreate(NULL, CGRectGetWidth([coinView bounds]), CGRectGetHeight([coinView bounds]), 8, 0, (CGColorSpaceRef)[(id)CGColorSpaceCreateDeviceRGB() autorelease], kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst) autorelease];
[self drawCoinInRect:CGContextGetClipBoundingBox(bitmapContext) context:bitmapContext heads:YES];
headsImage = CGBitmapContextCreateImage(bitmapContext);
CGContextClearRect(bitmapContext, CGContextGetClipBoundingBox(bitmapContext));
[self drawCoinInRect:CGContextGetClipBoundingBox(bitmapContext) context:bitmapContext heads:NO];
tailsImage = CGBitmapContextCreateImage(bitmapContext);
// add sunbeams layer ahead of time, make it invisible for now
static id sunbeamsImageRef;
if (!sunbeamsImageRef)
sunbeamsImageRef = [(id)[[UIImage applicationImageNamed:@"sunbeams.png"] imageRef] retain];
sunbeamsView = [[[UIView alloc] initWithFrame:CGRectMake(-(600.0 - CGRectGetWidth([window bounds])) / 2.0, -(600.0 - CGRectGetHeight([window bounds])) / 2.0, 600, 600)] autorelease]; // retained by superview
[[sunbeamsView _layer] setContents:sunbeamsImageRef];
[[sunbeamsView _layer] setDelegate:self];
[[sunbeamsView _layer] setOpacity:0.0];
[[window contentView] addSubview:sunbeamsView];
}
- (void)applicationWillTerminate;
{
[stablizedDate release];
CFRelease(headsImage);
CFRelease(tailsImage);
[window release];
}
- (void)acceleratedInX:(float)x Y:(float)y Z:(float)z;
{
float xRotationAngle = asinf(z / sqrtf(y * y + z * z)); // -M_PI / 2.0 to M_PI / 2.0
if (!isStabilized && xRotationAngle < 0.0 && fabsf(xRotationAngle + (M_PI / 2.0)) < (20.0 / 180.0 * M_PI)) { // within 20 degrees of flat
if (!stablizedDate)
stablizedDate = [[NSDate date] retain];
else if ([[NSDate date] timeIntervalSinceDate:stablizedDate] > 0.25)
isStabilized = YES;
} else if (!isStabilized) {
[stablizedDate autorelease];
stablizedDate = nil;
} else if (isStabilized && (xRotationAngle > 0.0 || fabsf(xRotationAngle + (M_PI / 2.0)) > (20.0 / 180.0 * M_PI))) {
isStabilized = NO;
if (fabsf(xRotationAngle) < (70.0 / 180.0 * M_PI)) // within 70 degrees of straight up
[coinView flip];
}
}
// NSObject (LKLayerDelegate)
- (id)actionForLayer:(LKLayer *)layer forKey:(NSString *)key;
{
if ([key isEqualToString:@"opacity"]) {
LKBasicAnimation *opacityAnimation = [LKBasicAnimation animationWithKeyPath:key];
[opacityAnimation setTimingFunction:[LKTimingFunction functionWithName:@"easeInEaseOut"]];
[opacityAnimation setDuration:1.0];
return opacityAnimation;
} else if ([key isEqualToString:@"transform"]) {
LKBasicAnimation *transformAnimation = [LKBasicAnimation animationWithKeyPath:key];
[transformAnimation setTimingFunction:[LKTimingFunction functionWithName:@"easeInEaseOut"]];
[transformAnimation setDuration:1.0];
return transformAnimation;
} else
return (id)[NSNull null]; // we aren't an NSView subclass
}
// API
- (void)drawCoinInRect:(CGRect)rect context:(CGContextRef)context heads:(BOOL)heads;
{
CGRect coinRect = CGRectInset(rect, 0.0, (CGRectGetHeight(rect) - CGRectGetWidth(rect)) / 2.0);
// draw coin body
CGContextSetCMYKFillColor(context, 0.0, 0.0, 1.0, 0.3, 1.0);
CGContextFillEllipseInRect(context, coinRect);
CGContextSetLineWidth(context, 6.0);
CGContextSetCMYKStrokeColor(context, 0.0, 0.0, 1.0, 0.0, 1.0);
CGContextStrokeEllipseInRect(context, CGRectInset(coinRect, 3.0, 3.0));
CGContextSetRGBStrokeColor(context, 153.0 / 255.0, 145.0 / 255.0, 22.0 / 265.0, 1.0);
CGContextStrokeEllipseInRect(context, CGRectOffset(CGRectInset(coinRect, 3.0, 3.0), 0.0, 3.0));
// draw heads or tails label
UIPushContext(context);
UITextLabel *textLabel = [[[UITextLabel alloc] initWithFrame:CGRectInset(coinRect, 20.0, 50.0)] autorelease];
[textLabel setText:(heads ? @"Heads" : @"Tails")];
[textLabel setFont:(GSFontRef)[(id)GSFontCreateWithName("Marker Felt", kGSFontTraitBold, 50.0) autorelease]];
[textLabel setColor:(CGColorRef)[(id)GSColorCreateColorWithDeviceRGBA(228.0 / 255.0, 211.0 / 255.0, 26.0 / 265.0, 1.0) autorelease]];
[textLabel setShadowColor:(CGColorRef)[(id)GSColorCreateColorWithDeviceRGBA(153.0 / 255.0, 145.0 / 255.0, 22.0 / 265.0, 1.0) autorelease]];
[textLabel setShadowOffset:CGSizeMake(0, 3)];
[textLabel setCentersHorizontally:YES];
[textLabel drawContentsInRect:CGContextGetClipBoundingBox(context)];
UIPopContext(context);
}
- (CGImageRef)headsImage;
{
return headsImage;
}
- (CGImageRef)tailsImage;
{
return tailsImage;
}
- (UIView *)sunbeamsView;
{
return sunbeamsView;
}
@end