FlyingPacer

导航

Cocos2dx For Multi-Platform: Chapter 2 - How to Add a sprite

Chapter 2 - How to Add a sprite

This article is written by Walzer and FlyingPacer, all rights reserved.

(http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Chapter_2_-_How_to_Add_a_sprite)

  • Chapter 2 - How to Add a sprite
    • 1. Add image resources
      • 1.1 add resources on iphone
      • 1.2 add resources on android
      • 1.3 add resources on win32
      • 1.4 add resources on WoPhone
    • 2. Add a sprite
      • TIPS 1
      • TIPS 2

1. Add image resources

Here’re tree images made by Ray Wenderlich ’s wife. Cocos2dSimpleGame will use them.

After Chapter 1 - Create a New cocos2d-x project with multi-platforms, you must have cocos2d-x/Cocos2dSimpleGameForXXX folder now. Please download these images and copy to cocos2d-x/Cocos2dSimpleGameForXXX/Resource folder

Now return to the IDE of different platforms.

1.1 add resources on iphone

It’s so easy, open Xcode and click Add -> Existing Files from the context menu of Cocos2dSimpleGame/Resource group, add these three images above.
Notice that you should tick the check box of Cocos2dxSimpleGameForIOS in the "Add to Targets" form

1.2 add resources on android

If you run build_native.sh for compilation, you should copy the images to the Resource folder, else you should copy the image files to "assets" folder.

1.3 add resources on win32

Win32 executable files will find the resources from it’s relative path. So we had to copy the images from cocos2d-x/Cocos2dSimpleGameForWin32/Resource folder to cocos2d-x/Debug.win32 folder manually.

But lazy guys like me, can always find lazy ways.
Write this line into Post-Build Event -> Command Line

xcopy /Y /E .\Resource\*.* $(OutDir)
Each time the building completed, VistualStudio will copy the resources to the executable path

1.4 add resources on WoPhone

Using zip resource package on WoPhone games is highly recommended. If you are still not very clear about this, please read How to use ZIP resource package on cocos2d-uphone

In our Cocos2dSimpleGame, you can follow these 3 steps:
1. Compress Cocos2dSimpleGameForWoPhone+/Resources/*.* to a zip file, e.g. Cocos2dSimpleGameForWoPhone.zip. Make sure the images are the root of zip file, it MUST NOT at Coocs2dSimpleGameForWoPhone.zip/Cocos2dSimpleGameForWoPhone/Player.png
2. Copy Cocos2dSimpleGameForWoPhone.zip into D:/Work7/NEWPLUS/TDA_DATA/Data/APPS/Cocos2dSimpleGameForWoPhone/
3. Add 2 lines of code into TG3AppMaiin function of Cocos2dSimpleGameForWoPhone/WoPhone/main.cpp. It looks like this:


#include "AppDelegate.h"
#include "SimpleAudioEngine.h"

Int32 TG3AppMain(const TUChar * pAppID, UInt32 nCmd, void * pCmdParam)
{
cocos2d::CCFileUtils::setResourceZipFile("/NEWPLUS/TDA_DATA/Data/APPS/Cocos2dSimpleGameForWoPhone/Cocos2dSimpleGameForWoPhone.zip");
CocosDenshion::SimpleAudioEngine::setResourceZipFile("/NEWPLUS/TDA_DATA/Data/APPS/Cocos2dSimpleGameForWoPhone/Cocos2dSimpleGameForWoPhone.zip");

AppDelegate app;
app.Run();

return 1;
}

2. Add a sprite

You can see how easy to port cocos2d games from objc to c++ now. Open HelloWorldScene.cpp, replace the init method with following.

 1 bool HelloWorld::init()
2 {
3 bool bRet = false;
4 do
5 {
6 //////////////////////////////////////////////////////////////////////////
7 // super init first
8 //////////////////////////////////////////////////////////////////////////
9
10 CC_BREAK_IF(! CCLayer::init());
11
12 //////////////////////////////////////////////////////////////////////////
13 // add your codes below...
14 //////////////////////////////////////////////////////////////////////////
15
16 // 1. Add a menu item with "X" image, which is clicked to quit the program.
17
18 // Create a "close" menu item with close icon, it's an auto release object.
19 CCMenuItemImage *pCloseItem = CCMenuItemImage::itemFromNormalImage(
20 "CloseNormal.png",
21 "CloseSelected.png",
22 this,
23 menu_selector(HelloWorld::menuCloseCallback));
24 CC_BREAK_IF(! pCloseItem);
25
26 // Place the menu item bottom-right conner.
27 pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
28
29 // Create a menu with the "close" menu item, it's an auto release object.
30 CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, NULL);
31 pMenu->setPosition(CCPointZero);
32 CC_BREAK_IF(! pMenu);
33
34 // Add the menu to HelloWorld layer as a child layer.
35 this->addChild(pMenu, 1);
36
37 /////////////////////////////
38 // 2. add your codes below...
39
40 CCSize winSize = CCDirector::sharedDirector()->getWinSize();
41 CCSprite *player = CCSprite::spriteWithFile("Player.png",
42 CCRectMake(0, 0, 27, 40) );
43 player->setPosition( ccp(player->getContentSize().width/2, winSize.height/2) );
44 this->addChild(player);
45
46 bRet = true;
47 } while (0);
48
49 return bRet;
50 }

Beyonds the close menu, we only add the section of “2. Add your codes below” actually. You can see how to translate cocos2d-iphone codes line by line simply to cocos2d-x multi-platform codes.

 1 // cpp with cocos2d-x
2 bool HelloWorld::init()
3 {
4 if ( CCLayer::init() )
5 {
6 CCSize winSize = CCDirector::sharedDirector()->getWinSize();
7 CCSprite *player = CCSprite::spriteWithFile("Player.png",
8 CCRectMake(0, 0, 27, 40) );
9 player->setPosition( ccp(player->getContentSize().width/2,
10 winSize.height/2) );
11 this->addChild(player);
12 }
13 return true;
14 }
 1 // objc with cocos2d-iphone
2 -(id) init
3 {
4 if( (self=[super init] ))
5 {
6 CGSize winSize = [[CCDirector sharedDirector] winSize];
7 CCSprite *player = [CCSprite spriteWithFile:@"Player.png"
8 rect:CGRectMake(0, 0, 27, 40) ];
9 player.position = ccp(player.contentSize.width/2,
10 winSize.height/2);
11 [self addChild:player];
12 }
13 return self;
14 }

TIPS 1

  1. Don’t use __super in C++ to instead super in objc. The keyworkd __super is only recognized by VC++, but can not compiled by GCC. So you had better to call the name of parent class, CCLayer::init()
  2. There’s no the concept of property. So the properties in objc, we use get/set methods instead. For example, if you want to fetch the contentSize property of CCSprite , you must call sprite->getContentSize() method. The aleph of cotentSize should be trun to capital “C”, then add “get” prefix to it.
  3. Use setter to set the value of properties, “player.position = …” , translate to player->setPosition(…)
  4. But the access to members of structures isn’t following this rule. E.g. there’re no getter/setter wrapper with the “width” & “height” in winSize structure.
  5. You needn’t to explain the usage of each params in parameter list like objc. For example, [CCSprite spriteWithFile …, rect …]; is translated to CCSprite::spriteWithFile(…, …);
  6. We have implemented some frequently used functions of CGGeometry, such as CGRectMake, CGPointMake, CGSizeMake, CGPointZero, CGSizeZero, CGRectZero. You can find them in cocos2dx/include/CGGeometry.h. The featrues of them are the same to iOS.
  7. All the gaming elements in cocos2d-x, such as sprite, layer, scene, label, action, are allocated in the heap. So we must call their methods by “->”
  8. Use keyword “this” in cpp to instead “self” in objc.
  9. The return type of init method is “bool” now. There’s no keyword “id” in cpp, so the methods returning “id” is translated to a object pointer or bool.
  10. For android, the title bar has ocupied some space, so you should set the player's position to ccp(player.contentSize.width/2 + 40, winSize.height/2).

Well, we can build and run the code. Now the ninja is dressed in black, hidden in the black background with red eyes. For the gameplay, we had to change the background to white. It’s so easy, modify HelloWorld to inherit from CCColorLayer instead of CCLayer.

At first, modify the declaration in HelloWorldScene.h

1 // cpp with cocos2d-x
2 class HelloWorld : public cocos2d::CCColorLayer
1 // objc with cocos2d-iphone
2 @interface HelloWorld : CCColorLayer

Then modity the very beginning of HelloWorld::init() from

1 if ( !CCLayer::init() )
2 {
3 return false;
4 }

to

1 if ( !CCColorLayer::initWithColor( ccc4(255,255,255,255) ) )
2 {
3 return false;
4 }

Here’s a bit different to RayWenderlich’s code, because prefer defensive programming. The normal code is if supoer init success, then do bla-bla…, I prefer if init failed, do the error handling first, then continue writing the correct flow. OK, back to the topic. Let’s compare the translation of objc to cpp again

1 // cpp with cocos2d-x
2 if ( CCColorLayer::initWithColor( ccc4(255,255,255,255) ) )
1 // objc with cocos2d-iphone
2 if ( self = [super initWithColor:ccc4(255,255,255,255)] )

TIPS 2

  1. The default permission of inheritance in c++ is private. So the modifier “public” before CCColorLayer is required.
  2. RicardoQuesada, the chief author of cocos2d-iphone , suggest us to use namespace in cocos2d-x. It’s very important to check your invoking of cocos2d-x classes is in “cocos2d” namespace or in “CocosDenshion” namespace

Build and run, then you can see the hero standing lonely in the white background.

  • IPhone
  • Android
  • WoPhone
  • Win32

posted on 2011-03-21 15:29  jieffchinese  阅读(1322)  评论(0编辑  收藏  举报