Source/Bit.m
author Jens Alfke <jens@mooseyard.com>
Thu May 29 15:04:06 2008 -0700 (2008-05-29)
changeset 9 a59acc683080
parent 8 45c82a071aca
child 10 6c78cc6bd7a6
permissions -rw-r--r--
Finally fixed the slow animation performance of board games; all it took was changing the board's z index from 1 to 0, somehow. Games working well now.
jens@0
     1
/*  This code is based on Apple's "GeekGameBoard" sample code, version 1.0.
jens@0
     2
    http://developer.apple.com/samplecode/GeekGameBoard/
jens@0
     3
    Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved.
jens@0
     4
jens@0
     5
    Redistribution and use in source and binary forms, with or without modification, are permitted
jens@0
     6
    provided that the following conditions are met:
jens@0
     7
jens@0
     8
    * Redistributions of source code must retain the above copyright notice, this list of conditions
jens@0
     9
      and the following disclaimer.
jens@0
    10
    * Redistributions in binary form must reproduce the above copyright notice, this list of
jens@0
    11
      conditions and the following disclaimer in the documentation and/or other materials provided
jens@0
    12
      with the distribution.
jens@0
    13
jens@0
    14
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
jens@0
    15
    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
jens@0
    16
    FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
jens@0
    17
    BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
jens@0
    18
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
jens@0
    19
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
jens@0
    20
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
jens@0
    21
    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
jens@0
    22
*/
jens@0
    23
#import "Bit.h"
jens@0
    24
#import "Game.h"
jens@0
    25
#import "QuartzUtils.h"
jens@0
    26
jens@0
    27
jens@9
    28
#ifdef TARGET_OS_IPHONE
jens@9
    29
#define kPickedUpScale   2.0      // more magnification, so piece shows up underneath fingertip
jens@9
    30
#define kPickedUpOpacity 0.6
jens@9
    31
#else
jens@9
    32
#define kPickedUpScale   1.2
jens@9
    33
#define kPickedUpOpacity 0.9
jens@9
    34
#endif
jens@9
    35
jens@9
    36
jens@0
    37
@implementation Bit
jens@0
    38
jens@0
    39
jens@0
    40
- (id) copyWithZone: (NSZone*)zone
jens@0
    41
{
jens@1
    42
    Bit *clone = [super copyWithZone: zone];
jens@1
    43
    clone->_owner = _owner;
jens@1
    44
    return clone;
jens@0
    45
}
jens@0
    46
jens@7
    47
- (void) dealloc
jens@7
    48
{
jens@7
    49
    [super dealloc];
jens@7
    50
}
jens@7
    51
jens@7
    52
jens@0
    53
@synthesize owner=_owner;
jens@0
    54
jens@0
    55
- (BOOL) isFriendly         {return _owner.friendly;}
jens@0
    56
- (BOOL) isUnfriendly       {return _owner.unfriendly;}
jens@0
    57
jens@7
    58
/*
jens@7
    59
- (NSString*) identifier
jens@7
    60
{
jens@7
    61
    if( _identifier )
jens@7
    62
        return _identifier;
jens@7
    63
    // Defaults to just identifying the owner:
jens@7
    64
    return [NSString stringWithFormat: @"p%i", _owner.index+1];
jens@7
    65
}
jens@7
    66
*/
jens@0
    67
jens@0
    68
- (CGFloat) scale
jens@0
    69
{
jens@0
    70
    NSNumber *scale = [self valueForKeyPath: @"transform.scale"];
jens@0
    71
    return scale.floatValue;
jens@0
    72
}
jens@0
    73
jens@0
    74
- (void) setScale: (CGFloat)scale
jens@0
    75
{
jens@0
    76
    [self setValue: [NSNumber numberWithFloat: scale]
jens@0
    77
        forKeyPath: @"transform.scale"];
jens@0
    78
}
jens@0
    79
jens@0
    80
jens@0
    81
- (int) rotation
jens@0
    82
{
jens@0
    83
    NSNumber *rot = [self valueForKeyPath: @"transform.rotation"];
jens@0
    84
    return round( rot.doubleValue * 180.0 / M_PI );
jens@0
    85
}
jens@0
    86
jens@0
    87
- (void) setRotation: (int)rotation
jens@0
    88
{
jens@0
    89
    [self setValue: [NSNumber numberWithDouble: rotation*M_PI/180.0]
jens@0
    90
        forKeyPath: @"transform.rotation"];
jens@0
    91
}
jens@0
    92
jens@0
    93
jens@0
    94
- (BOOL) pickedUp
jens@0
    95
{
jens@9
    96
    return _pickedUp;
jens@0
    97
}
jens@0
    98
jens@0
    99
- (void) setPickedUp: (BOOL)up
jens@0
   100
{
jens@9
   101
    if( up != _pickedUp ) {
jens@0
   102
        CGFloat shadow, offset, radius, opacity, z, scale;
jens@0
   103
        if( up ) {
jens@0
   104
            shadow = 0.8;
jens@0
   105
            offset = 2;
jens@0
   106
            radius = 8;
jens@9
   107
            opacity = kPickedUpOpacity;
jens@9
   108
            scale = kPickedUpScale;
jens@0
   109
            z = kPickedUpZ;
jens@0
   110
            _restingZ = self.zPosition;
jens@0
   111
        } else {
jens@0
   112
            shadow = offset = radius = 0.0;
jens@0
   113
            opacity = 1.0;
jens@9
   114
            scale = 1.0/kPickedUpScale;
jens@0
   115
            z = _restingZ;
jens@0
   116
        }
jens@9
   117
jens@9
   118
        //self.zPosition = z;
jens@8
   119
#if !TARGET_OS_IPHONE
jens@0
   120
        self.shadowOpacity = shadow;
jens@0
   121
        self.shadowOffset = CGSizeMake(offset,-offset);
jens@0
   122
        self.shadowRadius = radius;
jens@1
   123
#endif
jens@0
   124
        self.opacity = opacity;
jens@0
   125
        self.scale *= scale;
jens@9
   126
        _pickedUp = up;
jens@0
   127
    }
jens@0
   128
}
jens@0
   129
jens@0
   130
jens@0
   131
- (BOOL)containsPoint:(CGPoint)p
jens@0
   132
{
jens@0
   133
    // Make picked-up pieces invisible to hit-testing.
jens@0
   134
    // Otherwise, while dragging a Bit, hit-testing the cursor position would always return
jens@0
   135
    // that Bit, since it's directly under the cursor...
jens@0
   136
    if( self.pickedUp )
jens@0
   137
        return NO;
jens@0
   138
    else
jens@0
   139
        return [super containsPoint: p];
jens@0
   140
}
jens@0
   141
jens@0
   142
jens@0
   143
-(id<BitHolder>) holder
jens@0
   144
{
jens@0
   145
    // Look for my nearest ancestor that's a BitHolder:
jens@0
   146
    for( CALayer *layer=self.superlayer; layer; layer=layer.superlayer ) {
jens@0
   147
        if( [layer conformsToProtocol: @protocol(BitHolder)] )
jens@0
   148
            return (id<BitHolder>)layer;
jens@0
   149
        else if( [layer isKindOfClass: [Bit class]] )
jens@0
   150
            return nil;
jens@0
   151
    }
jens@0
   152
    return nil;
jens@0
   153
}
jens@0
   154
jens@0
   155
jens@0
   156
- (void) destroy
jens@0
   157
{
jens@0
   158
    // "Pop" the Bit by expanding it 5x as it fades away:
jens@0
   159
    self.scale = 5;
jens@0
   160
    self.opacity = 0.0;
jens@0
   161
    // Removing the view from its superlayer right now would cancel the animations.
jens@0
   162
    // Instead, defer the removal until sometime shortly after the animations finish:
jens@0
   163
    [self performSelector: @selector(removeFromSuperlayer) withObject: nil afterDelay: 1.0];
jens@0
   164
}
jens@0
   165
jens@0
   166
jens@0
   167
@end