jens@0: /* This code is based on Apple's "GeekGameBoard" sample code, version 1.0. jens@0: http://developer.apple.com/samplecode/GeekGameBoard/ jens@0: Copyright © 2007 Apple Inc. Copyright © 2008 Jens Alfke. All Rights Reserved. jens@0: jens@0: Redistribution and use in source and binary forms, with or without modification, are permitted jens@0: provided that the following conditions are met: jens@0: jens@0: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@0: and the following disclaimer. jens@0: * Redistributions in binary form must reproduce the above copyright notice, this list of jens@0: conditions and the following disclaimer in the documentation and/or other materials provided jens@0: with the distribution. jens@0: jens@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@0: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@0: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@0: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@0: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@0: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@0: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@0: */ jens@0: #import "Bit.h" jens@0: #import "Game.h" jens@0: #import "QuartzUtils.h" jens@0: jens@0: jens@0: @implementation Bit jens@0: jens@0: jens@0: - (id) copyWithZone: (NSZone*)zone jens@0: { jens@1: Bit *clone = [super copyWithZone: zone]; jens@1: clone->_owner = _owner; jens@1: return clone; jens@0: } jens@0: jens@0: @synthesize owner=_owner; jens@0: jens@0: - (BOOL) isFriendly {return _owner.friendly;} jens@0: - (BOOL) isUnfriendly {return _owner.unfriendly;} jens@0: jens@0: jens@0: - (CGFloat) scale jens@0: { jens@0: NSNumber *scale = [self valueForKeyPath: @"transform.scale"]; jens@0: return scale.floatValue; jens@0: } jens@0: jens@0: - (void) setScale: (CGFloat)scale jens@0: { jens@0: [self setValue: [NSNumber numberWithFloat: scale] jens@0: forKeyPath: @"transform.scale"]; jens@0: } jens@0: jens@0: jens@0: - (int) rotation jens@0: { jens@0: NSNumber *rot = [self valueForKeyPath: @"transform.rotation"]; jens@0: return round( rot.doubleValue * 180.0 / M_PI ); jens@0: } jens@0: jens@0: - (void) setRotation: (int)rotation jens@0: { jens@0: [self setValue: [NSNumber numberWithDouble: rotation*M_PI/180.0] jens@0: forKeyPath: @"transform.rotation"]; jens@0: } jens@0: jens@0: jens@0: - (BOOL) pickedUp jens@0: { jens@0: return self.zPosition >= kPickedUpZ; jens@0: } jens@0: jens@0: - (void) setPickedUp: (BOOL)up jens@0: { jens@0: if( up != self.pickedUp ) { jens@0: CGFloat shadow, offset, radius, opacity, z, scale; jens@0: if( up ) { jens@0: shadow = 0.8; jens@0: offset = 2; jens@0: radius = 8; jens@0: opacity = 0.9; jens@0: scale = 1.2; jens@0: z = kPickedUpZ; jens@0: _restingZ = self.zPosition; jens@0: } else { jens@0: shadow = offset = radius = 0.0; jens@0: opacity = 1.0; jens@0: scale = 1.0/1.2; jens@0: z = _restingZ; jens@0: } jens@0: jens@0: self.zPosition = z; jens@1: #if !TARGET_OS_ASPEN jens@0: self.shadowOpacity = shadow; jens@0: self.shadowOffset = CGSizeMake(offset,-offset); jens@0: self.shadowRadius = radius; jens@1: #endif jens@0: self.opacity = opacity; jens@0: self.scale *= scale; jens@0: } jens@0: } jens@0: jens@0: jens@0: - (BOOL)containsPoint:(CGPoint)p jens@0: { jens@0: // Make picked-up pieces invisible to hit-testing. jens@0: // Otherwise, while dragging a Bit, hit-testing the cursor position would always return jens@0: // that Bit, since it's directly under the cursor... jens@0: if( self.pickedUp ) jens@0: return NO; jens@0: else jens@0: return [super containsPoint: p]; jens@0: } jens@0: jens@0: jens@0: -(id) holder jens@0: { jens@0: // Look for my nearest ancestor that's a BitHolder: jens@0: for( CALayer *layer=self.superlayer; layer; layer=layer.superlayer ) { jens@0: if( [layer conformsToProtocol: @protocol(BitHolder)] ) jens@0: return (id)layer; jens@0: else if( [layer isKindOfClass: [Bit class]] ) jens@0: return nil; jens@0: } jens@0: return nil; jens@0: } jens@0: jens@0: jens@0: - (void) destroy jens@0: { jens@0: // "Pop" the Bit by expanding it 5x as it fades away: jens@0: self.scale = 5; jens@0: self.opacity = 0.0; jens@0: // Removing the view from its superlayer right now would cancel the animations. jens@0: // Instead, defer the removal until sometime shortly after the animations finish: jens@0: [self performSelector: @selector(removeFromSuperlayer) withObject: nil afterDelay: 1.0]; jens@0: } jens@0: jens@0: jens@0: @end