cocos2d视频教程进阶篇--第3天--猴子跳跳游戏

今天我们学习一个Cocosd2d-iphone游戏。中间介绍了texturepacker 和physics editor的使用(需要MAC操作系统),我们一起做一个实战级别的游戏。


其中还介绍了 图片资源文件加密, 碰撞检测,动画效果等知识,比较有趣。


感觉代码太枯燥的,敬请期待视频上传

高清avi视频和项目源代码已经提供下载:

百度网盘:http://pan.baidu.com/s/1ELk78 里面的进阶篇。

 
 
//
//  Floor.h
//  MonkeyJump
//
//  Created by Mac on 14-3-10.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//

#import "GB2Sprite.h"

@interface Floor : GB2Sprite // 既有cocos2d CCSprite 又包含 b2Body

+(Floor*)floorSprite;

@end


//
//  Floor.m
//  MonkeyJump
//
//  Created by Mac on 14-3-10.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//

#import "Floor.h"

@implementation Floor

+(Floor*)floorSprite{
    // GB2Sprite
    return [[[self alloc] initWithStaticBody:@"grassfront" spriteFrameName:@"floor/grassfront.png"] autorelease];
}
@end



//
//  GameLayer.h
//  MonkeyJump
//
//  Created by Andreas Löw on 10.11.11.
//  Copyright codeandweb.de 2011. All rights reserved.
//

// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

@class Object;
@class Monkey;
@class HeadUpDisplay;

// GameLayer
@interface GameLayer : CCLayer
{
    float       _timeLeftBeforeNextObject;
    Object*     _nextObject;
    
    Monkey*     _monkey;
    CCSpriteBatchNode* _objectLayer ;

    CCSprite *__backGrass;
    float _heapHeight;   //堆积物体的最高高度
}


@property (assign,nonatomic) float highestObjectY;
@property(nonatomic) float heapHeight;  // 不需要写synthesis

// returns a CCScene that contains the GameLayer as the only child
+(CCScene *) scene;

@end




//
//  GameLayer.mm
//  MonkeyJump
//
//  Created by Andreas Löw on 10.11.11.
//  Copyright codeandweb.de 2011. All rights reserved.
//

// Import the interfaces
#import "GameLayer.h"
#import "GB2DebugDrawLayer.h"
#import "GB2Sprite.h"
#import "Floor.h"

#import "Object.h"
#import "Monkey.h"
#import "HeadUpDisplay.h"
#import "SimpleAudioEngine.h"

#import "ZipUtils.h"
#import "cocos2d/Support/ZipUtils.h"


// HelloWorldLayer implementation
@implementation GameLayer {
    CCSprite *__background;
    Floor *_floorObj;
    HeadUpDisplay *_hud;
    int _tickAfterMonkeyDead;
    float _timeGap;
    CCLayerColor *_indicator;
}


+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];

	// 'layer' is an autorelease object.
	GameLayer *layer = [GameLayer node];

	// add layer as a child to scene
	[scene addChild: layer];

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
-(id) init
{

    caw_setkey_part(0, 0xb789a2ef);
    caw_setkey_part(1, 0xa185b1df);
    caw_setkey_part(2, 0x5e648b88);
    caw_setkey_part(3, 0x9cf4f44e);


     CGSize screenSize = [[CCDirector sharedDirector] winSize];

    float temp;
    if (screenSize.width > screenSize.height){
        temp = screenSize.width;
        screenSize.width = screenSize.height;
        screenSize.height = temp;
    }

	if( (self=[super init]))
    {
        // 加载我们的spritesheet            pvr.czz
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"tp_objects.plist"];

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

        // 加载box2d 物体属性
        [[GB2ShapeCache sharedShapeCache] addShapesWithFile:@"pe_monkey.plist"];

        // 最底层
        __background = [CCSprite spriteWithSpriteFrameName:@"jungle.png"];
        __background.anchorPoint = ccp(0,0);
        __background.position = ccp(0,0);
        [self addChild:__background z:0];

        // 背景的草
        __backGrass = [CCSprite spriteWithSpriteFrameName:@"floor/grassbehind.png"];
        __backGrass.anchorPoint = ccp(0, 0);
        __backGrass.position = ccp(0, 0);
        [self addChild:__backGrass z:2];

        // 所有展示的 box2d世界中的物体
        _objectLayer = [CCSpriteBatchNode batchNodeWithFile:@"tp_objects.pvr.ccz"];

        [self addChild:_objectLayer z:10];


        _floorObj = [Floor floorSprite];
        CCSprite* floor = (CCSprite *) [_floorObj ccNode];
        [_objectLayer addChild:floor];

        [self scheduleUpdate];

        _timeLeftBeforeNextObject = 2;
        _nextObject = nil;

        GB2Node* leftWall = [[[GB2Node alloc] initWithStaticBody:nil node:nil] autorelease];
        [leftWall addEdgeFrom:b2Vec2FromCC(0, 0) to:b2Vec2FromCC(0, 10000)];


        GB2Node*rightWall = [[[GB2Node alloc] initWithStaticBody:nil node:nil] autorelease];
        [rightWall addEdgeFrom:b2Vec2FromCC(screenSize.height, 0) to:b2Vec2FromCC(screenSize.height, 10000)];

        // i really not like
        //调试box2d
//        CCNode* debugLayer = [[[GB2DebugDrawLayer alloc] init] autorelease];
//        [self addChild:debugLayer z:40];
        
        _monkey = [[[Monkey alloc] initWithParentlayer:self] autorelease];
        
        [_monkey setPhysicsPosition:b2Vec2FromCC(240, (120 + 32) / 2)];
        [_objectLayer addChild:[_monkey ccNode] z:40];


        _hud = [[HeadUpDisplay alloc] init];
        [self addChild:_hud z:20];

        [self setIsTouchEnabled:YES];


        _heapHeight = floor.position.y + floor.contentSize.height;

        _indicator = [[[CCLayerColor alloc] initWithColor:ccc4(255, 0, 0, 128) width:70 height:20] autorelease];
        [self addChild:_indicator z:30];
        _indicator.visible = NO;


        [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"tafi-maradi-loop.caf" loop:YES];
    }
    
	return self;
}

// 接受用户事件  触发猴子的运动
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch* touch = (UITouch*) [touches anyObject];
    
    CGPoint uiPos = [touch locationInView:[touch view]];
    
    CGPoint pos = [[CCDirector sharedDirector] convertToGL:uiPos];
    
    float mX = [_monkey ccNode].position.x;
    
    if (pos.x < mX){
        _monkey.isMovingLeft = YES;
    }
    else {
        _monkey.isMovingLeft = NO;
    }


    // 触屏的上半部分  触摸 让猴子起跳
    if (pos.y > 160.0){
        [_monkey jump];
    }
}




-(void)update:(float) dt{
    //CCLOG(@"update method");
    _timeGap = 3.0f;

    [_hud notifiedHealth:_monkey.health];
    [_hud notifieadScore:_monkey.score];

    if (_monkey.health < 0){
        _tickAfterMonkeyDead++;

        if (_tickAfterMonkeyDead > 90){
            [[GB2Engine sharedInstance] deleteAllObjects]; // box2d 清空
            [[CCDirector sharedDirector] replaceScene:[GameLayer scene]];    // cocos2d 图形

            return;
        }
    }


    CGSize screenSize = [[CCDirector sharedDirector] winSize];

    _timeLeftBeforeNextObject -= dt;

    float monkeyY = [_monkey ccNode].position.y;

    if (_timeLeftBeforeNextObject > 0.5 * _timeGap && nil != _nextObject){
        _indicator.position = ccp([_nextObject ccNode].position.x, 300);
        _indicator.visible = YES;

    }       else{
        _indicator.visible = NO;
    }

    if (_timeLeftBeforeNextObject <= 0){
        _nextObject = [Object randomObject];

        int offsetX = rand() % 400 + 40;
        int offsetY = 400 + _heapHeight;

        [_nextObject setPhysicsPosition:b2Vec2FromCC(offsetX, offsetY)];

        [_objectLayer addChild:[_nextObject ccNode]];

        _timeGap *= 0.8;
        
        _timeLeftBeforeNextObject = _timeGap;
        if (_timeLeftBeforeNextObject < 0.5){
            _timeLeftBeforeNextObject  = 0.5;
        }
        //CCLOG(@"time gap is %f", _timeLeftBeforeNextObject);

    }

    // 调整摄像头位置
    [self adjustViewPoint:screenSize monkeyY:monkeyY];


    // 堆积物体的顶部      遍历box2d世界中的所有东西
    [[GB2Engine sharedInstance] iterateObjectsWithBlock:^(GB2Node *node) {
           // 是Object吗

            if ([node isKindOfClass:([Object class])]){
                Object *obj = (Object *)node;

                if (b2_staticBody != [obj getBodyType]      //已经变成静态的 不再考虑
                    &&  _nextObject != obj
                    && obj.numContacts > 1 //和多个物体又接触 才算在堆上
                    && [obj linearVelocity].LengthSquared() < 0.4
                        ){       // 只有obj是落在堆上的物体 才去更新_heapHeight

                    float objY = [obj ccNode].position.y + [obj ccNode].contentSize.height;

                    if (_heapHeight < objY){
                        _heapHeight = objY;

                        if (_heapHeight > 120){
                            ;
                        }

                        //CCLOG(@"heap height is %f", _heapHeight);
                    }

                    // 如果物体在堆的下层,离顶部很远 使它变成静态物体  box2d性能提高
                    if (objY < _heapHeight - 320){
                        [obj setBodyType:b2_staticBody];

                        static int numObjectsFromDynamicToStatic = 0;
                        numObjectsFromDynamicToStatic ++;
//                        CCLOG(@"%x(%d) become from dynamic to static , totally %d objects changed",
//                        obj, obj.numContacts, numObjectsFromDynamicToStatic);

                    }
                }

            }
    }];


}

- (void)adjustViewPoint:(CGSize)screenSize monkeyY:(float)monkeyY {
    float centerY = monkeyY - screenSize.width / 2;

    if (centerY < 0){
        centerY = 0;
    }


    _objectLayer.position = ccp(0, -centerY);

    __backGrass.position = ccp(0, -0.8 * centerY);

    __background.position = ccp(0, -0.6 * centerY);
}


@end





//
// Created by Mac on 14-3-16.
// Copyright (c) 2014 codeandweb.de. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <cocos2d.h>
#import "CCSpriteBatchNode.h"

@interface HeadUpDisplay : CCSpriteBatchNode {
    float _displayHealth;
}

@property(nonatomic) float displayHealth;

-(id)init;

- (void)notifieadScore:(float)theScore;

-(void)notifiedHealth:(float) monkeyHealth;
@end



//
// Created by Mac on 14-3-16.
// Copyright (c) 2014 codeandweb.de. All rights reserved.
//

#import "HeadUpDisplay.h"
#import "CCSprite.h"
#import "CCAction.h"
#import "CCActionInterval.h"
#import "CCActionInstant.h"
#import "CCSpriteFrame.h"
#import "CCSpriteFrameCache.h"

#define MAX_DISPLAY_TOKE_NUM 10

@implementation HeadUpDisplay {

    CCSprite *_displayToken [MAX_DISPLAY_TOKE_NUM];

    CCSprite* _scoreDisplay[5];

@private
    float _scoreOnBoard;
    CCSpriteFrame *_digits [10];
}

- (id)init {
    [super initWithFile:@"tp_objects.pvr.ccz" capacity:50];

    if (self){
        for (int i = 0; i < MAX_DISPLAY_TOKE_NUM; i ++){
            _displayToken[i] = [CCSprite spriteWithSpriteFrameName:@"hud/banana.png"];
            _displayToken[i].position = ccp(20 + i * 15, 280);
            [self addChild:_displayToken[i]];
            _displayToken[i].visible = YES;

        }

        for (int i = 0; i < 5; i ++){
            _scoreDisplay[i] = [CCSprite spriteWithSpriteFrameName:@"numbers/0.png"];
            _scoreDisplay[i].position = ccp(380 + i * 15, 280);
            _scoreDisplay[i].scale = 0.7f;
            [self addChild:_scoreDisplay[i]];
            _scoreDisplay[i].visible = NO;
        }

        for (int i = 0; i < 10; i ++){
            NSString* name = [NSString stringWithFormat:@"numbers/%d.png", i];
            _digits[i] = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:name];
        }
    }

    _displayHealth = 100.0; // 100 ---- MAX_DISPLAY_TOKE_NUM
    _scoreOnBoard = 0;

    return self;
}


-(void) notifieadScore:(float)theScore{
    if (_scoreOnBoard < theScore){
        _scoreOnBoard += 1;

        if (_scoreOnBoard > theScore){
            _scoreOnBoard = theScore;
        }
    }

    int scoreInt = (int)_scoreOnBoard;

    char buf[5 + 1] = {0};

    snprintf(buf, 6, "%5d", scoreInt);

    for (int i = 0; i < 5; i ++){
        if (' ' == buf[i]){
            _scoreDisplay[i].visible = NO;
            continue;
        }

        int index = buf[i] - '0';

        [_scoreDisplay[i] setDisplayFrame:_digits[index]];
        _scoreDisplay[i].visible = YES;
    }


}

- (void)notifiedHealth:(float)monkeyHealth {

    if (monkeyHealth > _displayHealth){
        _displayHealth += 13.0f;
        if (_displayHealth > monkeyHealth){
            _displayHealth = monkeyHealth;
        }
    }  else{
          _displayHealth -= 13.0f;

        if (_displayHealth < monkeyHealth){
            _displayHealth = monkeyHealth;
        }
    }


    int displayNum = (int)((_displayHealth / 100) * MAX_DISPLAY_TOKE_NUM);

    int i;

    for (i =0; i < displayNum; i ++){
        //_displayToken[i].visible = YES;
        CCSprite *token =    _displayToken[i];
        if (NO == token.visible){

            token.visible = YES;

            token.opacity = 0.0f;
            token.scale = 0.3;

            // 多个动作 合并
            CCSpawn *action  = [CCSpawn actions:
                    [CCScaleTo actionWithDuration:0.3 scale:1.0f],
                    [CCFadeIn actionWithDuration:0.3f],
                    nil]  ;

            [token runAction:action];

        }
    }

    for (; i < MAX_DISPLAY_TOKE_NUM; i ++){

        CCSprite *token =    _displayToken[i];
        if (YES == token.visible && [token numberOfRunningActions] <= 0){

            CCSpawn *disappear = [CCSpawn actions:
                    [CCScaleTo actionWithDuration:0.3 scale:0.3],
                    [CCFadeOut actionWithDuration:0.3],
                    nil]; // visiable == YES;

            CCHide* hide = [CCHide action];

            CCSequence *all = [CCSequence actions:disappear, hide, nil];


            [token runAction:all];

        }
    }
}

@end



//
//  Monkey.h
//  MonkeyJump
//
//  Created by Mac on 14-3-11.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//

#import "GB2Sprite.h"

@class GameLayer;
@class GB2Contact;

@interface Monkey : GB2Sprite
{
    bool _isMovingLeft;
    
    int _numContactWithFloor;
    
    int _numContactWithHead;
    int _numContactWithLeft;
    int _numContactWithRight;
    
    ccTime  _timePassed;
    int _animatePhase;


    int _trappedCount; // 记录猴子被困住的时间  -- 跳到堆积物体的顶部以上




    float _health;
}

@property (assign, nonatomic) bool isMovingLeft;
@property (assign, nonatomic) int numbContactWithFloor;

@property(nonatomic) float health;


@property(nonatomic) float score;

-(id)initWithParentlayer:(GameLayer*) theParentLayer;
-(void)jump;

- (void)beginContactWithFloor:(GB2Contact *)contact;

- (void)endContactWithFloor:(GB2Contact *)contact;


- (void)beginContactWithObject:(GB2Contact *)contact;

- (void)endContactWithObject:(GB2Contact *)contact;
@end



//
//  Monkey.m
//  MonkeyJump
//
//  Created by Mac on 14-3-11.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//    xcode -> appcode

#import "Monkey.h"
#import "SimpleAudioEngine.h"
#import "GMath.h"
#import "GB2Contact.h"

#import "GameLayer.h"
#import "Object.h"

@implementation Monkey {
    GameLayer *__parentLayer;
}

@synthesize isMovingLeft = _isMovingLeft;
@synthesize numbContactWithFloor = _numbContactWithFloor;

-(id)initWithParentlayer:(GameLayer*) theParentLayer{
    __parentLayer = theParentLayer;

    [super initWithDynamicBody:@"monkey" spriteFrameName:@"monkey/idle/2.png"];
    
    if (self){
        [self setFixedRotation:YES];
        [self setBullet:YES];
        
        self.isMovingLeft = NO;
        _numContactWithFloor = 0;
        
        
        _numContactWithHead = 0;
        _numContactWithLeft = 0;
        _numContactWithRight = 0;
        
        _timePassed = 0.3;
        
        _animatePhase = 1;

        _health = 100;


        
    }
    
    return self;
}

// 自己实现动画效果  周期性的改变自己展示的图形
-(void)updateCCFromPhysics{
    [super updateCCFromPhysics]; //使物体 先服从box2d中原有的物理规律


    if (_health < 0) {
        return;
    }

    
    float impulse = self.mass * 0.5;
    float velocityX = [self linearVelocity].x;
    
    float velocityY = [self linearVelocity].y;
    
    //CCLOG(@"v y is %f", velocityY);
    
    if (velocityY > 8){
        //body->SetLinearDamping(0.6);
        self.linearVelocity = b2Vec2(velocityX, 0.6 * velocityY);
    }
    
    //使猴子水平移动
    if (_isMovingLeft && velocityX > -1.0){
        [self applyLinearImpulse:b2Vec2(-impulse, 0) point:self.worldCenter];
    } else if (!_isMovingLeft && velocityX < 1.0){
        [self applyLinearImpulse:b2Vec2(impulse, 0) point:self.worldCenter];
    }

    // 设置猴子 在屏幕显示什么图片 实现动画效果
    [self setMonkeyDisplayFrame];

    // 计算猴子已经被困多长时间
    if (_numContactWithHead > 0){
        _trappedCount ++;

        if (_trappedCount > 60){
            [self setPhysicsPosition:b2Vec2FromCC(ccNode.position.x,
            __parentLayer.heapHeight)];
        }
    }
    else{
        _trappedCount = 0;
    }


    float curRelevateScore = 1.0 *   [self ccNode].position.y - 75;

    if (self.score < curRelevateScore){
        self.score = curRelevateScore;
    }



}


// 设置猴子应该显示那一张图片 实现动画效果
- (void)setMonkeyDisplayFrame {

    _timePassed -= 1.0f / 60.0f;

    if (_timePassed <= 0){
        _animatePhase++;

        if (_animatePhase >= 3){
            _animatePhase = 1;
        }


        _timePassed = 0.3;
    }

    NSString* frameName;
    NSString* dir;
    float monkeyVelocityLengthSquare = [self linearVelocity].LengthSquared();

    dir = _isMovingLeft ? @"left":@"right";

    //CCLOG(@"v square is %f", monkeyVelocityLengthSquare);

    if ( monkeyVelocityLengthSquare < 0.3){
        if (_numContactWithHead > 0){
            frameName = @"arms_up";
        }
        else{
            frameName = @"idle/2";
        }
    }
    else {
        if (_numContactWithFloor < 0){

            frameName = [NSString stringWithFormat:@"jump/%@", dir];
        }
        else{
            if (_numContactWithLeft > 0 && _isMovingLeft){
                frameName = [NSString stringWithFormat:@"push/%@_%d", dir, _animatePhase];
            }
            else if (_numContactWithRight > 0 && !_isMovingLeft){
                frameName = [NSString stringWithFormat:@"push/%@_%d", dir, _animatePhase];
            }
            else{
                frameName = [NSString stringWithFormat:@"walk/%@_%d", dir, _animatePhase];
            }
        }
    }

    NSString* completeFrameName = [NSString stringWithFormat:@"monkey/%@.png", frameName];

    [self setDisplayFrameNamed:completeFrameName];
}

-(void)jump{

    if (_health < 0)
    {
        return;
    }

    if (_numContactWithFloor <=0){
        return; //离地 的时候不需要再施加冲量了
    }
    
    float factor = 1.0f;
    if (_numContactWithHead > 0){
        factor = 3.0f;
    }
    
    [self applyLinearImpulse:b2Vec2(0, self.mass * 6.0 * factor) point:self.worldCenter];
    
    float _pan = ([self ccNode].position.x - 240.0) / 240.0;
    
    [[SimpleAudioEngine sharedEngine] playEffect:@"jump.caf" pitch:gFloatRand(0.8, 1.2) pan:_pan gain:1.0];
}

-(void)beginContactWithFloor:(GB2Contact*) contact{
    _numContactWithFloor ++;
}

-(void)endContactWithFloor:(GB2Contact*) contact{
    _numContactWithFloor --;
}

-(void)beginContactWithObject:(GB2Contact*) contact{

    GB2Node* otherNode = [contact otherObject] ;
    if ([otherNode isKindOfClass:[Object  class]]){   // 如果是香蕉则补充生命值
        Object *other = (Object *)otherNode;
        if ([other.objName isEqualToString:@"banana"]){
            _health += 60;
            if (_health > 100){
                _health = 100;
            }
            [other disappear];

            [[SimpleAudioEngine sharedEngine] playEffect:@"gulp.caf"];

            //return;

        } else if ([other.objName isEqualToString:@"bananabunch"]){
            _health += 90;
            if (_health > 100){
                _health = 100;
            }
            [other disappear];


            [[SimpleAudioEngine sharedEngine] playEffect:@"gulp.caf"];


            //return;
        }
    }



    void* str = contact.ownFixture->GetUserData();
    
    NSString* fixId = (NSString*)str;
    
    if ([fixId isEqualToString:@"head"]){
        _numContactWithHead ++;


        GB2Node* otherNode = [contact otherObject]    ;
        if ([otherNode isKindOfClass:[Object  class]]){
            b2Vec2 otherV = [otherNode linearVelocity];

            float otherVY = otherV.y;

            // 造成伤害
            [self hurtHealth:otherNode otherVY:otherVY];

        }


    } else if([fixId isEqualToString:@"push_left"]){
        _numContactWithLeft ++;
    } else if ([fixId isEqualToString:@"push_right"]){
        _numContactWithRight ++;
    } else{
        _numContactWithFloor ++;
    }
}

- (void)hurtHealth:(GB2Node *)otherNode otherVY:(float)otherVY {
    if (otherVY < -0.3) // 另外一个物体是向下运动的  0
            {
                _health += 0.5* otherVY * otherNode.mass;


                [[SimpleAudioEngine sharedEngine] playEffect:@"hurt.caf" pitch:1.0 pan:1.0 gain:2.0];

                CCLOG(@"health is %f", _health);

                if (_health < 0){
                    [self setFixedRotation:NO];

                    [self setCollisionMaskBits:0x0001]; // 是猴子只和 地面发生碰撞

                    [self setDisplayFrameNamed:@"monkey/dead.png"];
                }

            }
}

-(void)endContactWithObject:(GB2Contact*) contact{
    void* str = contact.ownFixture->GetUserData();
    
    NSString* fixId = (NSString*)str;
    
    if ([fixId isEqualToString:@"head"]){
        _numContactWithHead --;
    } else if([fixId isEqualToString:@"push_left"]){
        _numContactWithLeft --;
    } else if ([fixId isEqualToString:@"push_right"]){
        _numContactWithRight --;
    } else{
        _numContactWithFloor --;
    }
}



@end



//
//  Object.h
//  MonkeyJump
//
//  Created by Mac on 14-3-10.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//

#import "GB2Sprite.h"

@interface Object : GB2Sprite
{
    NSString* _objName;

    GB2Node* _contactOtherObjNames[50]; //和那些物体又接触

    int _numContacts;
}

@property (assign, nonatomic) int numContacts;
@property (retain, nonatomic) NSString *objName;

-(id)initWithObjName:(NSString*) theObjName;
+(id)randomObject;

-(id)disappear;

@end



//
//  Object.m
//  MonkeyJump
//
//  Created by Mac on 14-3-10.
//  Copyright (c) 2014年 codeandweb.de. All rights reserved.
//

#import "Object.h"
#import "GMath.h"
#import "GB2Contact.h"
#import "SimpleAudioEngine.h"

@implementation Object {
    bool _hasBeginDisappearAction;
}

@synthesize objName = _objName;
@synthesize numContacts = _numContacts;

-(id)initWithObjName:(NSString*) theObjName
{
    NSString* pngName = [NSString stringWithFormat:@"objects/%@.png", theObjName];
    // GB2Sprite
    [super initWithDynamicBody:theObjName spriteFrameName:pngName];
    
    if (self){
        _objName = theObjName;

        _numContacts = 0;

        _hasBeginDisappearAction = NO;
    }
    
    return self;
}
+(id)randomObject{
    int type = rand() % 7;
    
    NSString* myObjName = @"backpack.png";
    
    switch (type) {
        case 0:
            myObjName = @"backpack";
            break;
        case 1:
            myObjName = @"statue";
            break;
        case 2:
            myObjName = @"banana";
            break;
        case 3:
            myObjName = @"bananabunch";
            break;
        case 4:
            myObjName = @"hat";
            break;
        case 5:
            myObjName = @"pineapple";
            break;
        case 6:
            myObjName = @"canteen";
            break;
            
        default:
            break;
    }
    
    return [[[Object alloc] initWithObjName:myObjName] autorelease];
}

- (id)disappear {

    // 消失动画
    if (NO == _hasBeginDisappearAction)
    {
        CCSpawn *outAction = [CCSpawn actions:
                [CCScaleTo actionWithDuration:0.2 scale:0.0],
                [CCFadeOut actionWithDuration:0.2],
                nil];


        CCCallFunc *deleteAction = [CCCallFunc actionWithTarget:self selector:@selector(deleteNow)];

        [self runAction:[CCSequence actions:outAction, deleteAction, nil ]];

        _hasBeginDisappearAction = YES;
    }

    return nil;
}


-(void)beginContactWithObject:(GB2Contact*)contact{

    GB2Node *other_ = (contact.otherObject);
    _contactOtherObjNames[_numContacts] = other_;

    _numContacts ++;

    if (_numContacts >= 50){
        ;
    }


    b2Vec2 v = [self linearVelocity];
    
    if (v.LengthSquared() < 3){
        return;
    }


    // 播放声音
    NSString* cafName = [NSString stringWithFormat:@"%@.caf",_objName];
    
    float pan = ([self ccNode].position.x - 240.0) / 240.0;
    
    //
    [[SimpleAudioEngine sharedEngine] playEffect:cafName pitch:gFloatRand(0.8, 1.2) pan:(pan) gain:1.0];





}

-(void)endContactWithObject:(GB2Contact*) contact{
    _numContacts --;

    if (_numContacts < 0){
        ;
    }
}

-(void)beginContactWithFloor:(GB2Contact*) contact{
    [self beginContactWithObject:contact];

    //_numContacts ++;
}

-(void)endContactWithFloor:(GB2Contact*) contact{
    
    _numContacts --;

    if (_numContacts < 0){
        ;
    }
}


-(void) dealloc{
    [_objName release];
    [super dealloc];
}
@end


你可能感兴趣的:(cocos2d视频教程进阶篇--第3天--猴子跳跳游戏)