Source/Piece.m
changeset 0 e9f7ba4718e1
child 1 3eb7be1dd7b6
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Source/Piece.m	Fri Mar 07 11:43:02 2008 -0800
     1.3 @@ -0,0 +1,132 @@
     1.4 +/*  This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
     1.5 +    http://developer.apple.com/samplecode/GeekGameBoard/
     1.6 +    Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
     1.7 +
     1.8 +    Redistribution and use in source and binary forms, with or without modification, are permitted
     1.9 +    provided that the following conditions are met:
    1.10 +
    1.11 +    * Redistributions of source code must retain the above copyright notice, this list of conditions
    1.12 +      and the following disclaimer.
    1.13 +    * Redistributions in binary form must reproduce the above copyright notice, this list of
    1.14 +      conditions and the following disclaimer in the documentation and/or other materials provided
    1.15 +      with the distribution.
    1.16 +
    1.17 +    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
    1.18 +    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
    1.19 +    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
    1.20 +    BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    1.21 +    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
    1.22 +    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
    1.23 +    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
    1.24 +    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.25 +*/
    1.26 +#import "Piece.h"
    1.27 +#import "QuartzUtils.h"
    1.28 +
    1.29 +
    1.30 +@implementation Piece
    1.31 +
    1.32 +
    1.33 +- (id) initWithImageNamed: (NSString*)imageName
    1.34 +                    scale: (CGFloat)scale
    1.35 +{
    1.36 +    self = [super init];
    1.37 +    if (self != nil) {
    1.38 +        self.imageName = imageName;
    1.39 +        [self setImage: GetCGImageNamed(imageName) scale: scale];
    1.40 +        self.zPosition = kPieceZ;
    1.41 +    }
    1.42 +    return self;
    1.43 +}
    1.44 +
    1.45 +
    1.46 +- (id) initWithCoder: (NSCoder*)decoder
    1.47 +{
    1.48 +    self = [super initWithCoder: decoder];
    1.49 +    if( self ) {
    1.50 +        self.imageName = [decoder decodeObjectForKey: @"imageName"];
    1.51 +        // (actual image (self.contents) was already restord by superclass)
    1.52 +    }
    1.53 +    return self;
    1.54 +}
    1.55 +
    1.56 +- (void) encodeWithCoder: (NSCoder*)coder
    1.57 +{
    1.58 +    [super encodeWithCoder: coder];
    1.59 +    [coder encodeObject: _imageName forKey: @"imageName"];
    1.60 +}
    1.61 +
    1.62 +
    1.63 +- (void) dealloc
    1.64 +{
    1.65 +    [_imageName release];
    1.66 +    [super dealloc];
    1.67 +}
    1.68 +
    1.69 +
    1.70 +- (NSString*) description
    1.71 +{
    1.72 +    return [NSString stringWithFormat: @"%@[%@]", 
    1.73 +            [self class],
    1.74 +            _imageName.lastPathComponent.stringByDeletingPathExtension];
    1.75 +}
    1.76 +
    1.77 +
    1.78 +@synthesize imageName=_imageName;
    1.79 +
    1.80 +
    1.81 +- (void) setImage: (CGImageRef)image scale: (CGFloat)scale
    1.82 +{
    1.83 +    self.contents = (id) image;
    1.84 +    self.contentsGravity = @"resize";
    1.85 +    self.minificationFilter = kCAFilterLinear;
    1.86 +    int width = CGImageGetWidth(image), height = CGImageGetHeight(image);
    1.87 +    if( scale > 0 ) {
    1.88 +        if( scale >= 4.0 )
    1.89 +            scale /= MAX(width,height);             // interpret scale as target dimensions
    1.90 +        width = ceil( width * scale);
    1.91 +        height= ceil( height* scale);
    1.92 +    }
    1.93 +    self.bounds = CGRectMake(0,0,width,height);
    1.94 +    self.imageName = nil;
    1.95 +}
    1.96 +
    1.97 +- (void) setImage: (CGImageRef)image
    1.98 +{
    1.99 +    CGSize size = self.bounds.size;
   1.100 +    [self setImage: image scale: MAX(size.width,size.height)];
   1.101 +}
   1.102 +
   1.103 +- (void) setImageNamed: (NSString*)name
   1.104 +{
   1.105 +    [self setImage: GetCGImageNamed(name)];
   1.106 +    self.imageName = name;
   1.107 +}
   1.108 +
   1.109 +
   1.110 +- (BOOL)containsPoint:(CGPoint)p
   1.111 +{
   1.112 +    // Overrides CGLayer's implementation,
   1.113 +    // returning YES only for pixels at which this layer's alpha is at least 0.5.
   1.114 +    // This takes into account the opacity, bg color, and background image's alpha channel.
   1.115 +    if( ! [super containsPoint: p] )
   1.116 +        return NO;
   1.117 +    float opacity = self.opacity;
   1.118 +    if( opacity < 0.5 )
   1.119 +        return NO;
   1.120 +    float thresholdAlpha = 0.5 / self.opacity;
   1.121 +    
   1.122 +    CGColorRef bg = self.backgroundColor;
   1.123 +    float alpha = bg ?CGColorGetAlpha(bg) :0.0;
   1.124 +    if( alpha < thresholdAlpha ) {
   1.125 +        CGImageRef image = (CGImageRef)self.contents;
   1.126 +        if( image ) {
   1.127 +            // Note: This makes the convenient assumption that the image entirely fills the bounds.
   1.128 +            alpha = MAX(alpha, GetPixelAlpha(image, self.bounds.size, p));
   1.129 +        }
   1.130 +    }
   1.131 +    return alpha >= thresholdAlpha;
   1.132 +}
   1.133 +
   1.134 +
   1.135 +@end