All pastes #838401 Raw Edit

Stuff

public text v1 · immutable
#838401 ·published 2007-12-30 09:51 UTC
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