[转]Cocos2dx教程专栏(一) 一切从一个游戏菜单开始:
类别:Cocos2dx教程
状态:游客可见,可回,会员可关联(没审核)
阅读:6627
评论:0
时间:Jan. 17, 2017, 6:27 p.m.
关键字:Cocos2dx
来源:http://blog.csdn.net/u012184326/article/details/40992833
学了cocos2dx不久,许多知识还是不是很懂,呵呵,至少cocos2dx的API函数没懂多少。但是这个时候就不要绝望,应该先做一个让自己可以小玩一下的游戏。
这个教程我把cocos2d中自带的打飞机游戏MoonWarriors(月球战士)这个游戏从js版转化为c++版,讲解如何制作一个2D游戏。
一切从一个游戏菜单开始。
(一)环境配置
我简单地说一下配置cocosdx文件:
1.从官网上下载coccs2dx,解压出来就是一个文件
2.下载vs2012
3.下载python,并且配置python环境变量,具体怎么配置参考以下的博文:
(二)创建游戏工程:
接下来要创建一个工程MyMoonWarriors:
1.依次打开cocos2d-x-2.2.2->tools->project-creator
2.在project-creator目录下按住shift+鼠标右键,选择在此处打开命令窗口,输入命令:
python create_project.py
-project MyMoonWarriors -package
org.MyMoonWarriors.game
-language cpp
输入完以后,有如下效果就说明成功了:

这个时候工程文件的位置在cocos2d-x-2.2.2->projects->MyMoonWarriors
好!创建完文件以后就是迈向游戏制作的第一步!!
(三)创建游戏菜单:
1.放置资源文件:
当然,做游戏首先要有大量的图片资源,所以首先我们打开工程文件MyMoonWarriors的所在位置,会发现会如下的文件夹:选中Resources文件夹,把游戏需要的图片等资源都放置在这里

这个资源文件还是蛮难找的,找不到也没有关系,我把它上传了。请读者在这个链接下载资源文件,然后把它拷贝进去:(下面可以下载)
2.开始写代码:
依次打开MyMoonWarriors->proj.win32->MyMoonWarriors.sln(因为我们是在windows下写代码,所以上面那些
其他文件夹如proj.andorid、proj.ios等等不用管它,后面会慢慢讲)
打开后效果如上,我们要在最后一个写代码(上面那4个都是cocos2dx带的库文件,代码中经常要用到上面的API函数)
3.如何写代码:
打开MyMoonWarriors会发现我们不知如何下手,以前写的控制台程序对开发一个游戏来讲,简直是小巫见大巫,瞬间感觉以前多牛逼都是扯淡了。不过不要担忧,以前学的都是非常有用的。
首先,我们要记住C++面向对象的一个思想:先把功能写成一个个函数或者类,然后在main函数中调用这些功能函数或类等让代码生成程序运行起来!
在写游戏也是这样,我们大部分都是在Classes这个文件夹添加各种游戏类(比如主角,敌人,菜单类,主角管理,敌人管理等等),然后在win32中的main.cpp中调用这些游戏对象来运行

上面的这些经验对一个游戏开发初学者来说,都是十分宝贵的经验。接下来我们开始尝试创建一个游戏菜单,效果如下:

分析一下这个界面效果:很明显,它是一个由背景 logo 菜单项三个部分组成的一个菜单界面...
好,开始写代码:
1.创建一个类StartMenu:
创建方法是在工程文件夹里面创建StartMenu.cpp和StartMenu.h,然后拷贝复制到VS2012中的classes文件夹下(=
=疑问来了,为什么不直接在VS2012下直接创建文件?我试过了,如果直接创建,在工程文件夹会显示不出来,所以只能用这样一个稍微复杂的方法,以后创建文件都这样创建)
2.在StartMenu.h中写如下功能类(代码我加了注释了,不懂的可以多看看或者手动度娘一下):
#ifndef __StartMenu_H__ #define __StartMenu_H__ class StartMenu : public cocos2d::CCLayer { public: static cocos2d::CCScene *scene();//创建菜单场景 virtual bool init();//初始化菜单类的成员变量 void menuCallback(CCObject *pSender);//回调函数,这个在点击菜单项的时候会用到回调机制,调用该函数 CREATE_FUNC(StartMenu);//这个函数有点麻烦,就暂时当作是一个自动释放内存的函数 //(很重要,教程一不会用到,后面慢慢讲) private: }; #endif // !__StartMenu_H__ //1.#ifndef __StartMenu_H__,#define __StartMenu_H__关于这个作用无非就是防止头文件的重复包含和编译 //2.虚函数机制virtual的作用就是为了声明这个函数是属于派生类的, //从而对基类的同名函数进行重写,而不是属于基类的,这样基类的指针调用该函数就不会因为同名调用到基类的函数去, //而是调用派生类的函数 //虚函数的出现是为了体现这样一种C++多态的机制 //友元函数 构造函数 static静态函数 不能用virtual关键字修饰; //普通成员函数 和析构函数 可以用virtual关键字修饰;
2.在写StartMenu.cpp之前
,我们还要创建一个StdAfx.cpp和StdAfx.h用来把需要包含的类库都放在这个上面,代码很简单
StdAfx.h:
#include "cocos2d.h"//包含cocos2d类库 USING_NS_CC;//使用cc命名空间
StdAfx.cpp:
#include "StdAfx.h"
3.开始写StartMenu.cpp:
#include "StdAfx.h" //记住,这个要写在第一个 #include "StartMenu.h" CCScene* StartMenu ::scene() { CCScene *scene=CCScene ::create(); StartMenu *layer=StartMenu ::create(); scene->addChild(layer); return scene; } bool StartMenu ::init() { if (!CCLayer ::init()) { return false ; } CCDirector *pDirector=CCDirector ::sharedDirector(); //创建一个导演类,用来调用整个场景所需要的变量,比如窗口大小 CCSize winSize=pDirector->getWinSize();//通过导演类获得窗口的大小 CCSprite *pLoadingImg = CCSprite ::create("loading.png"); //创建一个精灵类,来存放一张背景图片 pLoadingImg->setPosition( ccp(winSize.width / 2, winSize.height / 2));//图片放在正中央 this->addChild(pLoadingImg);//场景添加图片 return true ; } //1.菜单是一个场景,场景要有一个导演来调度资源的排布 //2.精灵类在cocos2d中很常见,创建一个图片可以用一个精灵类CCSprite //3.添加图片经常用this->addChild();
4.接下来可以运行看看效果了,把AppDelegate.cpp中添加
#include"StartMenu.h"
然后把
bool AppDelegate ::applicationDidFinishLaunching()
函数里面的
CCScene *pScene = HelloWorld ::scene();改成 CCScene *pScene
= StartMenu::scene();
点击F5调试运行,可以看到如下效果。成功加载了背景!!
接下来继续添加Logo和菜单选项了,代码会有点多,但是只有几个知识点,就是菜单类的学习和一些设置图片锚点等等
#include "StdAfx.h" #include "StartMenu.h" CCScene * StartMenu ::scene() { CCScene *scene = CCScene ::create(); StartMenu *layer = StartMenu ::create(); scene->addChild(layer); return scene; } // on "init" you need to initialize your instance bool StartMenu ::init() { if ( ! CCLayer::init() ) { return false ; } CCDirector* pDirector = CCDirector ::sharedDirector(); CCSize winSize = pDirector->getWinSize(); CCSprite *pLoadingImg = CCSprite ::create( "loading.png"); //用CCSprite创建一张背景图Loading,然后设置它在窗口的摆放位置,然后加进场景里面 pLoadingImg->setPosition( ccp (winSize.width / 2, winSize.height / 2)); this ->addChild(pLoadingImg); //仿照上面的创建一个Logo图,设置图片的锚点,一样放进场景里面 CCSprite *pLogoImg = CCSprite ::create( "logo.png"); pLogoImg->setAnchorPoint( ccp (0.5, 1)); pLogoImg->setPosition( ccp (winSize.width / 2, winSize.height-60)); this ->addChild(pLogoImg); //创建菜单项的方法可能有点复杂,但是思路很清晰 //1.首先同样用CCSprite创建一个菜单项正常,被点击,不能使用三种状态的图片,后面有个CCRectMake是(0,0)表示从图像的0,0(左上角) //点开始,(126,33)表示截取一张完整图像中的宽126,高33的部分图像 //这么做有个很简单的原因是做美术的时候总是把多张图放在一起整合成一张图,避免太多的图片资源导致混乱。 //2.接着用CCMenuItemSprite创建一个菜单项,然后把三种不同的状态加进去 //3.后面有个Menu_selector(StartMenu:menuCallback);用来表示菜单项被点击的时候会响应事件(通常是切换场景) //4.最后要给项设置一个节点标志setTag(),用来识别是哪个菜单项被创建 //这样一个菜单项创建完毕,后面两个菜单项依法炮制创建出来 CCSprite *pNewNormalItemImg = CCSprite ::create( "menu.png", CCRectMake (0, 0, 126, 33)); CCSprite *pNewSelectedItemImg = CCSprite ::create( "menu.png", CCRectMake (0, 33, 126, 33)); CCSprite *pNewDisabledItemImg = CCSprite ::create( "menu.png", CCRectMake (0, 66, 126, 33)); CCMenuItemSprite *pNewItem = CCMenuItemSprite ::create(pNewNormalItemImg, pNewSelectedItemImg, pNewDisabledItemImg, this , menu_selector( StartMenu ::menuCallback)); pNewItem->setTag(1); //仿照第一个菜单项创建 CCSprite *pOptionNormalItemImg = CCSprite ::create( "menu.png", CCRectMake (126, 0, 126, 33)); CCSprite *pOptionSelectedItemImg = CCSprite ::create( "menu.png", CCRectMake (126, 33, 126, 33)); CCSprite *pOptionDisabledItemImg = CCSprite ::create( "menu.png", CCRectMake (126, 66, 126, 33)); CCMenuItemSprite *pOptionItem = CCMenuItemSprite ::create(pOptionNormalItemImg, pOptionSelectedItemImg, pOptionDisabledItemImg, this , menu_selector( StartMenu ::menuCallback)); pOptionItem->setTag(2); //仿照第一个菜单项创建 CCSprite *pAboutNormalItemImg = CCSprite ::create( "menu.png", CCRectMake (252, 0, 126, 33)); CCSprite *pAboutSelectedItemImg = CCSprite ::create( "menu.png", CCRectMake (252, 33, 126, 33)); CCSprite *pAboutDisabledItemImg = CCSprite ::create( "menu.png", CCRectMake (252, 66, 126, 33)); CCMenuItemSprite *pAboutItem = CCMenuItemSprite ::create(pAboutNormalItemImg, pAboutSelectedItemImg, pAboutDisabledItemImg, this , menu_selector( StartMenu ::menuCallback)); pAboutItem->setTag(3); //三个菜单项创建完毕之后,就要把它们合并成一个菜单了 //用CCMenu 创建一个菜单把三个菜单项包含进去 //设置每个菜单项之间的距离是30:alignItemsVerticallyWithPadding(20); CCMenu *pMenu = CCMenu ::create(pNewItem, pOptionItem, pAboutItem, NULL); pMenu->alignItemsVerticallyWithPadding(20); pMenu->setPosition( ccp (winSize.width / 2, winSize.height/2-60)); addChild(pMenu); return true ; } void StartMenu ::menuCallback( CCObject* pSender ) { int nTag = ((CCNode *) pSender)->getTag(); switch (nTag) { case 1: { CCLOG ("New Click" ); } break ; case 2: { CCLOG ("Option Click" ); } break ; case 3: { CCLOG ("About Click" ); } break ; } }
运行一下效果:

5.最后怎么点击一个菜单项就切换进入游戏:
写StartMenu:menuCallback()方法:
我们要实现的是点击New
Game选项就进入进入游戏场景:
在此之前要先建立游戏场景类:GameLayer.cpp和GameLayer.h
代码就不贴了
只是设置了一个背景图,读者可以仿照StartMenu菜单类写,贴一下StartMenu:menuCallback()方法:
前面加:
#include "GameLayer.h"
void StartMenu ::menuCallback( CCObject* pSender ) { int nTag = ((CCNode *) pSender)->getTag(); switch (nTag) { case 1: { CCLOG ("New Click" ); CCScene *GameLayerScene=GameLayer::scene(); CCDirector::sharedDirector()->replaceScene(GameLayerScene); } break ; case 2: { CCLOG ("Option Click" ); } break ; case 3: { CCLOG ("About Click" ); } break ; } }
运行结果,切换成功
教程一结束:(下面有源代码下载)
文件名 | 大小 | 时间 | 会员 | 费用 | 操作 | ||
MyMoonWarrior源码_Classes.rar(合格) | 5K246B | Jan. 18, 2017, 12:26 a.m. | 初学MPEG | 积分:0 荣誉:0 会币:0 |
下载 | ||
MyMoonWarrior图片资源 _Resources.rar(合格) | 4M281K | Jan. 18, 2017, 12:32 a.m. | 初学MPEG | 积分:0 荣誉:0 会币:0 |
下载 | ||
操作: