[转注自官网]Cocos2d-x Tutorial 3 - 让精灵动起来(Glede Edition for 2.0.3)

Chapter3 – 让精灵动起来

在上一章中我们把主人公放到了场景中。但是只有他一个人显得很孤单,没有怪没有妖,我们给他造。

我们用一个void addTarget()函数来完成这项工作,怪物会以随机的宿舍从场景右侧进入从左侧飞出。

 

首先在HellowWroldScene.h中声明 void addTarget() 函数,然后在HelloWorldScene.cpp中加入源代码(别忘了在HelloWorldScene.cpp的开头使用USING_NS_CC;)

// cpp with cocos2d-x

void HelloWorld::addTarget()

{

    CCSprite *target = CCSprite::create("Target.png", 

        CCRectMake(0,0,27,40) );



    // 决定怪物出现的XY坐标

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    int minY = target->getContentSize().height/2;

    int maxY = winSize.height

                          -  target->getContentSize().height/2;

    int rangeY = maxY - minY;

    // srand( TimGetTicks() );

    int actualY = ( rand() % rangeY ) + minY;



    // 创建怪物的时候让它稍微出一些屏幕

    // 怪物出现位置的Y坐标是随机的

    target->setPosition( 

        ccp(winSize.width + (target->getContentSize().width/2), 

        actualY) );

    this->addChild(target);



    // 通过设定怪物运动所需时间来决定他的速度

    int minDuration = (int)2.0;

    int maxDuration = (int)4.0;

    int rangeDuration = maxDuration - minDuration;

    // srand( TimGetTicks() );

    int actualDuration = ( rand() % rangeDuration )

                                        + minDuration;



    // 创建action

    CCFiniteTimeAction* actionMove = 

        CCMoveTo::create( (float)actualDuration, 

        ccp(0 - target->getContentSize().width/2, actualY) );

    CCFiniteTimeAction* actionMoveDone = 

        CCCallFuncN::create( this, 

        callfuncN_selector(HelloWorld::spriteMoveFinished));

    target->runAction( CCSequence::create(actionMove, 

        actionMoveDone, NULL) );

}

 对应的objc代码

// objc with cocos2d-iphone

-(void)addTarget 

{

  CCSprite *target = [CCSprite spriteWithFile:@"Target.png" 

                                rect:CGRectMake(0, 0, 27, 40)];



  // Determine where to spawn the target along the Y axis

  CGSize winSize = [[CCDirector sharedDirector] winSize];

  int minY = target.contentSize.height/2;

  int maxY = winSize.height - target.contentSize.height/2;

  int rangeY = maxY - minY;



  int actualY = (arc4random() % rangeY) + minY;



  // Create the target slightly off-screen along the right edge,

  // and along a random position along the Y axis as calculated

  target.position = 

    ccp(winSize.width + (target.contentSize.width/2), 

    actualY);

  [self addChild:target];



  // Determine speed of the target

  int minDuration = 2.0;

  int maxDuration = 4.0;

  int rangeDuration = maxDuration - minDuration;



  int actualDuration = (arc4random() % rangeDuration)

                                  + minDuration;



  // Create the actions

  id actionMove = 

    [CCMoveTo actionWithDuration:actualDuration

          position:ccp(-target.contentSize.width/2, actualY)];

  id actionMoveDone = 

    [CCCallFuncN actionWithTarget:self

                selector:@selector(spriteMoveFinished:)];

  [target runAction:[CCSequence actions:actionMove, 

                    actionMoveDone, nil]]; 

} 

 

在这里,我们设定的动作将actionMove和actionMoveDone串起来,使怪物结束运动之后会通过callfuncN_selector(HelloWorld::spriteMoveFinished) 会回调 HelloWorld::spriteMoveFinished() 方法,我们要在 HelloWorldScene.h声明它(记得CCNode的命名空间),也同样在HelloWorldScene.cpp里定义它,代码如下。

// cpp with cocos2d-x

void HelloWorld::spriteMoveFinished(CCNode* sender)

{

  CCSprite *sprite = (CCSprite *)sender;

  this->removeChild(sprite, true);

}

objc代码

// objc with cocos2d-iphone

-(void)spriteMoveFinished:(id)sender 

{

  CCSprite *sprite = (CCSprite *)sender;

  [self removeChild:sprite cleanup:YES]; 

} 

 

TIPs:

1.关于 int rand() 随机函数,srand 和 rand都是c标准函数, 一招鲜吃遍天什么平台都能用。用系统毫秒时间作为种子就能得到一个不错的随机效果。

2.C++里是true和false,objc里有YES和NO。

3.我们知道C里有函数指针,但是C++你可以把一个类的静态成员函数用作函数指针传递,这没问题,但是非静态的成员函数做起来就比较麻烦了,objc里有@selector这个东西能够指定对象传递消息,为了能够继续保持这个习惯(事实上这很方便),cocos2d-x在C++里实现了类似的selector,可以参考他们的声明:cocos2dx\include\selector_protocol.h。一共有5种不同的回调类型:

  • schedule_selector
  • callfunc_selector
  • callfuncN_selector
  • callfuncND_selector
  • menu_selector

根据定义去调用就可以了。比如对于函数

    static CCCallFuncN * create(CCObject* pSelectorTarget, SEL_CallFuncN selector);

看到第二个参数是SEL_callFunN类型的回调函数,你就需要根据SEL_callFunN的定义:

typedef void (CCObject::*SEL_CallFuncN)(CCNode*);

去定义一个返回值是void,只有一个CCNode类型参数的函数(比如我们的HelloWorld::spriteMoveFinished),然后使用callFuncN_selector()宏,将函数名字括起来……像这样:

callFuncN_selector(HelloWorld::spriteMoveFinished)

这就是create第二个参数了!没跑。

 

言归正传我们继续造妖怪。然后我们要让妖怪隔几秒一段时间一只一只地进来,要在HelloWorld::init方法里添加如下代码:

// cpp with cocos2d-x

// 每秒呼叫 HellowWorld::gameLogic 函数一次

this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 );

 

objc代码

// objc with cocos2d-iphone

// Call game logic about every second

[self schedule:@selector(gameLogic:) interval:1.0];

 

同样的我们要在HelloWorldScene.h声明一下gameLogic函数,要把它声明成public。然后在HelloWorldScene.cpp里实现如下:

// cpp with cocos2d-x

void HelloWorld::gameLogic(float dt)

{

    this->addTarget();

}

objc代码

// objc with cocos2d-iphone

-(void)gameLogic:(float)dt

{

    [self addTarget];

}

 

好那么完工了,生成一下,跑跑看,大师兄妖怪来了!

[转注自官网]Cocos2d-x Tutorial 3 - 让精灵动起来(Glede Edition for 2.0.3)

 

你可能感兴趣的:(cocos2d-x)