上一章我們講到說以前的HelloWorld演示更名爲cpp-empty-test。
本章我們來分析一下
運行程序,我們可以看到熟悉的HelloWorld程序:與之前cocos2d-x2.x版本的HelloCpp看起來沒太大差別
主要有三點:
1,標題文字顯示爲Cpp Empty Test。
2,按鈕由下面改到了上面。
3,左下角的信息顯示有所不同
以前顯示的是(1)批次(2)每幀的平均運行秒數(3)FPS數;
現在改成了(1)OPENGL的頂點數量(2)OPENGL的批次(3)FPS數/每幀的平均運行秒數。
具體看下工程代碼:
工程的目錄有兩個
Classes:程序中的類。
- AppDelegate.h/cpp:Cocos2d-x程序框架
- AppMacros.h:所用到的宏,主要是設置分辯率及對應的資源目錄
- HelloWorldScene.h/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;
// 運行它。
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();
}
代碼跟之前版本差別不大,不過這裏要注意,3.0使用了auto自動類型變量,這個是C++11的新標準,比如原來要指定變量是int還是float,現在可以用auto,在賦值的時候,編譯器自動識別類型。下面,我們來看一下HelloWorld場景。它是一個基於cocos2d::Layer的派生類。cocos2d::Layer是什麼?
在這裏,我想打個比方來建立一些基本的認知,比方說我們生活在地球上,地球屬於宇宙內的一部分。從Cocos2d-x的框架體系來看,我們是Sprite精靈,地球是Layer,而宇宙是Scene。一個程序要想表現出精彩的世界,要先建立一個宇宙Scene,然後增加地球,月球,太陽等Layer,然後在這些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中增加了精靈,按鈕,文字等表現物,有了這些表現物,一個Layer才有價值。