Cocos2d-x 3.0正式版 HelloWorld分析

我們不管是對於一款編程語言的學習,還是對一個遊戲引擎的學習,第一個基本都是HelloWorld,那麼我們現在來分析一下,Cocos3.0正式版的HelloWord  又有哪些改進?


我們可以對比2.2版本的Cocos,現在3.0的HelloWord已經改名爲cpp-empty-test。這次我們來分析一下這個cpp-empty-test


運行程序,我們可以看到熟悉的HelloWorld程序:




和之前cocos2d-x2.x版本的HelloWorld看起來沒太大差別,主要改變有三點:


標題文字顯示爲Cpp Empty Test。


按鈕由下面改到了上面。


左下角的信息顯示有所不同,以前顯示的是批次  每幀的平均運行秒數FPS數,現在改成了 OPENGL的頂點數量   OPENGL的批次   FPS數/每幀的平均運行秒數。


說了一堆蛋疼的廢話  現在來具體看下工程代碼:




我們可以看到Visual Studio工程下目錄有兩個


分別是:

  Classes:程序中的類。


{
      AppDelegate.h   AppDelegate.cpp:Cocos2d-x程序框架


       AppMacros.h    主要是設置分辯率及對應的資源目錄                


       HelloWorldScene.h  HelloWroldScene.cpp   場景顯示層


}

win32:WIN32程序的主函數

{
       main.cpp   winMain主函數
}

在WinMain函數中,只有一個實例化程序並運行它的過程:

int APIENTRY _tWinMain(HINSTANCE hInstance,

                       HINSTANCE hPrevInstance,

                       LPTSTR    lpCmdLine,

                       int       nCmdShow)

{

    UNREFERENCED_PARAMETER(hPrevInstance);

    UNREFERENCED_PARAMETER(lpCmdLine);


    // 創建一個程序對象。

    AppDelegate app;

// Run起來。

    return Application::getInstance()->run();

}


 一切,都被封裝到程序類AppDelegate中。這是一個基於Cocos2d-x的cocos2d::Application

類的派生類。它將程序框架封裝爲一個類,提供了統一的多平臺上基本程序框架的實現。


AppDelegate.cpp:

#include "AppDelegate.h"

#include <vector>
#include <string>

#include "HelloWorldScene.h"
#include "AppMacros.h"

USING_NS_CC;
using namespace std;

AppDelegate::AppDelegate() {

}

AppDelegate::~AppDelegate() 
{
}

//初始化函數
bool AppDelegate::applicationDidFinishLaunching() {
    // 取設備
    auto director = Director::getInstance();
	// 取OpenGL
    auto glview = director->getOpenGLView();
    if(!glview) {
	    //如果爲空,創建 Cpp Empty Test的窗口。
        glview = GLView::create("Cpp Empty Test");	
	    //設置設備使用的窗口,這一句可以去掉。
        director->setOpenGLView(glview);
    }
     //設置設備使用的窗口。
    director->setOpenGLView(glview);

    // 是WP8平臺,設置分辯率
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
	// 在WP8上跑DX11,使用ResolutionPolicy::NO_BORDER模式設置分辯率會有一個BUG,這裏改爲ResolutionPolicy::SHOW_ALL模式。  

    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::SHOW_ALL);
#else
    glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER);
#endif

	//取得了視窗的大小
	Size frameSize = glview->getFrameSize();
    
    vector<string> searchPath;

    //根據視窗大小與分辯率的大小選擇相應的資源目錄。

    //ipadhd
	if (frameSize.height > mediumResource.size.height)
	{
        searchPath.push_back(largeResource.directory);

        director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height, largeResource.size.width/designResolutionSize.width));
	}
    //ipad
    else if (frameSize.height > smallResource.size.height)
    {
        searchPath.push_back(mediumResource.directory);
        
        director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height, mediumResource.size.width/designResolutionSize.width));
    }
    //iphone
	else
    {
        searchPath.push_back(smallResource.directory);

        director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height, smallResource.size.width/designResolutionSize.width));
    }
    
    // 設置資源目錄
    FileUtils::getInstance()->setSearchPaths(searchPath);
	
    // 打開FPS顯示
    director->setDisplayStats(true);

    // 設置每秒60幀
    director->setAnimationInterval(1.0 / 60);

    // 創建HelloWorld場景
    auto scene = HelloWorld::scene();

    // 運行場景
    director->runWithScene(scene);

    return true;
}

// 當打電話時,遊戲跳到後臺,響應這句
void AppDelegate::applicationDidEnterBackground() {
    Director::getInstance()->stopAnimation();

    // 如果使用聲音文件,下面可以用這句代碼暫停
    // SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

// 當電話打完以後,選擇恢復遊戲時,響應這句
void AppDelegate::applicationWillEnterForeground() {
    Director::getInstance()->startAnimation();

    // 如果使用聲音文件,下面可以用這句代碼恢復
    // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}


代碼跟之前版本差別不大,要注意的是,cocos2d-x 3.0版本使用了auto自動類型變量,這個是C++11的新標準,比如原來要指定變量是int  float  double char,現在可以用auto,在賦值的時候,編譯器會自動識別類型。  很方便吧



        下面我們來看一下HelloWorld場景,它是一個基於cocos2d::Layer的派生類。cocos2d::Layer是什麼?在這裏,打個比方來建立一些基本的認知,比方說我們日常生活拍一部電影。從Cocos2d-x的框架體系來看,director是一個電影的導演   比如在北京拍  北京就是一個Scene   在王府井取一個景  那個王府井就是一個Layer  在王府井拍一個景的話 我們需要演員  也就是Sprite   演員需要有一些肢體語言的動作 也就是我們的Action   這樣 相信大家也有一定的瞭解了吧。


        一個程序要想表現出精彩的世界,要先建立一個Scene,然後增加Layer,然後在這些Layer上增加相應的人。而我們站在Layer上 也會跟着一起運動也就形成了Cocos中的Action。


  OK,現在我們來看一下如何創建Scene和Layer:

HelloWorldScene.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
    // 初始化
    virtual bool init();  

    // 靜態函數創建Scene
    static cocos2d::Scene* scene();
    
    // 響應按鈕退出程序
    void menuCloseCallback(Ref* sender);
    
    // 增加一個靜態的create函數來創建實例。
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__
   
	HelloWorldScene.cpp:

#include "HelloWorldScene.h"
#include "AppMacros.h"
//使用Cocos2d-x命名空間
USING_NS_CC;
//靜態函數創建場景
Scene* HelloWorld::scene()
{
    // 創建一個Scene,即剛纔電影提到的北京
    auto scene = Scene::create();
    
    // 創建一個Layer,即王府井
    HelloWorld *layer = HelloWorld::create();

    // 將王府井這一個層放到北京這個大場景中
    scene->addChild(layer);

    return scene;
}

// 初始化
bool HelloWorld::init()
{
    //先進行初始化
    if ( !Layer::init() )
    {
        return false;
    }
    //取得分辯率的大小及原點座標
    auto visibleSize = Director::getInstance()->getVisibleSize();
    auto origin = Director::getInstance()->getVisibleOrigin();

    // 創建一個菜單項,它由兩張圖片來表現普通狀態和按下狀態,設置按下時調用menuCloseCallback函數響應關閉
    auto closeItem = MenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));
    
    closeItem->setPosition(origin + Point(visibleSize) - Point(closeItem->getContentSize() / 2));

    //由菜單項創建菜單.
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    this->addChild(menu, 1);
    
    //創建一個文字標籤
    auto label = LabelTTF::create("Hello World", "Arial", TITLE_FONT_SIZE);
    
    // 設置居中顯示
    label->setPosition(Point(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));

    // 將文字標籤放到當前Layer中。
    this->addChild(label, 1);

    // 增加一個圖片精靈
    auto sprite = Sprite::create("HelloWorld.png");

    // 設置居中顯示
    sprite->setPosition((ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    //將Sprite放到當前Layer中。
    this->addChild(sprite);
    return true;
}

//響應菜單按下時的事件處理
void HelloWorld::menuCloseCallback(Ref* sender)
{
	//如果是WP8平臺,彈出消息框提示一下。
#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::getInstance()->end();
	//退出程序
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

Layer中增加了Sprite(精靈),Menu(按鈕),LabelTTF(文字)等表現物,有了這些表現物,一個Layer(層)才有價值。


好了  學習的時間總是過的很快,珍惜現在,展望未來,我們下次再見:)


By:Net Fly


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章