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

(一)初识cocos2d

2017-09-15 23:13 288 查看
cocos2d版本:  3.15

vs版本: 2015

按照着网上说的一些教程,先到 http://www.cocos2d-x.org/download  下载源码包,但是我发现了一个坑,

我在2017-09-15下载的最新版是3.15.1,但是几次下载回来都说文件格式损坏,然后压缩出的文件不完整。

我很不解,于是下载了历史版本3.15  发现就没问题了,然后按照教程: http://www.cjjjs.com/paper/sckf/201652614817878.html

利用C++技术网中命令行的方式新建了一个项目,然后再用vs打开即可。

不过好像和我在《cocos2d高级开发教程》上看到的有些不一致(可能是因为《cocos2d高级开发教程》说的是过时的版本吧)



我看到的文件目录是这样的,然后参考《cocos2d高级开发教程》去看懂这个helloworld,运行结果如下:



右下角是我们加入的一个菜单,点击会关闭该窗口

我这里对一些代码写了一些注释,帮助读懂第一个helloworld的源代码:

HelloWorldScene.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Scene
//定义了一个 HelloWorld类,该类继承自 Scene,因此 HelloWorld 本身是一个场景
{	//从 CCLayer 类派生出 HelloWorld 类(这是一个层),并重载了 HelloWorld 类的 init()方法
public:
static cocos2d::Scene* createScene(); //在 Cocos2d 中,在层下设置一个创建场景的静态函数是一个常见的技巧

//为了保证初始化方法可以被子类重载,需要确保初始化方法声明为虚函数:
virtual bool init(); //初始化 HelloWorld 类

// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);

// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__


HelloWorldScene.c:

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
return HelloWorld::create(); //????
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first, 调用父类的 init 方法来进行最初的初始化
if ( !Scene::init() )
{
return false;
}
/* 为什么我们要在一个实例方法中初始化类, 而不在构造函数中初始化呢?
在 C++中,一般习惯在构造函数中初始化类
------Cocos2d-x 不使用传统的值类型,所有的对象都创建在堆上,然后通过指针引用
创建 Cocos2d-x 对象通常有两种方法:
第一种是首先使用 new 操作符创造一个未初始化的对象,然后调用 init 系列方法来初始化;
第二种是使用静态的工厂方法直接创建一个对象。
*/
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin(); //用户可以通过类提供的静态方法获取独一无二的实例
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
//    you may modify it.  创建菜单并添加到层

// add a "close" icon to exit the progress. it's an autorelease object
//在 HelloWorld 类的 init()方法中添加了一个菜单,当用户点击该菜单时,就会触发此类中的 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));

// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1); //这个层添加菜单

/////////////////////////////
// 3. add your codes below... 创建"Hello World"标签并添加到层中

// add a label shows "Hello World"
// create and initialize a label
//创建一个文本标签并添加到层中,显示内容"Hello World
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);

// position the label on the center of the screen
label->setPosition(Vec2(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - label->getContentSize().height));

//add the label as a child to this layer
this->addChild(label, 1);//1是z轴顺序,也就是显示的先后顺序,其值越大,表示显示的位置就越靠前。

//4. add "HelloWorld" splash screen",用"HelloWorld.png"创建一个精灵并添加到层中
auto sprite = Sprite::create("HelloWorld.png"); //工厂方法
/*
使用构造函数创建的对象,它的所有权已经属于调用者了,使用工厂方法创建的对象的所有权却并不属于调用者,
因此,使用构造函数创建的对象需要调用者负责释放,而使用工厂方法创建的对象则不需要。
*/
// position the sprite on the center of the screen
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

// add the sprite as a child to this layer
this->addChild(sprite, 0);

return true;
}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
//Close the cocos2d-x game scene and quit the application
Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif

/*To navigate back to native iOS screen(if present) without quitting the application  ,do not use Director::getInstance()->end() and exit(0) as given above,instead trigger a custom event created in RootViewController.mm as below*/

//EventCustom customEndEvent("game_scene_close_event");
//_eventDispatcher->dispatchEvent(&customEndEvent);

}
单例( singleton)则是一个很易于理解的概念。在 Cocos2d-x 引擎中,我们能看到大量单例的身影.它们大部分出现在一些系统资源管理类中。单例模式保证了全局有且只有一个实例对象,保证自动地初始化该对象,使得程序在任何时候任何地方都可以访问、获取该对象。 

例如, Cocos2d-x 的游戏流程控制器 CCDirector 是一个独一无二的控制器,用于切换游戏场景。换句话说,不可能同时存在两个 CCDirector 实例。 

在这种情况下, Cocos2d-x 采用了单例的技巧。用户可以通过类提供的静态方法获取独一无二的实例,而不需要自己来创建。 

例如,我在vs中的项目视图下的 base/ 看到的CCDirector.cpp中的代码:

static Director *s_SharedDirector = nullptr;
//...其他一些于此无关紧要的代码
Director* Director::getInstance()
{
    if (!s_SharedDirector)
    {
        s_SharedDirector = new (std::nothrow) Director;
        CCASSERT(s_SharedDirector, "FATAL: Not enough memory");
        s_SharedDirector->init();
    }

    return s_SharedDirector;
}


这里看到了熟悉的身影,单例模式!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: