顯示具有 Touch 標籤的文章。 顯示所有文章
顯示具有 Touch 標籤的文章。 顯示所有文章

2012年6月20日 星期三

Cocos2d 2.0 Animation

To do animation under cocos2d 2.0 you need to create sprite frame cache, sprite sheet, animation frames, animation, sprite, action, and start the animation.

Create Sprite Frame Cache

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"role.plist"];

Create Sprite Sheet


    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"role.png"];

    [self addChild:spriteSheet];

Create Animation Frames


    NSMutableArray *danceAnimationFrames = [NSMutableArray array];
    for(int i=1; i <= 14; i++) {
        [danceAnimationFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"role%02d.png", i]]];
    }

Create Animation


    CCAnimation *danceAnimation = [CCAnimation animationWithSpriteFrames:danceAnimationFrames delay:0.1f];

Add Animation to Animation Cache

    [[CCAnimationCache sharedAnimationCache] addAnimation:danceAnimation name:@"danceAnimation"];

Get Animation from Animation Cache

    danceAnimation = [[CCAnimationCache sharedAnimationCache] animationByName:@"danceAnimation"];

Create Sprite


    self.role = [mySprite spriteWithSpriteFrameName:@"role01.png"];

Create Action



    self.danceAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:danceAnimation]];

Sample Code for AniEgg.h


#import "cocos2d.h"

#import "mySprite.h"



@interface AniEgg : CCLayer {

    mySprite *_role;
    CCAction *_danceAction;
}

+(CCScene *)scene;
@property (nonatomic, retain) mySprite *role;
@property (nonatomic, retain) CCAction *danceAction;

@end

Sample Code for AniEgg.m


#import "AniEgg.h"



BOOL paused;

int pausedCount;


@implementation AniEgg

@synthesize role = _role;
@synthesize danceAction = _danceAction;


+(CCScene *) scene {
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];
    // 'layer' is an autorelease object.
    AniEgg *layer = [AniEgg node];
    // add layer as a child to scene
    [scene addChild: layer];
    // return the scene
    return scene;
}

-(id) init {
    if( (self=[super init]) ) {
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"role.plist"];
        CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"role.png"];
        [self addChild:spriteSheet];
        NSMutableArray *danceAnimationFrames = [NSMutableArray array];
        for(int i=1; i <= 14; i++) {
            [danceAnimationFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"role%02d.png", i]]];
        }
        CCAnimation *danceAnimation = [CCAnimation animationWithSpriteFrames:danceAnimationFrames delay:0.1f];
        CGSize winSize = [[CCDirector sharedDirector] winSize];
        self.role = [mySprite spriteWithSpriteFrameName:@"role01.png"];
        _role.position = ccp(winSize.width / 2, winSize.height / 2);
        self.danceAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:danceAnimation]];
        [spriteSheet addChild:_role];
        [_role runAction:_danceAction];
        paused = NO;
        [self schedule:@selector(nextFrame:) interval:0.1f];
        self.isTouchEnabled = YES;
    }
    return self;
}

- (void) nextFrame:(ccTime)dt {
    if ([_role isTouched]) {
        if (paused) {
            paused = NO;
            [[[CCDirector sharedDirector] actionManager] resumeTarget:_role];
            pausedCount = 0;
        } else {
            paused = YES;
            [[[CCDirector sharedDirector] actionManager] pauseTarget:_role];
            pausedCount = 0;
        }
        [_role setUnTouched];
    }
    if (paused) {
        pausedCount++;
        if (pausedCount >= 20) {
            paused = NO;
            [[[CCDirector sharedDirector] actionManager] resumeTarget:_role];
            pausedCount = 0;            
        }
    }
}

- (void) dealloc
{
    self.role = nil;
    self.danceAction = nil;
}

@end

2012年6月18日 星期一

Cocos2d 2.0 Multi Touch Detection for CCSprite


In order to detect multi touch for CCSprite in Cocos2d 2.0, you must implement CCStandardTouchDelegate.

Implement CCStandardTouchDelegate

@interface mySprite : CCSprite <CCStandardTouchDelegate>

Add Standard Delegation

[[[CCDirector sharedDirector] touchDispatcher] addStandardDelegate:self priority:0];

Remove Delegation

[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];

Detect Touched or Not

-(BOOL)touched:(UITouch *)touch {
    CGPoint touchPoint = [touch locationInView:[touch view]];
    touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
    CGRect rect = [self boundingBox];
    if (CGRectContainsPoint(rect, touchPoint)) {
        return YES;
    } 
    return NO;
}

NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches) {
    isTouched = [self touched:touch];
    if (isTouched) {
        // Your actions
    }
}

sample code for mySprite.h

#import "cocos2d.h"



@interface mySprite : CCSprite <CCSyandardTouchDelegate>
@end

sample code for mySprite.c


#import "mySprite.h"


@implementation mySprite
-(void)onEnter {
[[[CCDirector sharedDirector] touchDispatcher] addStandardDelegate:self priority:0];
    [super onEnter];
}


-(void)onExit {
[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
    [super onExit];
}


-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSSet *allTouches = [event allTouches];
    for (UITouch *touch in allTouches) {
        isTouched = [self touched:touch];
        if (isTouched) {
            id enlarge = [CCScaleTo actionWithDuration:0.5f scale:1.1f];
            id resize = [CCScaleTo actionWithDuration:0.5f scale:1];
            [self runAction:[CCSequence actions:enlarge, resize, nil]];
        }
    }
}


-(BOOL)touched:(UITouch *)touch {
    CGPoint touchPoint = [touch locationInView:[touch view]];
    touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
    CGRect rect = [self boundingBox];
    if (CGRectContainsPoint(rect, touchPoint)) {
        return YES;
    } 
    return NO;
}
@end

Cocos2d 2.0 Single Touch Detection for CCSprite

In order to detect single touch for CCSprite in Cocos2d 2.0, you must implement CCTargetedTouchDelegate.

Implement CCTargetedTouchDelegate

@interface mySprite : CCSprite <CCTargetedTouchDelegate>

Add Target Delegation

[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

Remove Delegation

[[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];

Detect Touched or Not

CGPoint touchPoint = [touch locationInView:[touch view]];
touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
CGRect rect = [self boundingBox];
if (CGRectContainsPoint(rect, touchPoint)) {
    return YES;

return NO;

sample code for mySprite.h

#import "cocos2d.h"



@interface mySprite : CCSprite <CCTargetedTouchDelegate>
@end

sample code for mySprite.c


#import "mySprite.h"


@implementation mySprite
-(void)onEnter {
    [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    [super onEnter];
}


-(void)onExit {
    [[[CCDirector sharedDirector] touchDispatcher] removeDelegate:self];
    [super onExit];
}


-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
    BOOL isTouched = [self touched:touch];
    if (isTouched) {
        [self stopAllActions];
        id enlarge = [CCScaleTo actionWithDuration:0.5f scale:1.1f];
        id resize = [CCScaleTo actionWithDuration:0.5f scale:1];
        [self runAction:[CCSequence actions:enlarge, resize, nil]];
    }
    return isTouched;
}


-(BOOL)touched:(UITouch *)touch {
    CGPoint touchPoint = [touch locationInView:[touch view]];
    touchPoint = [[CCDirector sharedDirector] convertToGL:touchPoint];
    CGRect rect = [self boundingBox];
    if (CGRectContainsPoint(rect, touchPoint)) {
        return YES;
    } 
    return NO;
}
@end

2012年6月13日 星期三

Cocos2d 2.0 Touch Input

Cocos2d supports two different ways of handling touch events. These are defined by two different types of delegates: Standard Touch Delegate and Targeted Touch Delegate.

Standard Touch Delegate

Standard Touch Event includes ccTouchesBegan:withEvent:ccTouchesMoved:withEvent:ccTouchesEnded:withEvent:ccTouchesCancelled:withEvent:.

@protocol CCStandardTouchDelegate <NSObject>
@optional
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end


You'll get all events, and all touches; it will be up to you to sort out which touches you care about in a multi-touch environment.


To get these events in a CCLayer subclass, you simply set isTouchEnabled = YES:


self.isTouchEnabled = YES;

Targeted Touch Delegate

Targeted Touch Event includes ccTouchBegan:withEvent:ccTouchMoved:withEvent:ccTouchEnded:withEvent:ccTouchCancelled:withEvent:.


@protocol CCTargetedTouchDelegate <NSObject>

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;

@optional
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end

Targeted Touch methods provide only a single touch.  Standard Touch methods provide a set of touches.

The ccTouchBegan method is required and returns a boolean value. So ccTouchBegan will be invoked separately for each of the available touches, and you return YES to indicate a touch you care about. Only touches claimed by ccTouchBegan will be subsequently passed on to the Moved, Ended, and Cancelled events.

To receive these events, you must register as a targeted touch delegate with the global dispatcher. In a CCLayer subclass, override registerWithTouchDispatcher as follows:

-(void) registerWithTouchDispatcher
{
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
                                          priority:0 swallowsTouches:YES];
}

Multi Touch

To recieve multi-touch events, you have to activate them. You can do this by adding the following code in your AppDelegate's applicationDidFinishLaunching:

[glView setMultipleTouchEnabled:YES];

If you are using Cocos2d with Storyboard, you can do this by adding the following code in your ViewController's viewDidLoad:

[self.view setMultipleTouchEnabled:YES]