(九)C++自制植物大战僵尸游戏自定义对话框的实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD


对话框在游戏的交互中非常重要。在游戏中,对话框不仅可以提醒用户下达任务指令,而且还可以让用户进行操作,自定义游戏中的各种属性。对话框在游戏的交互中非常常见且大量使用。Cocos2d-x中并未实现对话框的功能。所以自定义实现一个对话框非常有必要。

代码文件位置

自定义对话框代码文件在Class\Based文件夹中,详细位置如下图所示。


Dialog.h

Dialog 类继承Cocos2d-xLayerColor 类,LayerColor 继承LayerLayerCocos2d-x 中表示一个层,Layer 存在于场景中,一个场景可以包含多个层。LayerColor 可以设置层的颜色。由于需要弹出一个对话框,所以背景需要变黑,所以Diaglog 继承LayerColor。当弹出一个对话框时,背景就会变黑,让用户聚焦到此对话之中。详细的C++代码如下所示。

cpp 复制代码
class Dialog :public LayerColor
{
public:
	/**
	 *创建触摸监听
	 */
	static EventListenerTouchOneByOne* createTouchtListener(Sprite* sprite);

	/**
	 *设置鼠标监听
	 */
	virtual void setMouseListener(EventListenerMouse* listener);

protected:
	/**
	 *创建标签
	 */
	virtual Label* label(const std::string &name, const float& fontsize, Vec2 &vec2 = Vec2(0, 0), 
		const float& space = 0, const Color3B& color = Color3B::GREEN, const float& scale = 1);

	/**
	 *创建按钮上的标签 
	 */
	virtual void createLabel(Sprite* sprite, MenuItemImage* MenuItem, const std::string &name, 
		Vec2 &vec2, float& fontsize, const float& space = 0, const Color3B& color = Color3B::GREEN);

	/**
	 *创建屏蔽层
	 */
	virtual void createShieldLayer(Node* node);

	/**
	 *删除层
	 */
	virtual void deleteDialog(){}

	/**
	 *设置鼠标监听是否可用
	 */
	virtual void setMouseListenerEnable(bool isEnable = true);

CC_CONSTRUCTOR_ACCESS:
	Dialog();
	~Dialog();

protected:
	Global* _global;
	EventListenerMouse* _mouseListener;

private:
	Vec2 _phasePosition; /* 相差位置 */
	EventListenerTouchOneByOne* _shieldListener;
};

对话框函数可以移动,所以定义了触摸监听函数createTouchtListener()setMouseListener() 。对话框上需要有标签,所以定义了标签函数createLabel() 。对话框上需要有各种按钮,所以定义了创建按钮的函数。当弹出对话框时,背景中的所有按钮及可点击的部分我们不希望可以再被点击,所以需要当弹出对话框时将背景触摸点击监听屏蔽,所以定义了屏蔽层函数createShieldLayer()


Dialog.cpp

在源文件中实现了头文件中定义的函数。下面将对重要的函数进行介绍。

构造函数

构造函数对重要变量进行初始化。

cpp 复制代码
Dialog::Dialog():
	_shieldListener(nullptr),
	_mouseListener(nullptr),
	_phasePosition(Vec2::ZERO),
	_global(Global::getInstance())
{
}

createTouchtListener()函数

函数有一个参数,传入一个Sprite (精灵),用于监听这个Sprite的触摸。创建完成后返回监听。

在函数中需要获取Sprite 坐标以及触摸位置的坐标。计算这两个坐标之间的差值phasePosition ,在触摸移动的过程中需要实时改变Sprite 的位置,设置位置时需要减去phasePosition ,这样才能平稳滑动Sprite ,否则在首次接触Sprite 的时候会导致Sprite瞬间移动到触摸位置。

cpp 复制代码
EventListenerTouchOneByOne* Dialog::createTouchtListener(Sprite* sprite)
{
	/* 创建触摸监听 */
	static Vec2 phasePosition = Vec2(Vec2::ZERO);
	auto listener = EventListenerTouchOneByOne::create();
	listener->onTouchBegan = [&,sprite](Touch *t, Event *e) {
		if (sprite->getBoundingBox().containsPoint(t->getLocation()))
		{
			phasePosition = t->getLocation() - sprite->getPosition();
			return true;
		}
		else return false;
	};
	listener->onTouchMoved = [=](Touch *t, Event *e) {
		sprite->setPosition(t->getLocation() - phasePosition);
	};

	Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, sprite);

	return listener;
}

createShieldLayer()函数

当弹出对话框时,背景中的所有按钮及可点击的部分我们不希望可以再被点击,所以需要当弹出对话框时将背景触摸点击监听屏蔽,所以定义了屏蔽层函数createShieldLayer()

函数有一个参数Node ,当将Node 传入该函数,除该Node可以监听事件之外,场景中其他层的监听将会被屏蔽。

cpp 复制代码
void Dialog::createShieldLayer(Node* node)
{
	// set shieldLayer
	_shieldListener = EventListenerTouchOneByOne::create();
	_shieldListener->onTouchBegan = [](Touch* touch, Event* event)-> bool { return true; };
	_shieldListener->setSwallowTouches(true);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(_shieldListener, node);
}

label()函数

函数参数较多,参数表示的有文字本身、字体大小颜色、字间距、缩放比例、位置等。

cpp 复制代码
Label* Dialog::label(const std::string &name, const float& fontsize, Vec2 &vec2, const float& space, const Color3B& color, const float& scale)
{
	auto label = Label::createWithTTF(name, GAME_FONT_NAME_1, fontsize);
	label->setScaleX(scale);
	label->setColor(color);
	label->setAdditionalKerning(space);//设置列间距
	label->enableShadow(Color4B(100, 20, 100, 255));//设置阴影
	label->setPosition(vec2);
	return label;
}

其他函数

cpp 复制代码
void Dialog::setMouseListener(EventListenerMouse* listener)
{
	_mouseListener = listener;
}

void Dialog::setMouseListenerEnable(bool isEnable)
{
	_mouseListener->setEnabled(isEnable);
}
相关推荐
Mr.Z.41136 分钟前
【历年CSP-S复赛第一题】暴力解法与正解合集(2019-2022)
c++
Death20040 分钟前
使用Qt进行TCP和UDP网络编程
网络·c++·qt·tcp/ip
郭二哈1 小时前
C++——list
开发语言·c++·list
黑不溜秋的2 小时前
C++ 语言特性29 - 协程介绍
开发语言·c++
一丝晨光2 小时前
C++、Ruby和JavaScript
java·开发语言·javascript·c++·python·c·ruby
￴ㅤ￴￴ㅤ9527超级帅2 小时前
LeetCode hot100---二叉树专题(C++语言)
c++·算法·leetcode
邓校长的编程课堂2 小时前
在Visual Studio中使用CMakeLists.txt集成EasyX库的详细指南
visual studio·少儿编程·easyx·信息学奥赛·图形化编程·趣味编程
_GR2 小时前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
Death2003 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半8883 小时前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法