From 9cd57b731ab1c666d4a1cb725538fdc137763d12 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sat, 30 Jul 2011 11:19:14 -0400 Subject: Initial commit (version 0.2.1) --- libs/cocos2d/CCParallaxNode.m | 161 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100755 libs/cocos2d/CCParallaxNode.m (limited to 'libs/cocos2d/CCParallaxNode.m') diff --git a/libs/cocos2d/CCParallaxNode.m b/libs/cocos2d/CCParallaxNode.m new file mode 100755 index 0000000..9d39cc8 --- /dev/null +++ b/libs/cocos2d/CCParallaxNode.m @@ -0,0 +1,161 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2009-2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#import "CCParallaxNode.h" +#import "Support/CGPointExtension.h" +#import "Support/ccCArray.h" + +@interface CGPointObject : NSObject +{ + CGPoint ratio_; + CGPoint offset_; + CCNode *child_; // weak ref +} +@property (readwrite) CGPoint ratio; +@property (readwrite) CGPoint offset; +@property (readwrite,assign) CCNode *child; ++(id) pointWithCGPoint:(CGPoint)point offset:(CGPoint)offset; +-(id) initWithCGPoint:(CGPoint)point offset:(CGPoint)offset; +@end +@implementation CGPointObject +@synthesize ratio = ratio_; +@synthesize offset = offset_; +@synthesize child=child_; + ++(id) pointWithCGPoint:(CGPoint)ratio offset:(CGPoint)offset +{ + return [[[self alloc] initWithCGPoint:ratio offset:offset] autorelease]; +} +-(id) initWithCGPoint:(CGPoint)ratio offset:(CGPoint)offset +{ + if( (self=[super init])) { + ratio_ = ratio; + offset_ = offset; + } + return self; +} +@end + +@implementation CCParallaxNode + +@synthesize parallaxArray = parallaxArray_; + +-(id) init +{ + if( (self=[super init]) ) { + parallaxArray_ = ccArrayNew(5); + lastPosition = CGPointMake(-100,-100); + } + return self; +} + +- (void) dealloc +{ + if( parallaxArray_ ) { + ccArrayFree(parallaxArray_); + parallaxArray_ = nil; + } + [super dealloc]; +} + +-(void) addChild:(CCNode*)child z:(NSInteger)z tag:(NSInteger)tag +{ + NSAssert(NO,@"ParallaxNode: use addChild:z:parallaxRatio:positionOffset instead"); +} + +-(void) addChild: (CCNode*) child z:(NSInteger)z parallaxRatio:(CGPoint)ratio positionOffset:(CGPoint)offset +{ + NSAssert( child != nil, @"Argument must be non-nil"); + CGPointObject *obj = [CGPointObject pointWithCGPoint:ratio offset:offset]; + obj.child = child; + ccArrayAppendObjectWithResize(parallaxArray_, obj); + + CGPoint pos = self.position; + pos.x = pos.x * ratio.x + offset.x; + pos.y = pos.y * ratio.y + offset.y; + child.position = pos; + + [super addChild: child z:z tag:child.tag]; +} + +-(void) removeChild:(CCNode*)node cleanup:(BOOL)cleanup +{ + for( unsigned int i=0;i < parallaxArray_->num;i++) { + CGPointObject *point = parallaxArray_->arr[i]; + if( [point.child isEqual:node] ) { + ccArrayRemoveObjectAtIndex(parallaxArray_, i); + break; + } + } + [super removeChild:node cleanup:cleanup]; +} + +-(void) removeAllChildrenWithCleanup:(BOOL)cleanup +{ + ccArrayRemoveAllObjects(parallaxArray_); + [super removeAllChildrenWithCleanup:cleanup]; +} + +-(CGPoint) absolutePosition_ +{ + CGPoint ret = position_; + + CCNode *cn = self; + + while (cn.parent != nil) { + cn = cn.parent; + ret = ccpAdd( ret, cn.position ); + } + + return ret; +} + +/* + The positions are updated at visit because: + - using a timer is not guaranteed that it will called after all the positions were updated + - overriding "draw" will only precise if the children have a z > 0 +*/ +-(void) visit +{ +// CGPoint pos = position_; +// CGPoint pos = [self convertToWorldSpace:CGPointZero]; + CGPoint pos = [self absolutePosition_]; + if( ! CGPointEqualToPoint(pos, lastPosition) ) { + + for(unsigned int i=0; i < parallaxArray_->num; i++ ) { + + CGPointObject *point = parallaxArray_->arr[i]; + float x = -pos.x + pos.x * point.ratio.x + point.offset.x; + float y = -pos.y + pos.y * point.ratio.y + point.offset.y; + point.child.position = ccp(x,y); + } + + lastPosition = pos; + } + + [super visit]; +} +@end -- cgit 1.4.1