Cocos2d-x游戏开发实例详解1:开始菜单

2015年03月25日 13:08 0 点赞 0 评论 更新于 2025-11-21 15:13

本系列将通过实际演练,详细解说Cocos2d-x引擎的各个模块。

打开工程与查看源码

我使用WebStorm打开HTML5工程,查看了MoonWarriors的源码。源码存放在src目录下,config目录中包含一些配置信息,例如游戏状态、分数、命条数等。游戏的JavaScript代码从文件名大致能看出其功能。

开始菜单的实现

我从开始菜单入手,HTML5版的开始菜单代码为SysMenu.js,我依照其逻辑用Cocos2d-x进行了重写,下面来看看效果。

开始菜单元素

这个开始菜单包含以下元素:菜单项、logo、飞机、背景图,FPS相关内容暂不讨论。

类的结构与构造方式

该类继承自CCLayer,其结构与HelloWorld类似,不过没有构造函数。这是因为引擎引入引用计数来管理内存,为方便开发者,对C++的部分内容进行了包装,类似Objective - C的实现方式,这种结构被称为“二阶段构造”。

在代码最下方有一个宏定义的函数CREATE_FUNC(StartMenu),实际上它就是一个create()函数。其执行流程如下:首先创建一个新对象,接着检查其init()函数的返回值,若init成功,则将对象添加到自动释放池;若失败,则返回null。所以,若使用这种结构定义类,就必须实现init()函数。

在我的实现中,所有界面元素的初始化都在init()函数中完成,其余部分为回调函数,其中update()函数用于实现飞机的随机飞行。

界面元素的实现

1. 背景

背景使用CCSprite实现,代码如下:

CCSprite* sl = CCSprite::create(s_loading);
sl->setAnchorPoint(ccp(0, 0));
this->addChild(sl, 0, 1);

这里创建了一个CCSprite对象,设置其锚点为(0, 0),表示以其左下角为基准点。addChild函数有三个参数,第一个参数是要添加的子对象,第二个参数是z坐标,它决定了层次关系,方向是从屏幕指向屏幕外,值越大表示越在上层,第三个参数是一个tag标记,后续需要时可以通过该标记获取对象。

2. logo

logo同样使用CCSprite实现,代码如下:

CCSprite* logo = CCSprite::create(s_logo);
logo->setAnchorPoint(ccp(0, 0));
logo->setPosition(ccp(0, 250));
this->addChild(logo, 10, 1);

设置锚点为(0, 0),即以其左下角为基准点,然后将位置设置为(0, 250),这意味着logo的左下角位于(0, 250)处,其余部分按照OpenGL的坐标系确定。

3. 菜单

菜单使用图片实现,因此依然采用CCSprite。以下是创建一个菜单项不同状态的代码:

CCSprite* newGameNormal = CCSprite::create(s_menu, CCRectMake(0, 0, 126, 33));
CCSprite* newGameSelected = CCSprite::create(s_menu, CCRectMake(0, 33, 126, 33));
CCSprite* newGameDisabled = CCSprite::create(s_menu, CCRectMake(0, 33 * 2, 126, 33));

s_menu是菜单图片的索引,该图片包含了所有菜单项,创建某个菜单项时需要使用坐标来截取。这里使用的坐标系是屏幕坐标系,原点在左上角,向右为x正轴,向下为y正轴。

接着创建一个菜单项:

CCMenuItemSprite* newGame = CCMenuItemSprite::create(newGameNormal, newGameSelected, newGameDisabled, this, menu_selector(StartMenu::flareEffec));

参数中,第四个是目标对象,最后一个是回调函数,点击该菜单项时会执行此回调函数。这里的回调函数实现了一个特效,后续会详细讲解。

除了newGame菜单项,还有aboutsettings两个菜单项,它们的实现方式与newGame类似,只是使用的图片和回调函数不同。

然后创建菜单:

CCMenu* menu = CCMenu::create(newGame, gameSetting, about, NULL);

需要注意的是,在2.1.0版本中,最后一个参数必须为NULL,它是一个结束标志。

最后对菜单进行布局和位置设置:

menu->alignItemsVerticallyWithPadding(10);
this->addChild(menu, 1, 2);
menu->setPosition(ccp(winSize.width / 2, winSize.height / 2 - 80));

设置菜单项垂直间隔为10,addChild函数的zOrder设为1,表明菜单位于背景的上层。若不设置锚点,默认锚点为(0.5, 0.5),即中心点。

至此,开始菜单的主要元素基本实现完成,接下来还需要实现飞机的随机飞行效果。