声 明
本教程仅用于初学cocos2dx同学使用,内容由本人(Code-Man)编写,此教程使用cocos2dx版本为3.4。本教程内容可以自由转载,但必须同时附带本声明,或注明出处。Cocos2d-CodeMonkey,461679592。
【一】知己知彼
Hello,很高兴又跟Monkey们见面了。相信经过上一个教程大家已经打好了环境,并对C++有了一定的了解。在计算机语言里存在着这么一个
诅咒,任何一本计算机语言的教科书里都会有一句:Hello World 。哈哈哈!!
今天我也毫不例外的从HelloWorld讲起。
运行编译好的项目,如图:
左下角的含义:
GL verts : 78 的意思是:当前场景传送给显卡的顶点数量。
53.1 的意思:表示游戏当前的帧率,这经常能反映这个游戏对应这个设备来说是否存在卡顿。当帧率低于30帧以下时,是人无法接受的卡顿。市面上基本普及了60帧的设备。
0.013的意思:的意思是每一帧所处理的时间。
在看代码之前,先说以下cocos2dx的组成成分吧。
Cocos2dx的五脏六腑组成成分:
【二】寻根问底
都说戏如人生,人生如戏。其实游戏就像一场电影。当我第一次看到这张图的时候,在想这是不是要拍戏了。有导演,有场景,还有布局层,节点难道就是里面的演员吗?
其实你完全是可以这样理解啦。每一个演员都扮演着自己的角色,他们各自都有自己的特点。下面来看看他们都有什么用吧。
1.节点。
节点里面有一个比较好理解儿子(子类),就是Sprite(精灵)。这是游戏里最常见,也是最常用的元素。比如游戏的人物、武器、衣服...。当然节点下有很多的子类,节点本身并不承载任何显示在屏幕的内容(图片或者图像),但所有显示在屏幕上的内容元素都是节点的子类,可以说显示在屏幕上的元素皆为节点
2.布局层。
除精灵以为最多的元素。一个游戏离不开、背景层、暂停层、结束层。层是透明的因为有了精灵在层上,才丰富了它。把每一个层叠在一起,俯视来看,就是一个完整的游戏了。如果用过PS的可以直接理解为PS里的图层。
3.场景。
4.导演。
主导者,就像现实中的导演一样,场景的切换,开始、暂停、继续都是导演说的算。它控制着整个游戏的流程。
代码部分:
本人用的是Xcode,VS的Monkey们不用太过在意开发工具的不一样,其实内容都是一模一样的。
1.HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" //很明显HelloWorld继承了我们的布局层,所有HelloWorld也是一个层 class HelloWorld : public cocos2d::Layer { public: //结合上面的所学的知识,聪明的Monkey可以,已经通过英文已经猜到这个方法的作用了吧。 //没错它就是创建一个场景。也就是创建一个箱子,里面装了我们的布局层 static cocos2d::Scene* createScene(); //virtual关键字: 如果C++不是学得特别多的暂可忽视。 //这个函数主要是初始化,这个类中所用到的变量等。 virtual bool init(); //结合第一张图片,我们可以看到右下角的那个按钮。这个方法也就是那个按钮, //按下去之后所要调用的方法。按下去之后的事情都发生在这个方法里。 void menuCloseCallback(cocos2d::Ref* pSender); //暂可不予理会,你只需要知道,没有它,HelloWorld就不能创建出来。 CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
2.HelloWorldScene.cpp
#include "HelloWorldScene.h" USING_NS_CC; //创建场景方法 Scene* HelloWorld::createScene() { // 首先,先创建一个场景。在Cocos2dx里面, //基本90%以上的Node(节点,场景也是一个Node)都可以用crate 创建出来。 auto scene = Scene::create(); // 创建一个层,这个层也就是类自己本身 // 好奇的朋友会问。HelloWorld是自己创建的类,可是我们并没有create这个方法,哪里来的呢? // 还记得,HelloWorldScene.h文件里的:CREATE_FUNC(HelloWorld); 吗?没错就是来自于这里 // 为什么会有create,暂不讲解。有兴趣的可百度,C++ 宏定义。 auto layer = HelloWorld::create(); //add(添加的意思),Child(儿子),就是把括号里的儿子添加到自己身上。哈哈哈,很好理解吧。 scene->addChild(layer); // 返回这个场景,交给谁?没错就是导演,导演在哪?,暂不告诉你,下期会讲解(要是没讲,记得吐槽我)。 return scene; } //初始化 bool HelloWorld::init() { // 注意:这里比较坑,刚学的时候被坑过一次。在这里只需记住一句话:有了你爸才能有你。你爸就是Layer(不是李刚) // 初始化Layer(HelloWorld的爸爸)不为真,才往下面执行 if ( !Layer::init() ) { return false; } // 导演,导演终于见到了导演。getInstance()这个方法,在cocos2dx里面经常用到,都是一个单例,单例是什么?暂不讲解。 // 只要知道这样就能拿到导演了,然后再拿到屏幕的大小 Size visibleSize = Director::getInstance()->getVisibleSize(); // 拿到屏幕的原点坐标,关于cocos2dx坐标的知识,会再后续文章单独讲解 Vec2 origin = Director::getInstance()->getVisibleOrigin(); // 创建一个按钮,看到没?又是create, // 1.第一个参数:正常状态下的图片,2.按下去时候的图片,3.回调函数,没错就是HelloWorldScene.h文件里的那个 // 在cocos2dx 拥有很多的宏定义,都是已大写形式存在。能方便开发偷懒,哈哈哈!! 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)); // 创建一个按钮层,它负责管理,添加到它上面的所有按钮,记住后面一定要跟一个NULL, // 暂不解释,可作为个人思考,真想知道就扣扣我吧,其实我寂寞了,O(∩_∩)O哈哈~ auto menu = Menu::create(closeItem,NULL); // 因为儿子已经设置了坐标,所有父亲的坐标设置为(0,0)就好了,Vec2::ZERO = Vec2(0,0) // 儿子的坐标永远相对于父亲的坐标,后期会详解坐标 menu->setPosition(Vec2::ZERO); //添加儿子咯,不用说,可是1是什么?先不用管,总之很厉害,哈哈哈 //好吧还是告诉你,1的意思就是:谁在上面,谁在下面?(有点邪恶)。数字越大,就越靠上,文字的是“1” 椰子图片的是“0”,所以文字在椰子图片上面。
//this是谁?HelloWorld自己,常用关键字,别忘了!!! this->addChild(menu,1); // 创建文字,也就是我们第一张图看到的文字:HelloWorld // 参数1.显示的文字,2.字体:也是就资源文件里的文件,3.字体大小 auto label = Label::createWithTTF("Hello World","fonts/Marker Felt.ttf",24); //哎,自己领悟吧这个.... label->setPosition(Vec2(origin.x + visibleSize.width/2,origin.y + visibleSize.height - label->getContentSize().height)); //添加儿子 this->addChild(label,1); // 添加第一张图片看到的里面的那个外星人(其实我是椰子啦!!) // 参数1:图片名 auto sprite = Sprite::create("HelloWorld.png"); //不解释 sprite->setPosition(Vec2(visibleSize.width/2 + origin.x,visibleSize.height/2 + origin.y)); //不想解释,不要问为什么,有钱任性!!!! this->addChild(sprite,0); //返回真干嘛?那你看谁调用它咯。提示:CREATE_FUNC(HelloWorld); return true; } //按钮的回调,按了按钮之后会发生的事情都在这了。。。 void HelloWorld::menuCloseCallback(Ref* pSender) { // 这个,不要管总之很厉害。。 #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 }