[转注自官网]Cocos2d-x Tutorial 2 - 添加精灵图片(Glede Edition for 2.0.3)

Chapter2 – 添加精灵图片

1.添加图片资源

接着我们上一章的进度,我们创建了一个 Cocos2dxSimpleGame 项目,在COCOS2DX_HOME下建立了一个Cocos2dSimpleGame的文件夹,并且能够在Win32平下下运行了。

现在我们要把三张图片添加到我们的项目中,这是Ray Wenderlich的太太的作品,作为这个简单的小游戏的主角儿。(分别为"Player.png"、"Target.png"、"Projectile.png")

要加入资源的方法很简单,只要把图片文件加入到COCOS2DX_HOME\Cocos2dxSimpleGame\Resources 文件夹内,新版本的Cocos2d-x的HelloWorld已经把Resources文件夹设置为工作目录了,这样在项目生成运行的时候就可以找到它们。

但是如果要从生成的可执行文件启动游戏,那么必须要让你的图片资源在可执行文件所在的目录下,就是说你要手动把Resources文件夹里的内容都复制到可执行文件所在的目录:Cocos2dxSimpleGame\Debug.win32 或者是 Release.win32里。

但是我们这样的懒人,一定要懒到骨头里,让系统自动完成这一步:

回到Visual Studio 2012,在Cocos2dSimpleGame.win32项目上 “右键->属性”。

在左侧找到”生成事件->后期生成事件”:[转注自官网]Cocos2d-x Tutorial 2 - 添加精灵图片(Glede Edition for 2.0.3)_第1张图片

 

将左上角的“配置”改为“所有配置”,以确保我们同时修改了 Debug 和 Release的配置

[转注自官网]Cocos2d-x Tutorial 2 - 添加精灵图片(Glede Edition for 2.0.3)_第2张图片

 

在“命令行”中添加如下命令行

xcopy /Y /E $(ProjectDir)..\Resources\* $(OutDir)

[转注自官网]Cocos2d-x Tutorial 2 - 添加精灵图片(Glede Edition for 2.0.3)_第3张图片

 

2.添加精灵图片

接下来我们要通过代码将图片添加到我们的游戏场景里。打开 HelloWorldScene.cpp 源文件,替换 init 方法。

这是原来的init代码:

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    bool bRet = false;
    do 
    {
        //////////////////////////////////////////////////////////////////////////
        // super init first
        //////////////////////////////////////////////////////////////////////////

        CC_BREAK_IF(! CCLayer::init());

        //////////////////////////////////////////////////////////////////////////
        // add your codes below...
        //////////////////////////////////////////////////////////////////////////

        // 1. Add a menu item with "X" image, which is clicked to quit the program.

        // Create a "close" menu item with close icon, it's an auto release object.
        CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
            "CloseNormal.png",
            "CloseSelected.png",
            this,
            menu_selector(HelloWorld::menuCloseCallback));
        CC_BREAK_IF(! pCloseItem);

        // Place the menu item bottom-right conner.
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));

        // Create a menu with the "close" menu item, it's an auto release object.
        CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
        pMenu->setPosition(CCPointZero);
        CC_BREAK_IF(! pMenu);

        // Add the menu to HelloWorld layer as a child layer.
        this->addChild(pMenu, 1);

        // 2. Add a label shows "Hello World".

        // Create a label and initialize with string "Hello World".
        CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
        CC_BREAK_IF(! pLabel);

        // Get window size and place the label upper. 
        CCSize size = CCDirector::sharedDirector()->getWinSize();
        pLabel->setPosition(ccp(size.width / 2, size.height - 50));

        // Add the label to HelloWorld layer as a child layer.
        this->addChild(pLabel, 1);

        // 3. Add add a splash screen, show the cocos2d splash image.
        CCSprite* pSprite = CCSprite::create("HelloWorld.png");
        CC_BREAK_IF(! pSprite);

        // Place the sprite on the center of the screen
        pSprite->setPosition(ccp(size.width/2, size.height/2));

        // Add the sprite to HelloWorld layer as a child layer.
        this->addChild(pSprite, 0);

        bRet = true;
    } while (0);

    return bRet;
}

 

原来的Hello World添加了背景啊Label啊按钮啊什么的,这里不需要他们。简单地换成下面的C++代码。

// cpp with cocos2d-x
bool HelloWorld::init()
{
    if ( CCLayer::init() )
    {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
        CCSprite* player = CCSprite::create("Player.png", CCRectMake(0, 0, 27, 40));

        player->setPosition( ccp(player->getContentSize().width/2, 
                              winSize.height/2) );
        this->addChild(player);
     
     return true;
    }
    return false;
}

 

 

这段代码,实际上是以下obj-c的翻译。

// objc with cocos2d-iphone
-(id) init
{
  if( (self=[super init] )) 
  {
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    CCSprite *player = [CCSprite spriteWithFile:@"Player.png" 
                                  rect:CGRectMake(0, 0, 27, 40) ];
    player.position = ccp(player.contentSize.width/2, 
                          winSize.height/2);
    [self addChild:player];
  }
  return self;
} 

 

TIPS 1

译注:原文是从objc程序猿的角度写的从objc代码翻译到C++代码,因为很多人是从cocos2d-iphone过渡到cocos2d-x。但我们都是C++/java程序猿,看起来好像不需要这些知识。事实上虽然用不着写objc,但是cocos2d-x有关的API的介绍很多只有写在cocos2d-iphone的教程里,要学好cocos2d-x我们还是需要看懂一些obj-c的代码的。我作为一个C++/java程序猿,从我们的角度解释一下这两种语言的一些差别,使大家基本能看懂一些objc的代码。

1.objc中有super,代表当前类的父类,可以用来继承父类的函数,和java也不太一样。C++里的一般做法是直接用父类的类名调用表示继承,像这样CCLayer::init()。实际上C++里也有__super关键字,但它只能被VC++识别,而GCC编译器不认它,我们的项目是跨平台的,一定会经过GCC和苹果的编译器,所以我们最好的还是使用C++的一般做法。

2.objc中有属性这个概念(property,就像C#),所以能够直接调"player.contentSize",并不代表它是public的。而C++就需要和java里一样写get/set方法了。

3.同样的objc程序猿能够写"player.position = ...",C#程序猿能写"player.Position = ...",C++/java程序猿继续setPosition(...)一脸。

4.幸亏还有一些简单的对象是结构体,比如CCSize、CCPoint,在C++里也能直接访问其成员。

5.关于objc里的成员函数——objc里叫消息,他的意思就是给某个类或者对象发送一个消息,他和函数的写法完全不一样,在C++/java程序猿看来objc的成员函数调用是非常奇葩的。首先它用一个中括号表示一个成员函数调用(无论是静态的,还是不是静态的)。中括号里先写对象名或者类名,然后用一个空格分隔,再写调用的函数名。我们假设一个对象Talker,他有个talk方法。对于没有参数函数就是这样:

[对象名/类名 函数名];

[Talker talk];

如果函数有一个参数,那么要在函数名右边加一个冒号,然后写上那个参数。像这样:

[对象名/类名 函数名: 参数1];

[Talker talk: para1];

如果你有多个参数,那么你要在上一个参数后面再写一个空格,一个提示表示参数意义,跟上冒号,再写参数。像这样:

[对象名/类名 函数名: 参数1 提示: 参数2 提示: 参数3];

[Talker talk: para1 content: para2 time: para3];

可是有个问题呀,后面的参数倒是有了提示符,知道他们什么意义了,第一个参数却不知道什么意义的,所以objc程序猿会在函数名中直接提示第一个参数的意义:

[对象名/类名 函数名: 参数1 提示: 参数2 提示: 参数3];

[Talker talkToTalker: para1 content: para2 time: para3];

而如果你有可变个数的参数,要用逗号分隔它们。像这样:

[对象名/类名 函数名: 参数1, 参数2, ...];

[Talker talkToTalker: para1, para2, ...];

看看上文出现过objc的例子,能看懂了吧?比如

CCSprite *player = [CCSprite spriteWithFile:@"Player.png" rect:CGRectMake(0, 0, 27, 40) ];

包括这些在内的静态构造方法,在新版的cocos2d-x里已经改成对C++程序猿来说比较容易理解的create()方法了。这略蛋疼的函数调用,作为我们C++/java程序猿只要能看懂就行。

6.cocos2d-iphone里经常用到有很多与CGGeometry有关的方法,比如 CGRectMake, CGPointMake, CGSizeMake, CGPointZero, CGSizeZero, CGRectZero。还有一些别的NS、UI开头的来自于iOS的类,在cocos2d-x里统一都是CC开头。细心的你看到了C++代码中的CCRectMake和objc代码里的CGRectMake了吗?

7.所有cocos2d-x的游戏元素比如sprite、layer、scene、label、action,都应该用指针调用。

8.C++/java里有this,objc里呢叫做self。一物一人的感觉……

9.objc程序猿喜欢用一个叫id的东西,有点像void*一样的指针,可以指一切,C++里我们思路很正常,用各种*。同时在cocos2d-x里的init方法返回值是bool,需要写一个分支的return,这和cocos2d-iphone不一样。

10.安卓上有个titile bar会占用屏幕空间,所以玩家的位置要加一个40。ccp(player.contentSize.width/2 + 40, winSize.height/2)。

 

好了,言归正传我们现在跑一遍。就看到黑色背景中有一只黑色的,忍者?这玩起来比较郁闷,所以我们改一下背景颜色。首先要改一下HelloWorldScene.h的声明:

C++

// cpp with cocos2d-x
class HelloWorld : public cocos2d::CCLayerColor

objc

// objc with cocos2d-iphone
@interface HelloWorld : CCLayerColor

 

然后改一下init方法里的继承父类方法,原来是这样:

if ( CCLayer::init() )

改成这样~

if ( CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )

ccc4是一个宏,能生成一个rgba颜色。

再给你们看一个objc的对比

// objc with cocos2d-iphone
if ( self = [super initWithColor:ccc4(255,255,255,255)] )

 

TIPS 2

1.对于objc程序员来说默认的继承是public的,C++程序猿都知道默认的继承是private……所以我们要手写public。

2.cocos2d-iphone的大佬Ricardo Quesada建议cocos2d-x要使用命名空间,我们在C++里主要用到两个命名空间cocos2d,和CocosDenshion。顺便一提cocos2d定义了一个宏表示使用cocos2d命名空间,我们可以简单地这样写:

USING_NS_CC;

 

好现在跑一下吧,你应该能看到一片苍茫之中,孤单的主人公。。。

[转注自官网]Cocos2d-x Tutorial 2 - 添加精灵图片(Glede Edition for 2.0.3)_第4张图片

 

 

 

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