Cocos2dx.3x入门三部曲-Hello Game项目解析(三)

1、前提:html

完成Hello Game项目的建立编译。android

具体参考:Cocos2dx.3x_Hello Game项目建立篇ios

2、本篇目标:windows

l  分析proj.win32工程的主要构成app

l  分析proj.android工程的主要构成eclipse

l  新建一个MyScene.cpp而后在游戏中显示出来编辑器

l  在android真机上运行查看效果工具

3、分析:性能

咱们游戏开发一般是这样的,首先在Microsoft Visual Studio 2012中proj.win32工程编写代码而且在windows上调试运行,当游戏主体开发完成后,进行so文件的编译打包,而后继续在eclipse的proj.android工程中编写少许的代码完成游戏在android平台下的打包开发。this

l  分析proj.win32工程的主要构成

用Microsoft Visual Studio 2012打开proj.win32工程

组成:

整个hellogame的解决方案由hellogame、libbox2d、libcocos2d、libSpine四个工程项目构成。

一、Hellogame工程:游戏主工程,咱们开发工做主要在这个工程中完成

二、libbox2d工程:模拟2D刚体物体的C++物理引擎,大名鼎鼎植物大战僵尸、愤怒的小鸟等游戏均有这个引擎的功劳

三、libcocos2d工程:这个不用说了,整个cocos2dx核心

四、libSpine工程:工具软件支持库

接下来主要对Hellogame工程的代码进行解析,libbox2d工程在后面的物理引擎篇的时候在进行讲解,至于其它2个工程在后续使用到的篇幅中在进行讲解。

Hellogame工程的源代码:

工程主要由src目录下的AppDelegate.cpp、AppDelegate.h、HelloWorldScene.cpp、HelloWorldScene.h四个源文件和win32目录下的main.cpp、main.h两个源文件组成。

src目录下的源文件是全部6个平台共用的代码文件,不论是android仍是ios都使用这个目录下的源文件,属于真正跨平台部分的代码。

win32目录下的源文件只是一个main主入口文件,负责win32平台下对游戏的调用。其实在对应的proj.android的工程里也有一个android平台对应的main主入口文件,只是因为平台的不一样实现代码也各有不一样,可是目的同样。

AppDelegate.cpp源代码:

AppDelegate相似于android的Application的做用,提供一些应用程序级别的状态的回调,整个游戏应用程序由这个文件方法进行控制。下面是几个主要方法的说明和解释:

#include "AppDelegate.h"
#include "HelloWorldScene.h"
//命名空间宏,偷懒引入cocos2d的头文件
USING_NS_CC;
AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate() 
{
}

//设置 OpenGL context
//这个设置对全部平台都有效
void AppDelegate::initGLContextAttrs()
{
    //设置 OpenGL context 属性,目前只能设置6个属性
    //red,green,blue,alpha,depth,stencil
    GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
    GLView::setGLContextAttrs(glContextAttrs);
}

//当应用程序启动时执行,游戏程序启动入口
//在这里咱们启动了第一个scene(场景)
//在具体游戏中一般在这里启动loading界面
//你的游戏从这里开始!
bool AppDelegate::applicationDidFinishLaunching() {
    // 初始化 director
    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();
    if(!glview) {
        glview = GLViewImpl::create("My Game");
        director->setOpenGLView(glview);
    }
    // 在屏幕上显示FPS数
    // 开发阶段建议开启这个设置,能够经过这个对本身游戏性能有个大致了解
    // 等游戏正式发布时关闭这个设置
    director->setDisplayStats(true);
    // 设置 FPS数 默认值为 1.0/60 
    director->setAnimationInterval(1.0 / 60);
    // 建立一个HelloWorld的scene.这个是自动回收的对象
    auto scene = HelloWorld::createScene();
    // 告诉director运行HelloWorld的scene
    director->runWithScene(scene);
    return true;
}

// 当游戏进入后台时会调用这个方法
// 好比玩游戏时按下android手机的home按键
// 好比当游戏时有电话打入直接显示来电界面
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();
    // 若是你的游戏使用了SimpleAudioEngine,必须在这里进行暂停
    // 暂停代码以下:
    // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}

// 当游戏恢复到前台运行时会调用这个方法
// 好比接电话结束是游戏界面又恢复到前台时
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();
    // 若是你的游戏使用了SimpleAudioEngine, 必须在这里进行恢复
    // 恢复代码以下:
    // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

上述代码解释中的提到的director(导演:负责游戏场景的显示切换等,像电影导演同样掌控整个电影的一切)、scene(场景:负责显示一个游戏场景,就像电影的一个场景镜头)。

上面代码中最重要的方法为applicationDidFinishLaunching(),由于你的游戏从这个方法开始!

 

HelloWorldScene.cpp源代码:

上面代码中在AppDelegate类的applicationDidFinishLaunching()方法中建立了一个HelloWorldScene的场景,而且运行这个场景,HelloWorldScene.cpp就是这个场景具体的代码实现。下面是几个主要方法的说明和解释:

#include "HelloWorldScene.h"
USING_NS_CC;
//建立场景
Scene* HelloWorld::createScene()
{
    //建立一个自释放的场景对象
    auto scene = Scene::create();
    //建立一个自释放的画面层对象
    auto layer = HelloWorld::create();
    //把建立的画面层添加到场景中
    //一个场景能够添加多个画面层
    scene->addChild(layer);
    //返回这个建立的场景
    return scene;
}

// 场景初始化方法
bool HelloWorld::init()
{
    // 1. 首先进行父类初始化
    if ( !Layer::init() )
    {
        //若是初始化父类失败返回false
        return false;
    }
    
    //获取整个手机可视屏幕尺寸
    Size visibleSize = Director::getInstance()->getVisibleSize();
    //获取手机可视屏原点的坐标
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    // 建立一个带图标的关闭按钮
    // 点击后调用menuCloseCallback方法退出游戏
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    // 设置关闭按钮的显示位置
    // 显示在可视屏幕的右下角
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    // 建立一个可自释放的菜单
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
    //建立一个显示"Hello Game"文字的Label
    auto label = Label::createWithTTF("Hello Game", "fonts/Marker Felt.ttf", 24);
    // 设置label在屏幕中的显示位置
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));
    // 把label添加到画面层
    this->addChild(label, 1);
    // 建立一个带图片的精灵
    auto sprite = Sprite::create("HelloWorld.png");
    // 设置图片精灵的显示位置
    sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    // 添加图片精灵到画面层
    this->addChild(sprite, 0);
    return true;
}

// 退出按钮事件
void HelloWorld::menuCloseCallback(Ref* pSender)
{
//当是wp8或者winrt平台的时候
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif
    //结束Director
    Director::getInstance()->end();
//当是ios平台的时候退出
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

上述的代码是一个简单的Scene(场景)实现代码,当咱们真正开发游戏时,其实就是制做一个一个的场景,而且经过Director进行调度组织构成一个完整的游戏。

 

l  分析proj.android工程的主要构成

用eclipse打开proj.android工程

组成:

整个hellogame的相比win32的要简单多了,除了android项目必须的一些组成部分以外:

一、  Classes文件夹:这里面的源文件和上面proj.win32中的属于同一份共享。

二、  jni/hellocpp/main.cpp:这个至关于proj.win32中的win32目录下的源文件,主入口。

三、  libs/armeabi/libcocos2dcpp.so:这个是整个游戏代码的编译包,其实真正游戏代码实现都最终由C++文件编译打包成这个so类库供android代码调用运行游戏。

整个游戏的开发基本上不须要在eclipse中编写代码,android平台只须要调用编译好的so文件便可运行游戏,eclipse中只须要把包含了so文件的android工程打包成apk文件发布便可。

l  新建一个MyScene.cpp而后在游戏中显示出来

用Microsoft Visual Studio 2012打开proj.win32工程,咱们将在这个工程里新加一个本身的Scence(场景)而且显示出来。这个看着是个很简单的任务可是对新手来讲仍是会碰到不少困难,因此这里特别的作一下演示。

文件新建:cpp文件这里有2个新建方法,

1、第一种方式

第一步:在右边的解决方案资源管理器中右键src新建类。

问题:到这里你会发现“浏览”按钮不能够用,新建的cpp只能新建到目录hellogame\proj.win32下,这样会致使一个问题。

第二步:先无论这个咱们按照提示继续点击“添加”进入类向导界面输入类名MyScene而后点击完成类的建立,这个时候在proj.win32目录下新加MyScene.cpp和MyScene.h两个文件。

2、第二种方式

第一步:在右边的解决方案资源管理器中右键src新建项

问题:到这里你会发现“浏览”按钮能够用,点击修改一下目录为hellogame\Classes下,并且须要选择是新建.ccp文件仍是.h文件.

第二步:这里先选择.cpp类型而后输入MyScene.cpp而后完成建立,而后继续前面的步骤新建MyScene.h文件。这个时候在Classes目录下会出现新加的MyScene.cpp和MyScene.h两个文件。

代码编写:

MyScene.h:

#include "cocos2d.h"
class MyScene : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();
    CREATE_FUNC(MyScene);

};
MyScene.cpp:
#include "MyScene.h"
USING_NS_CC;
Scene* MyScene::createScene()
{
    auto scene=Scene::create();
    auto layer=MyScene::create();
    scene->addChild(layer);
    return scene;
}
bool MyScene::init()
{
    if(!Layer::init())
    {
        return false;
    }
    //获取整个手机可视屏幕尺寸
    Size visibleSize = Director::getInstance()->getVisibleSize();
    //获取手机可视屏原点的坐标
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    //建立一个显示"MyScene"文字的Label
    auto label = Label::createWithTTF("MyScene", "fonts/Marker Felt.ttf", 24);
    //设置白色
    label->setColor(Color3B::WHITE);
    // 设置label在屏幕中的显示位置
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));
    // 把label添加到画面层
    this->addChild(label, 1);
    return true;
}

完成MyScene编写后,咱们要先在游戏开启后的界面中添加一个按钮菜单点击后进入MyScene 场景。游戏开启后的界面场景是HelloWorldScene,因此咱们须要在HelloWorldScene中添加一个按钮,而且为这个按钮添加一个点击启动MyScene的事件。

HelloWorldScene.h

在这个文件中首先声明一个按钮点击事件:

//切换到下一个scene事件

void menuNextCallback(cocos2d::Ref* pSender);

HelloWorldScene.cpp:
1、首先引入MyScene.h
#include "HelloWorldScene.h"
#include "MyScene.h"
USING_NS_CC;
……

2、实现menuNextCallback事件代码
// 按钮点击事件,点击后启动MyScene
void HelloWorld::menuNextCallback(Ref* pSender)
{
    //新建MyScene实例
    auto scene = MyScene::createScene();
    //用这MyScene实例替换当前scene
    Director::getInstance()->replaceScene(scene);
}

4、    添加在屏幕上添加启动按钮
……
// 设置关闭按钮的显示位置
    // 显示在可视屏幕的右下角
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    // 新建一个带图片的按钮菜单
    auto goItem=MenuItemImage::create("next_1.png","next_2.png",
CC_CALLBACK_1(HelloWorld::menuNextCallback, this));
    goItem->setPosition(Vec2(origin.x + visibleSize.width/2 - closeItem->getContentSize().width/2 ,origin.y/2 + closeItem->getContentSize().height/2)); 
    // 建立一个可自释放的菜单
    auto menu = Menu::create(closeItem,goItem, NULL);
    menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
……

好了到此为止咱们完成了全部代码的编写,如今开始调试运行查看一下效果。

 

问题:

这个时候若是你是用第二中方法建立的MyScene能正常编译运行而第一种方法建立的MyScene会发没法经过编译没办法运行会报以下错误:

IntelliSense: 没法打开 源 文件 "MyScene.h"   

error C1083: 没法打开包括文件:“MyScene.h”: No such file or directory

解决:

第一步:项目名点击右键属性

第二步:选择左边的C/C++而后在右边的附加包含目录追添加:;$(ProjectDir)

这个是我本人的附加包含目录,每一个人环境不一样应该有点区别

$(EngineRoot)cocos\audio\include;$(EngineRoot)external;$(EngineRoot)external\chipmunk\include\chipmunk;$(EngineRoot)extensions;..\Classes;..;%(AdditionalIncludeDirectories) ;$(ProjectDir)

完成如上设置后在进行项目调试运行就能正常运行起来了,而且点击按钮后成功的显示MyScene的画面达到了咱们设定的目标。

 

l  在android真机上运行查看效果

要在android真机运行,首先须要进行so文件的打包编译。

第一步:若是上面的步骤中是按照第一种方法建立的MyScene那么请把MyScene.cpp、MyScene.h两个文件从proj.win32文件拷贝到Classes文件夹下。若是是按照第二种方法建立的MyScene那么能够忽略本步骤。

第二步:用EditPlus等文本编辑器打开proj.android\jni目录下的Android.mk文件,把MyScene.cpp添加到须要编译的源文件清单中而后保存,以下:

……

LOCAL_SRC_FILES := hellocpp/main.cpp \

           ../../Classes/AppDelegate.cpp \

           ../../Classes/HelloWorldScene.cpp \

           ../../Classes/MyScene.cpp

……

第三步:开启Cygwin开始编译打包so文件,若是不会请参考:Cocos2dx.3x_Hello Game项目建立篇

第四步:打包so文件成功后,而后开启eclipse打开游戏工程而且链接android手机运行工程看看真机运行的效果是否跟前面windows中的效果是否同样。

结束语:

Cocos2d-x3.3入门三部曲到这里就算是完成了,接下来将以具体一个游戏为一个系列的方式继续深刻实战,第一个实战系列为:《Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始》,这个系列总共有多少篇待定,目标是直到作完一个完整的符合上线标准的游戏为止绝非草草的练习之做。

做者交流QQ:2303452599

           邮箱:mymoney1001@126.com

相关文章
相关标签/搜索