Chapter 3 - How to Move a sprite¶
We have added a hero to the scene in the last chapter Chapter 2 - How to Add a sprite. But the hero is so lonely that we should add some enemies to let him beat down.
The function void addTarget() will complete the work, the enemies will be added into the scene from right to left at random speed.
Declare void addTarget() in HelloWorldScene.h and add the following code to HelloWorldScene.cpp, (and don't forget to add using namespace cocos2d; at the start of HelloWorldScene.cpp)
1
2void HelloWorld::addTarget()
3{
4 CCSprite *target = CCSprite::spriteWithFile("Target.png",
5 CCRectMake(0,0,27,40) );
6
7
8 CCSize winSize = CCDirector::sharedDirector()->getWinSize();
9 int minY = target->getContentSize().height/2;
10 int maxY = winSize.height
11 - target->getContentSize().height/2;
12 int rangeY = maxY - minY;
13
14 int actualY = ( rand() % rangeY ) + minY;
15
16
17
18 target->setPosition(
19 ccp(winSize.width + (target->getContentSize().width/2),
20 actualY) );
21 this->addChild(target);
22
23
24 int minDuration = (int)2.0;
25 int maxDuration = (int)4.0;
26 int rangeDuration = maxDuration - minDuration;
27
28 int actualDuration = ( rand() % rangeDuration )
29 + minDuration;
30
31
32 CCFiniteTimeAction* actionMove =
33 CCMoveTo::actionWithDuration( (ccTime)actualDuration,
34 ccp(0 - target->getContentSize().width/2, actualY) );
35 CCFiniteTimeAction* actionMoveDone =
36 CCCallFuncN::actionWithTarget( this,
37 callfuncN_selector(HelloWorld::spriteMoveFinished));
38 target->runAction( CCSequence::actions(actionMove,
39 actionMoveDone, NULL) );
40}
|
1
2-(void)addTarget
3{
4 CCSprite *target = [CCSprite spriteWithFile:@"Target.png"
5 rect:CGRectMake(0, 0, 27, 40)];
6
7
8 CGSize winSize = [[CCDirector sharedDirector] winSize];
9 int minY = target.contentSize.height/2;
10 int maxY = winSize.height - target.contentSize.height/2;
11 int rangeY = maxY - minY;
12
13 int actualY = (arc4random() % rangeY) + minY;
14
15
16
17 target.position =
18 ccp(winSize.width + (target.contentSize.width/2),
19 actualY);
20 [self addChild:target];
21
22
23 int minDuration = 2.0;
24 int maxDuration = 4.0;
25 int rangeDuration = maxDuration - minDuration;
26
27 int actualDuration = (arc4random() % rangeDuration)
28 + minDuration;
29
30
31 id actionMove =
32 [CCMoveTo actionWithDuration:actualDuration
33 position:ccp(-target.contentSize.width/2, actualY)];
34 id actionMoveDone =
35 [CCCallFuncN actionWithTarget:self
36 selector:@selector(spriteMoveFinished:)];
37 [target runAction:[CCSequence actions:actionMove,
38 actionMoveDone, nil]];
39}
|
Here, callfuncN_selector(HelloWorld::spriteMoveFinished) backcalls the function spriteMoveFinished(), we need to declare it in the HelloWorldScene.h and define it as follows,
1
2void HelloWorld::spriteMoveFinished(CCNode* sender)
3{
4 CCSprite *sprite = (CCSprite *)sender;
5 this->removeChild(sprite, true);
6}
|
1
2-(void)spriteMoveFinished:(id)sender
3{
4 CCSprite *sprite = (CCSprite *)sender;
5 [self removeChild:sprite cleanup:YES];
6}
|
TIPs:
1. About rand function. srand and rand are c std function. For each platform, you could get the mili-second system time as sand to get a random number. On WoPhone, the function is TimGetTickes(), and on IPhone, you could get the random number by arc4random() directly
2. The YES and NO in objc are true and false in cpp
3. The callback function is selector:@selector(spriteMoveFinished) in objc, but it is a little complicated to implement in cpp, you could refer to the declarations in cocos2dx\include\selector_protocol.h. There are five different callback types:
- schedule_selector
- callfunc_selector
- callfuncN_selector
- callfuncND_selector
- menu_selector
How to use them is according to the callback function definition. For example, when use the function CCTimer::initWithTarget whose second parameter is a type of SEL_SCHEDULE, we could find its macro-definition schedule_selector(_SELECTOR) in selector_protocol.h, then we declare a callback function void MyClass::MyCallbackFuncName(ccTime), and transform it as the second parameter of CCTimer::initWithTarget.
Then, we should put the enemies into the scene at intervals, add the codes before init() function returns.
1
2
3this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 );
|
1
2
3[self schedule:@selector(gameLogic:) interval:1.0];
|
and implement gameLogic() in HelloWorldScene.cpp. Notice that gameLogic() should be declared as public, otherwise it won't be backcalled.
1
2void HelloWorld::gameLogic(ccTime dt)
3{
4 this->addTarget();
5}
|
1
2-(void)gameLogic:(ccTime)dt
3{
4 [self addTarget];
5}
|
Ok, everything is done, build and run, and enjoy your fruit.
IPhone 
Android 
WoPhone 
Win32 