目录
一、开发环境
二、开发内容
2.1 添加资源文件
2.2 游戏MenuLayer开发
2.3 GameLayer开发
三、演示效果
四、知识点
4.1 sprite、layer、scene区别
4.2 setAnchorPoint
一、开发环境
操作系统:UOS1060专业版本。
cocos2dx:版本4.0
环境搭建教程:统信UOS下配置安装cocos2dx开发环境
本课主要内容:
- 自定义Layer开发
- 游戏餐单按钮相关开发
文章地址:
二、开发内容
我们把开发游戏的menu相关元素放在一个Layer进行处理。
新建Layer目录,在其中新建文件GameLayer.h、GameLayer.cpp、GameMenuLayer.h、GameMenuLayer.cpp。
GameLayer:用于管理游戏相关内容。
GameMenuLayer:用于管理游戏餐单相关内容。
2.1 添加资源文件
前面的文章其实已经提到我们可以在LoadingScene.cpp中先加载资源,等到我们使用的时候可以直接通过资源的名字获取该资源信息。
在loadSource函数添加以下内容:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("map_spritesheet_32-hd.plist");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("map_spritesheet_32_2-hd.plist");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("map_spritesheet_16_na-hd.plist");
注意需要将对应的plist文件以及png图片拷贝到Resources目录中。否则精灵在创建是需要通过名称获取图片获取不到而导致程序崩溃。
2.2 游戏MenuLayer开发
GameMenuLayer.h文件内容代码如下:
#ifndef __LAYER_GAME_MENU_LAYER_H__
#define __LAYER_GAME_MENU_LAYER_H__
#include "cocos2d.h"
USING_NS_CC;
class GameMenuLayer : public Layer
{
public:
virtual bool init();
// implement the "static create()" method manually
CREATE_FUNC(GameMenuLayer)
MenuItemSprite *book_,*shop_,*update_;
Sprite * sprite_map_stars_container_;
Label * lable_star_,*lable_diamonds_;
bool isFirst;
void touchBook(Ref *pSender);
void touchShop(Ref *pSender);
void touchUpdate(Ref *pSender);
void onEnterTransitionDidFinish();
};
#endif // __LAYER_GAME_LAYER_H__
GameMenuLayer.cpp文件内容代码如下:
#include "GameMenuLayer.h"
// on "init" you need to initialize your instance
bool GameMenuLayer::init()
{
//
// 1. super init first
if ( !Layer::init() )
{
return false;
}
isFirst = true;
// 获取窗口大小
auto winSize = Director::getInstance()->getWinSize();
// 商店精灵
shop_ = MenuItemSprite::create(Sprite::createWithSpriteFrameName("butShop_0001.png"),
Sprite::createWithSpriteFrameName("butShop_0002.png"),
CC_CALLBACK_1(GameMenuLayer::touchShop,this));
// 百科全书精灵
book_ = MenuItemSprite::create(Sprite::createWithSpriteFrameName("butEncyclopedia_0001.png"),
Sprite::createWithSpriteFrameName("butEncyclopedia_0002.png"),
CC_CALLBACK_1(GameMenuLayer::touchBook,this));
// 升级精灵
update_ = MenuItemSprite::create(Sprite::createWithSpriteFrameName("butUpgrades_0001.png"),
Sprite::createWithSpriteFrameName("butUpgrades_0002.png"),
CC_CALLBACK_1(GameMenuLayer::touchUpdate,this));
book_->setPosition(Point(winSize.width - book_->getContentSize().width/2,book_->getContentSize().height/2 -130));
update_->setPosition(Point(book_->getPosition().x - 160 , update_->getContentSize().height/2-130));
shop_->setPosition(Point(update_->getPosition().x - 160 , shop_->getContentSize().height/2-130));
auto menu = Menu::create(shop_,update_,book_,nullptr);
menu->setPosition(Vec2::ZERO);
addChild(menu);
sprite_map_stars_container_ = Sprite::createWithSpriteFrameName("mapStarsContainer.png");
sprite_map_stars_container_->setPosition(Point(winSize.width - sprite_map_stars_container_->getContentSize().width/2 - 10,
winSize.height - sprite_map_stars_container_->getContentSize().height/2 + 60));
addChild(sprite_map_stars_container_);
// 星星的数量
lable_star_ = Label::createWithTTF("0","SohoGothicProMedium.ttf",26);
lable_star_->setPosition(Point(sprite_map_stars_container_->getContentSize().width/4*3 + 20,sprite_map_stars_container_->getContentSize().height/2));
sprite_map_stars_container_->addChild(lable_star_);
// 砖石的数量
lable_diamonds_ = Label::createWithTTF("0","SohoGothicProMedium.ttf",26);
lable_diamonds_->setPosition(Point(sprite_map_stars_container_->getContentSize().width/4,sprite_map_stars_container_->getContentSize().height/2));
sprite_map_stars_container_->addChild(lable_diamonds_);
return true;
}
void GameMenuLayer::touchBook(Ref *pSender)
{
}
void GameMenuLayer::touchShop(Ref *pSender)
{
}
void GameMenuLayer::touchUpdate(Ref *pSender)
{
}
void GameMenuLayer::onEnterTransitionDidFinish()
{
if(isFirst){
book_->runAction(MoveBy::create(0.3f,Point(0,130)));
update_->runAction(MoveBy::create(0.3f,Point(0,130)));
shop_->runAction(MoveBy::create(0.3f,Point(0,130)));
sprite_map_stars_container_->runAction(MoveBy::create(0.3f,Point(0,-70)));
isFirst = false;
}
}
2.3 GameLayer开发
其实GamelLayer添加了GameMenuLayer,并并且添加了一个背景就没啥了。
#ifndef __LAYER_GAME_LAYER_H__
#define __LAYER_GAME_LAYER_H__
#include "cocos2d.h"
USING_NS_CC;
class GameLayer : public Layer
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
// implement the "static create()" method manually
CREATE_FUNC(GameLayer)
Size win_size_;
Sprite *sprite_background_;
};
#endif // __LAYER_GAME_LAYER_H__
内容如下:
#include "GameLayer.h"
#include "GameMenuLayer.h"
USING_NS_CC;
Scene* GameLayer::createScene()
{
auto scene = Scene::create();
auto game_layer = GameLayer::create();
auto game_menu_layer = GameMenuLayer::create();
scene->addChild(game_layer);
scene->addChild(game_menu_layer);
return scene;
}
// on "init" you need to initialize your instance
bool GameLayer::init()
{
//
// 1. super init first
if ( !Layer::init() )
{
return false;
}
win_size_ = Director::getInstance()->getWinSize();
sprite_background_ = Sprite::createWithSpriteFrameName("MapBackground.png");
sprite_background_->setAnchorPoint(Vec2::ZERO);
sprite_background_->setPosition(Vec2::ZERO);
addChild(sprite_background_);
return true;
}
三、演示效果
四、知识点
4.1 sprite、layer、scene区别
在 cocos2d-x 游戏引擎中,`Sprite`、`Layer` 和 `Scene` 都是用于构建游戏场景和图层的类,但它们在功能和用途上有一些区别。
1. Sprite(精灵):
- `Sprite` 是游戏中可见的图像元素,通常用于表示游戏中的角色、物体、背景等。
- 你可以将纹理(图像)加载到 `Sprite` 中,使其显示特定的图像。
- `Sprite` 可以进行位置、大小、旋转等的设置,还可以添加动画和事件监听器。
- 用法示例:创建角色、敌人、道具、特效等可见的游戏元素。
2. Layer(图层):
- `Layer` 是场景中的可视化图层,用于呈现游戏中的各种元素,如精灵、文本、UI 等。
- 一个 `Layer` 通常是某种类型的视觉容器,可以用来组织和管理一组相关的游戏元素。
- `Layer` 可以添加到 `Scene` 中,一个 `Scene` 可以包含多个 `Layer`,从而实现图层的层次结构。
- 用法示例:创建游戏界面、UI 图层、特效图层等。
3. Scene(场景):
- `Scene` 是一个可视化的游戏场景容器,用于表示游戏中不同的画面、状态或关卡。
- 一个 `Scene` 通常由多个 `Layer` 组成,每个 `Layer` 呈现不同的游戏元素。
- `Scene` 可以管理场景之间的切换,实现从一个画面切换到另一个画面。
- 用法示例:创建游戏的不同关卡、主菜单、游戏结束画面等。
区别总结:
- `Sprite` 是游戏中的可见元素,用于表示角色、物体等。
- `Layer` 是图层容器,用于组织和呈现游戏元素。
- `Scene` 是画面容器,用于管理不同画面之间的切换。
通常的开发实践是,一个游戏会有多个 `Scene`,每个 `Scene` 包含多个 `Layer`,而每个 `Layer` 中包含多个 `Sprite`。这样的层次结构可以帮助你有效地组织和管理游戏中的元素。
4.2 setAnchorPoint
`setAnchorPoint` 是 cocos2d-x 中 `Node` 类的成员函数之一,用于设置节点的锚点位置。锚点是节点相对于自身位置的一个点,影响了节点的定位和旋转。
节点的锚点是一个具有两个坐标值(x 和 y)的点,取值范围通常是从 0 到 1,表示节点的宽度和高度的相对比例。
示例用法:
auto sprite = Sprite::create("image.png");
sprite->setPosition(Vec2(200, 200)); // 设置节点的位置
// 设置锚点为节点宽度的中心(x=0.5),高度的底部(y=0)
sprite->setAnchorPoint(Vec2(0.5, 0.0));
this->addChild(sprite);
在上述示例中,`setAnchorPoint` 函数被用来设置精灵节点的锚点位置。在这个例子中,锚点被设置在精灵的底部中心,这意味着节点的位置 `(200, 200)` 将会指向精灵底部中心,而不是默认的左下角。
通过调整锚点,你可以更好地控制节点的旋转、缩放和定位行为。需要注意的是,节点的位置和锚点相互作用,所以改变锚点可能会导致节点的位置发生变化。