您的位置:首页 > 移动开发 > Cocos引擎

【cocos2d-x 3.0】入门样例《SimpleGame》源码解读【1】

2014-02-14 11:39 369 查看

【序言】

UP主若干年前独立制作过几部小游戏,如:

《躲子弹之BadApple版》-- www.acfun.tv/v/ac63137

《金坷垃马里奥兄弟》 -- www.bilibili.tv/video/av2556

等等……

但遗憾的是都没有用到什么正儿八经的游戏引擎,全部都是用C++Builder从底层开始自己设计自己实现的

虽说学到了很多东西(比如消息循环啊,绘图API啊,简单的物理效果啊)

不过始终停留在学习层面(也许这些经验将来可以帮别人优化引擎? =v=)

如果想真正做点“上道儿”的小游戏或者什么玩意,还是要了解一些主流的游戏引擎,于是决定从今天开始学习cocos2d-x!

(为什么要从这个开始学呢,因为听说比较简单什么的我会到处乱说嘛?)

cocos2d-x官网上目前(2014年2月)最新的版本是3.0beta2

虽然还是属于测试的版本,但听说相比2.0系列又增加了不少好用的新特性,所以UP主决定跳过老版本直接从3.0入手学习

【准备工作】

如果你和UP主一样目前是cocos2d-x的新手,那在阅读代码之前肯定先要配置好环境

(请参见我前面转的一篇文章:http://blog.csdn.net/macuilxochitl/article/details/19158751

另外如果你是编程方面的新手,那么UP主建议你至少要熟悉C++基本语法,不太难的OO知识,不太难的数据结构与算法,以及一些不太难的设计模式

当然对于Win平台下游戏开发而言,如果你懂得一点消息循环机制,以及通过消息循环控制游戏帧率的机制是最好的

不然直接学习游戏引擎相关代码的话肯定经常会有一些难以理解的地方

(好了,其实上面都是UP主自己瞎编的,请不要过分相信)

废话到此为止,我们开始看一个样例游戏的代码吧!

(由于本文是UP主自身学习的过程中记录的,所以也许会有个别理解不准确的地方请指出)

【开始】

首先打开cocos2d-x解压目录下的build文件夹,打开cocos2d-win32.vc2012.sln

然后就可以在这个solution中找到SimpleGame这个项目

(你可以编译运行一下看看,就是那个忍者扔飞镖打幽灵的小游戏,有很多教程都写过,但大多是以2.0系列或更老版本的引擎实现的)

作为Win32程序启动入口,我们不妨先看一下win32\main.cpp

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

USING_NS_CC;

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR    lpCmdLine,
int       nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

// create the application instance
AppDelegate app;
EGLView eglView;
eglView.init("SimpleGame",900,640);
return Application::getInstance()->run();
}
这段儿其实不用怎么解释,这么简洁的main五星好评好嘛?

很明显就是初始化了一个900x640的游戏界面

并且定义了一个app实例并调用了run()作为游戏启动的入口

然后我们看一下app对象类AppDelegate.h

class  AppDelegate : private cocos2d::Application


发现main中的app它调用了Application基类的run,我们看一下这个方法

int Application::run()
{
PVRFrameEnableControlWindow(false);

// Main message loop:
LARGE_INTEGER nFreq;
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;

QueryPerformanceFrequency(&nFreq);
QueryPerformanceCounter(&nLast);

 // Initialize instance and cocos2d.
// [RN] 启动APP
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }

    EGLView* pMainWnd = EGLView::getInstance();

// [RN] 消息循环
    while(!pMainWnd->windowShouldClose())
    {
        QueryPerformanceCounter(&nNow);
        if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)
        {
            nLast.QuadPart = nNow.QuadPart;
            Director::getInstance()->mainLoop();
            pMainWnd->pollEvents();
        }
        else
        {
            Sleep(0);
        }
    }

/* Only work on Desktop
*  Director::mainLoop is really one frame logic
*  when we want to close the window, we should call Director::end();
*  then call Director::mainLoop to do release of internal resources
*/
Director::getInstance()->end();
Director::getInstance()->mainLoop();
return true;
}
进入这段我们首先看到了感人的一段 消息循环
部分,一个标准的消息循环嘛!

(和UP主曾经写小游戏时的方法如出一辙,说明我当年的代码也不算太山寨.. 哈哈)

每帧调用了Director导演实例的mainLoop()主循环,并调用pollEvent()轮询事件

(至于两个方法里面具体的事情,暂时就不用看太细了,毕竟我们目前是学习使用引擎,不用管太多引擎的实现)

然后重点就是前面的 启动APP 部分,它调用了AppDelegate子类中的applicationDidFinishLaunching()方法

bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();

director->setOpenGLView(EGLView::getInstance());

auto screenSize = EGLView::getInstance()->getFrameSize();
auto designSize = Size(480, 320);
std::vector<std::string> searchPaths;

if (screenSize.height > 320)
{
searchPaths.push_back("hd");
searchPaths.push_back("sd");
director->setContentScaleFactor(640.0f/designSize.height);
}
else
{
searchPaths.push_back("sd");
director->setContentScaleFactor(320.0f/designSize.height);
}

FileUtils::getInstance()->setSearchPaths(searchPaths);

EGLView::getInstance()->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::NO_BORDER);

// turn on display FPS
director->setDisplayStats(true);

// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);

// create a scene. it's an autorelease object
// [RN] 创建场景并调用场景的init()方法初始化,最后返回scene指针
auto scene = HelloWorld::scene();

// run
director->runWithScene(scene);

return true;
}


大概扫了一眼很好理解,前面就是设定了一堆关于画面尺寸、缩放比例方面的东西…(目前不用管太细)

然后就是设置是否显示帧数,以及帧数的设定

重点是最后的两句:创建了一个HelloWorld实例并返回了它的sence场景指针(也就是我们的游戏场景)

最后把这个场景交给了引擎中的大导演director,使我们的场景运行起来!

至此,这个引擎的启动入口和基本运作机制,我们就算是有了一个初步的认识了!

总体上cocos2dx给我们的第一印象很好,基本都是很清晰明了的(好评 =v=)

下一篇中UP主会继续解读本游戏的主要场景,也就是HelloWorldScene.cpp —— 这个游戏的核心代码了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2d-x 游戏引擎