cocos2d-x应用窗口相关源码剖析5-其他细节

Cocos2d-x“HelloWorld”细节分析

打开HelloWorld工程,里面有两个文件目录Classeswin32

Classes下有HelloWorldScene.h/cpp,AppDelegate.h/cpp.

win32下有main.h/cpp

首先看一下win32目录下的main.h,其中定义了使用win32平台进行编译的宏和一些Windows编程头文件。

#ifndef __MAIN_H__

#define __MAIN_H__

//定义使用WIN32平台进行编译的宏

#define WIN32_LEAN_AND_MEAN

所用到的Windows编程所用头文件

#include <windows.h>

#include <tchar.h>

// CocosC语言头文件

#include "CCStdC.h"

#endif// __MAIN_H__

再打开main.cpp.

加入main.h头文件

#include "main.h"

加入使用的AppDelegate类头文件

#include "../Classes/AppDelegate.h"

//WinMain主函数

int APIENTRY _tWinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,230)"> LPTSTR lpCmdLine,230)"> int nCmdShow)

{

//UNREFERENCED_PARAMETER用于在VC编译器下告知编译器,不必检测改变量是否使用的警告。

UNREFERENCED_PARAMETER(hPrevInstance);

UNREFERENCED_PARAMETER(lpCmdLine);

创建一个Cocos2d-x程序实例

AppDelegateapp;

//运行程序实例

returncocos2d::CCApplication::sharedApplication().run();

}


代码看着就这么几行,好像非常简单。那是因为Cocos2d-x把很多WINDOWS窗口程序的代码都封装到了内部。这也使得它更加简单易学。但我们也应该明白这里面是怎么一回事。

咱们转到AppDelegate.h,可以看到AppDelegate类是一个私有继承Cocos2d命名空间中的CCApplication类。它的成员函数均是重载了CCApplication类的成员函数。顾名思义,CCApplication代表了程序类。我们打开它的声明文件(CCApplication_win32.h)看一下:

#ifndef __CC_APPLICATION_WIN32_H__

#define __CC_APPLICATION_WIN32_H__

//Windows #include <Windows.h>

//Cocos2d-x公共头文件,声明了一些公共函数以及语言类型枚举ccLanguageType

#include "CCCommon.h"

使用cocos2d的命名空间来包括后面的代码

NS_CC_BEGIN;

声明一下CCRect类,在CCApplication中会用到类指针

class CCRect;

class CC_DLL CCApplication

public:

构造

CCApplication();

析构

virtual ~CCApplication();

初始化

virtual boolinitInstance() = 0;

程序启动后调用的函数,在这里创建设备与场景

virtual boolapplicationDidFinishLaunching() = 0;

当程序转入后台,如电话打入时调用

virtual voidapplicationDidEnterBackground() = 0;

当程序转入前台,再次恢复时调用

virtual voidapplicationWillEnterForeground() = 0;

设备设置FPS时调用的函数,设置帧间隔时间

voidsetAnimationInterval(double interval);

声明一个枚举,列出当前设备的摆放方向

typedef enum

{

///垂直方向键在下面

kOrientationPortrait =0,0)">///键在上面

kOrientationPortraitUpsideDown = 1,0)">水平方向,home键在右边

kOrientationLandscapeLeft = 2,0)">健在左边

kOrientationLandscapeRight = 3,230)"> } Orientation;

改变了摆放方向后调用的函数设置设备摆放方向

OrientationsetOrientation(Orientation orientation);

取得窗口的状态栏所在的矩形位置

void statusBarFrame(CCRect * rect);

运行程序

int run();

取得当前的程序实例,这种用法可参考C++模式设计中的单件模式

static CCApplication&sharedApplication();

取得当前的语言类型

static ccLanguageTypegetCurrentLanguage();

protected:

程序实例句柄

HINSTANCE m_hInstance;

加速键句柄

HACCEL m_hAccelTable;

声明为帧间隔,实际上是每两帧之间的频率次数

LARGE_INTEGER m_nAnimationInterval;

单件的程序实例指针

static CCApplication *sm_pSharedApplication;

};

NS_CC_END;

#endif// __CC_APPLICATION_WIN32_H__



通过对于CCApplication_win32.h的代码分析,我们可以清楚CCApplication的功能是对于程序的控制。

我们转到CCApplication类的cpp文件CCApplication_win32.cpp再来分析一下。

读前小提示:

CCDirector代表显示设备管理器。也是一个单件类。通过其静态函数CCDirector::sharedDirector()来访问唯一的显示设备。

重点关注函数:CCApplication()run()(在CCApplication_win32.cpp

#include "CCApplication.h"

设备头文件

#include "CCDirector.h"

在注册表中写入对于PVRFrame的显示和隐藏的设置

static void PVRFrameEnableControlWindow(bool bEnable);

// CCApplication的静态成员指针变量单件对象指针

CCApplication * CCApplication::sm_pSharedApplication = 0;

构造函数

CCApplication::CCApplication()

: m_hInstance(NULL)

,m_hAccelTable(NULL)

获取当前程序句柄

m_hInstance=GetModuleHandle(NULL);

m_nAnimationIntervalm_nAnimationInterval.QuadPart= 0;

断言程序中只有一个sm_pSharedApplication。确保当前类只有一个实例对象

CC_ASSERT(!sm_pSharedApplication);

设置单件对象指针指向当前类对象实例

sm_pSharedApplication= this;

CCApplication::~CCApplication()

断言程序只有一个就是指向当前类的实例对象

CC_ASSERT(this== sm_pSharedApplication);

sm_pSharedApplication= NULL;

程序运行

int CCApplication::run()

设置注册表隐藏

PVRFrameEnableControlWindow(false);

主消息循环

MSGmsg;

LARGE_INTEGERnFreq;

LARGE_INTEGERnLast;

LARGE_INTEGERnNow;

//WINDOWS高精度定时器的用法,先获取频率

QueryPerformanceFrequency(&nFreq);

获取当前的计数值即频率x当前时间

QueryPerformanceCounter(&nLast);

//initInstance函数为虚函数,由派生类进行了重载。此段代码在调用

AppDelegate重载的initInstance函数之后调用applicationDidFinishLaunching函数完成一

些初始化处理。

:AppDelegate重载函数做了什么我们暂且只先认为它如平时我们

WINDOWS基本框架程序一样创建了一个窗口。【伏笔1后面会有讲解】。

if (!initInstance() || ! applicationDidFinishLaunching())

return0;

取得当前使用的OPENGL窗口管理实例对象

CCEGLView&mainWnd = CCEGLView::sharedOpenGLView();

将窗口居中显示 mainWnd.centerWindow();

ShowWindow(mainWnd.getHWnd(),SW_SHOW);

非常熟悉!进入WINDOWS消息循环

while (1)

如果没有获取到消息

if (!PeekMessage(&msg,NULL,PM_REMOVE))

取得当前的计数值 QueryPerformanceCounter(&nNow);

//m_nAnimationInterval.QuadPart的值setAnimationInterval函数进行设置的固定值。此处是为了判断时间流逝了多久,是否应该更新显示设备 if(nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)

如果时间流逝达到了设定的时间差,则更新计数值。

nLast.QuadPart= nNow.QuadPart;

这里是设备渲染场景的函数,【伏笔2后面会有讲解】

CCDirector::sharedDirector()->mainLoop();

else

//sleep0秒的意义是让CPU做下时间片切换,防止死循环而使系统其它程序得

不到响应。

Sleep(0);

continue;

有消息获取到 if (WM_QUIT== msg.message)

如果获取的消息是退出则退出循环。

break;

如果没有定义加速键或者处理完加速键信息

if (!m_hAccelTable || ! TranslateAccelerator(msg.hwnd,m_hAccelTable,&msg))

处理消息 TranslateMessage(&msg);

DispatchMessage(&msg);

return(int) msg.wParam;

外部调用的设置帧间隔时间

void CCApplication::setAnimationInterval(double interval){

获取高精度定时器的频率计算出频率X帧间隔时差的值存入m_nAnimationInterval用做比较值 m_nAnimationInterval.QuadPart= (LONGLONG)(interval * nFreq.QuadPart);

摆放方向变化时外部自动调用的设置摆放方向

CCApplication::Orientation CCApplication::setOrientation(Orientationorientation){

切换视窗的宽高

CCEGLView *pView = CCDirector::sharedDirector()->getOpenGLView();

if(pView) {

return(Orientation)pView->setDeviceOrientation(orientation);

return(Orientation)CCDirector::sharedDirector()->getDeviceOrientation();

获取状态栏的位置矩形

void CCApplication::statusBarFrame(CCRect * rect){

if(rect) {

// WINDOWS系统没有状态栏,所以返回的矩形各位置都是0

*rect =CCRectMake(0,0);

静态成员函数,获取单件指针

CCApplication&CCApplication::sharedApplication(){

CC_ASSERT(sm_pSharedApplication);

return*sm_pSharedApplication;

静态成员函数,获取当前系统的语言类型

ccLanguageType CCApplication::getCurrentLanguage(){

默认为英语 ccLanguageTyperet = kLanguageEnglish;

//

LCIDlocaleID = GetUserDefaultLCID();

unsignedshort primaryLanguageID = localeID & 0xFF;

switch(primaryLanguageID){

caseLANG_CHINESE:

中文

ret =kLanguageChinese;

caseLANG_FRENCH:

法文

ret =kLanguageFrench;

caseLANG_ITALIAN:

意文

ret =kLanguageItalian;

caseLANG_GERMAN:

德文

ret =kLanguageGerman;

caseLANG_SPANISH:

西班牙文

ret =kLanguageSpanish;

caseLANG_RUSSIAN:

俄文

ret =kLanguageRussian;

return ret;

static void PVRFrameEnableControlWindow(bool bEnable){

HKEY hKey = 0;

打开注册表的

if(ERROR_SUCCESS !=RegCreateKeyExW(HKEY_CURRENT_USER,230)"> L"Software\\ImaginationTechnologies\\PVRVFRame\\STARTUP\\",230)"> 0,230)"> REG_OPTION_NON_VOLATILE,230)"> KEY_ALL_ACCESS,230)"> &hKey,230)"> NULL))

return;

const wchar_t * wszValue =L"hide_gui";

const wchar_t * wszNewData = (bEnable) ?L"NO" : L"YES";

wchar_t wszOldData[256] = {0};

DWORDdwSize = sizeof(wszOldData);

读取相应的键值

LSTATUSstatus = RegQueryValueExW(hKey,wszValue,(LPBYTE)wszOldData,230)"> &dwSize);

如果键值不存在,或者键值存在但与当前值不同,重设键值

if (ERROR_FILE_NOT_FOUND == status

|| (ERROR_SUCCESS ==status

&& 0 !=wcscmp(wszNewData,wszOldData)))

dwSize =sizeof(wchar_t) * (wcslen(wszNewData) + 1);

RegSetValueEx(hKey,REG_SZ,(const BYTE *)wszNewData,dwSize);

关闭注册表

RegCloseKey(hKey);

代码看完之后,我们来做一下CCApplication类的总结:

CCApplication的构造函数中可以看到这里定义了一个静态指针sm_pShareApplication;它在CCApplication实例化时指定为实例化单件对象的指针。在sharedApplication函数中返回实例化的单件对象引用。重点函数是run函数。在run函数开始调用了initInstance函数进行程序的初始化,调用返回为true后再调用applicationDidFinishLaunching函数完成一些逻辑的初始化工作,完成初始化后会进入WINDOWS消息循环,并通过高精度定时器进行FPS判断什么时候调用CCDirector::sharedDirector()->mainLoop()。直待收到窗口关闭的消息退出消息循环并返回。

好了,我们理解了CCApplication之后,我们再来看一下它的派生类AppDelegate,了解一下它都重载了哪些函数。

读前小提示:CCEGLView代表OpenGL显示窗口。封装了使用OpengGL做为显示底层API的一个基本的WINDOWS窗体的创建与控制。

读前小提示:CCDirector类中有一个函数enableRetianDisplay函数。这个函数主要是影响到IOS平台上支持高清显示的设备如iphone4iphone4s等。如果设置enableRetinaDisplay(false),则在iphone4平台上运行的结果是游戏的图片分辨率降低为原来的一半,因为宽高都被拉伸了一倍。如果设置enableRetinaDisplay(true),则在iphone4平台上运行的结果是游戏的图片分辨率正常,但是放置的位置的水平方向和垂直方向都拉伸了两倍。要记住在cocos2d里面设置精灵坐标时,使用的是点,而不是像素,在普通的iphone上,一个点就等于一个像素,而在高清显示设备中,默认一个点等于二个像素。在IOS SDK 4.0及以后的SDK中支持不同的分辨率。并提供了相应的函数对逻辑点与像素的对应比例值做设置。

重点关注函数:initInstance ()(AppDelegate.h)

#ifndef _APP_DELEGATE_H_

#define _APP_DELEGATE_H_

class AppDelegate : privatecocos2d::CCApplication

AppDelegate();

析构函数

virtual~AppDelegate();

重载初始化函数 virtualbool initInstance();

重载应用程序启动后调用的处理函数 virtualbool applicationDidFinishLaunching();

重载应用程序转入后台时调用的函数 virtualvoid applicationDidEnterBackground();

重载应用程序恢复前台时调用的函数 virtualvoid applicationWillEnterForeground();

// _APP_DELEGATE_H_

再来看AppDelegate.cpp文件

#include "AppDelegate.h"

#include "cocos2d.h"

#include "HelloWorldScene.h"

OpenGL窗口类

#include "CCEGLView.h"

命名空间

USING_NS_CC;

AppDelegate::AppDelegate() {

AppDelegate::~AppDelegate() {

初始化函数解答伏笔1

bool AppDelegate::initInstance()

定义一个bool返回值用于判断是否正常初始化

bool bRet =false;

do {

通过对宏定义的匹配来判断当前编译的代码的目标平台是什么,在这里可以知道的跨平台都支持哪些平台。我们的教程只针对平台部分做讲解,其它平台大家可以自行参考平台部分进行学习。

第一种平台类型,系统

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)

创建并初始化窗口管理实例对象,注意这里使用的是new来动态实例化的。

当程序退出时会通过显示设备的release函数进行对窗口的释放。【伏笔3后面会有讲解】。

CCEGLView *pMainWnd = new CCEGLView();

//CC_BREAK_IF宏的意思是如果括号中的语句为否则中断循环。配合do_while流程使

用。

可以看到这里的意思是,如果pMainWnd实例化失败或者创建窗口失

败则中断循环。在这里硬性的设定了窗口的标题和窗口的宽度高度。

CC_BREAK_IF(!pMainWnd|| !pMainWnd->Create(TEXT("cocos2d: Hello World"),480,230)"> 320));

// CC_PLATFORM_WIN32

第二种平台类型,IOS类型

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

//CC_PLATFORM_IOS

第三种平台类型,ANDORID #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

//CC_PLATFORM_ANDROID

第四种平台,WOPHONE平台

#if(CC_TARGET_PLATFORM == CC_PLATFORM_WOPHONE)

//CC_PLATFORM_WOPHONE

第五种平台,MARMALADE

#if(CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)

#endif

第六种平台,LINUX

#if(CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)

//CC_PLATFORM_LINUX

第七种平台,BADA

#if(CC_TARGET_PLATFORM == CC_PLATFORM_BADA)

//CC_PLATFORM_BADA

第八种平台 #if(CC_TARGET_PLATFORM == CC_PLATFORM_QNX)

// CC_PLATFORM_QNX

如果没有被中断,则成功完成初始化。

bRet =true;

退出循环

} while(0);

returnbRet;

重载应用程序启动后调用的处理函数

bool AppDelegate::applicationDidFinishLaunching() {

通过CCDirector的静态函数sharedDirector来获取单件显示设备管理器指针

CCDirector*pDirector = CCDirector::sharedDirector();

CCEGLViewsharedOpenGLView来获取单件管理实例对象并将其地址

的成员函数setOpenGLView传递给显示设备管理器。

pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());

打开使用高清模式,这里给屏蔽了,如未来有需要可以打开。但是在设计程序时需要

考虑到打开后对于位置的影响并提前制定相应的设计方案。

//pDirector->enableRetinaDisplay(true);

打开显示

FPSpDirector->setDisplayFPS(true);

设置当前屏幕的摆放方向,这里给屏蔽了。

//pDirector->setDeviceOrientation(kCCDeviceOrientationLandscapeLeft);

的帧间隔时间差为60分之一秒,从而期望帧。

pDirector->setAnimationInterval(1.0/ 60);

HelloWorldscene()创建返回一个场景实例

CCScene*pScene = HelloWorld::scene();

运行这个场景

pDirector->runWithScene(pScene);

returntrue;

重载应用程序转入后台时调用的函数,如电话打进来

void AppDelegate::applicationDidEnterBackground() {

暂停显示设备的渲染处理

CCDirector::sharedDirector()->pause();

如果使用了声音引擎,这里进行暂停设置。否则会影响到通话,因为暂时没用到,所以屏蔽

//SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();

重载应用程序恢复前台时调用的函数

void AppDelegate::applicationWillEnterForeground() {

恢复显示设备的渲染处理

CCDirector::sharedDirector()->resume();

如果使用了声音引擎,这里进行恢复设置

// SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();

InitInstance函数中,我们看到Cocos2d-xWindows窗口的创建与控制都封装到了CCEGLView类中。它已经暴露出一个Create函数,做为一个求知者,我们应该迫不及待的想要看到它在哪里创建窗口。继续追进去吧!GoGoGo!

我们进入了CCEGLView_win32.cpp,通过文件名可以知道CCEGLView类应该有多个平台的版本。我们暂不理它。看一下Create函数。(在CCEGLView_win32.cpp

我们先从boolCCEGLView::Create(LPCTSTR pTitle,int w,int h)开始

bool CCEGLView::Create(LPCTSTR pTitle,int h){

型返回值

do

检测窗口句柄是否已经存在。确保只创建一个窗口

CC_BREAK_IF(m_hWnd);

进入到这里,我们应该很高兴了。没错,终于找到了创建窗口的代码。

HINSTANCEhInstance = GetModuleHandle( NULL );

WNDCLASS wc;

设置相关参数

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

wc.lpfnWndProc = _WindowProc;

本窗口使用的消息处理函数

wc.cbClsExtra =0;

wc.cbWndExtra = 0;

wc.hInstance =hInstance;

wc.hIcon = LoadIcon( NULL,IDI_WINLOGO );

wc.hCursor = LoadCursor( NULL,IDC_ARROW );

wc.hbrBackground = NULL;

wc.lpszMenuName = NULL;

wc.lpszClassName = kWindowClassName;

注册窗口类如果失败,则判断失败原因是否是此类别已存在(错误码1410),如果

是,因为此类存在而导致失败,则仍然可以继续。

CC_BREAK_IF(!RegisterClass(&wc) && 1410 != GetLastError());

取得窗口的窗体矩形

RECT rcDesktop;

GetWindowRect(GetDesktopWindow(),&rcDesktop);

调用创建口函数

m_hWnd =CreateWindowEx(

WS_EX_APPWINDOW| WS_EX_WINDOWEDGE,kWindowClassName,0)">之前注册的窗口类

pTitle,0)">窗口标题

WS_CAPTION| WS_POPUPWINDOW | WS_MINIMIZEBOX,0)">窗体样式

窗体位置

窗体宽度

窗体高度

NULL,0)">无父窗口

无菜单

hInstance,0)">程序句柄

NULL );

判断窗口是否创建成功

CC_BREAK_IF(!m_hWnd);

取得显示设备的摆放方向 m_eInitOrientation= CCDirector::sharedDirector()->getDeviceOrientation();

通过对摆放方向的判断得出水平还是垂直 m_bOrientationInitVertical= (CCDeviceOrientationPortrait == m_eInitOrientation

||kCCDeviceOrientationPortraitUpsideDown == m_eInitOrientation) ? true :false;

m_tSizeInPoints.cx= w;

m_tSizeInPoints.cy= h;

设置窗口大小 resize(w,h);

使用此窗口进行的设置

m_pEGL =CCEGL::create(this);

如果创建失败销毁窗体并中断

if (!m_pEGL){

DestroyWindow(m_hWnd);

m_hWnd =NULL;

将静态指针设置为当前实例对象。

s_pMainWindow= this;

在注册类时,设定了窗口的消息处理回调函数为_WinDowProc,我们继续追入看一下程序退出时在哪里释放了Opengl窗口实例对象。呵呵,还记得前面我们埋下的伏笔3,它是用new创建出来的。而new出来的内存必须释放。程序退出会销毁窗体,消息处理函数会先后收到WM_CLOSEWM_DESTROY。我们找一下。(还是CCEGLView_win32.cpp,boolCCEGLView::Create()函数上面

static LRESULT CALLBACK _WindowProc(HWND hWnd,UINT uMsg,WPARAMwParam,230)"> LPARAM lParam){

窗体初始化完成,则由窗体进行消息处理,否则由WINDOWS

系统进行默认处理

if (s_pMainWindow&& s_pMainWindow->getHWnd() == hWnd){

return s_pMainWindow->WindowProc(uMsg,wParam,lParam);

}else{

returnDefWindowProc(hWnd,uMsg,230)"> }

继续。(在CCEGLView_win32.cpp,boolCCEGLView::Create()函数下面

LRESULT CCEGLView::WindowProc(UINT message,WPARAM wParam,LPARAMlParam){

PAINTSTRUCTps;

switch(message){

以上消息暂不理,可自行分析

caseWM_PAINT:

这里是刷新屏幕,因为使用了来进行绘制,所以这里不作任何处理。

BeginPaint(m_hWnd,&ps);

EndPaint(m_hWnd,230)"> caseWM_CLOSE:

调用单件显示设备管理器的end函数关闭窗口

CCDirector::sharedDirector()->end();

caseWM_DESTROY:

向消息循环发送WM_QUIT消息退出程序

PostQuitMessage(0);

default:

returnDefWindowProc(m_hWnd,message,230)"> }return 0;

进入显示设备管理器CCDirectorend函数。(在CCDirector.cpp

void CCDirector::end(){

是否在下一个循环时清除显示设备

m_bPurgeDirecotorInNextLoop= true;

!这里只是设置成员变量m_bPurgeDirecotorInNextLooptrue,没有什么delete。怎么回事呢?

好吧,继续分析,成员变量的名字意思是是否在下一个循环时清除显示设备。哦。也就是说这只是一个开关。在循环函数中判断它是否为true来清除显示设备。打开mainLoop函数。解答伏笔2(在CCDirector.cpp

void CCDisplayLinkDirector::mainLoop(void){

如果清除显示设备开关为true

if(m_bPurgeDirecotorInNextLoop){

清除设备

purgeDirector();

m_bPurgeDirecotorInNextLoop= false;

}否则判断显示设备是否有效

else if (!m_bInvalid) {

如果有效,绘制场景

drawScene();

调用内存管理器释放其管理的内存

CCPoolManager::getInstance()->pop();

马上要接晓答案了(在CCDirector.cpp

void CCDirector::purgeDirector(){

以上暂不理。有兴趣的朋友请自行分析

调用Opengl窗口管理实例对象的函数进行释放。

m_pobOpenGLView->release();

m_pobOpenGLView= NULL;

进入OpenGL窗口管理类的release函数(在CCEGLView_win32.cpp

void CCEGLView::release(){

销毁窗体

if(m_hWnd){

s_pMainWindow= NULL;

注销所使用的窗口类

UnregisterClass(kWindowClassName,GetModuleHandle(NULL));

释放使用到的指针 CC_SAFE_DELETE(m_pSet);

CC_SAFE_DELETE(m_pTouch);

CC_SAFE_DELETE(m_pDelegate);

CC_SAFE_DELETE(m_pEGL);

关键点:在最后释放了自已在AppDelegate::initInstance()中通过创建对象而占用

的内存。

deletethis;

现在我们了解了Cocos2d-x是如何将WINDOWS程序基本框架封装在自已的类之中的。运行一下程序,可们可以看到弹出的窗口显示出HelloWorld的画面。而当初复杂的WINDOWS程序基本框架。在这里只化为简单的一句run()。非常简洁!

这个运行中的窗口,没有最大化系统按钮,窗体大小也被固定在480x320。我们希望能够更灵活的设置窗口的标题和大小。那我们必须要做一些改动。即然已经看懂了代码,下面就亲自实习一下吧。

打开AppDelegateinitInstance函数,增加相应的参数。(AppDelegate.cpp中的boolAppDelegate::initInstance()函数)

bool AppDelegate::initInstance(LPCTSTR szTitle,UINT wWidth,UINTwHeight)

并改动下面一句

CC_BREAK_IF(! pMainWnd

//改成由函数参数来创建OpenGL窗体

|| !pMainWnd->Create(szTitle,wWidth,wHeight));

//||! pMainWnd->Create(TEXT("cocos2d: Hello World"),320));

然后我们打开CCApplication_win32.cpp,找到run函数。做同样的修改。

int CCApplication::run(LPCTSTR szTitle,UINT wHeight)

if (! initInstance(szTitle,wHeight) || !applicationDidFinishLaunching())

// if (! initInstance() || !applicationDidFinishLaunching())

之后我们将头文件所需要改动的函数声明也一一改动。保存,重新编译libcocos2d工程。再打开HelloWorld中的main.cpp修改这一句:

我们可以在这里自已设定窗口标题和窗口大小

return cocos2d::CCApplication::sharedApplication().run(TEXT("第一个Cocos2d-x程序"),800,600);

//returncocos2d::CCApplication::sharedApplication().run();



编译 HelloWorld 。运行一下。享受一下成果!

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...