cocos2d-x 3.0 touch事件
本文将详细介绍 Cocos2d-x 3.0 中的触摸事件,同时会提及该版本的一些重要变化,并给出相关代码示例。如果你想深入了解 Cocos2d-x 3.0 的触摸事件,不妨接着往下看。
Cocos2d-x 3.0 的主要变化
Cocos2d-x 3.0 有不少显著变化,例如弃用了 Objective-C 的命名规则,并且引入了一种新的写法——lambda 表达式(后续会详细介绍)。下面是一些类名在 2.x 版本和 3.0 版本的对比:
| 2.2 版本 | 3.0 版本 |
| -------------- | -------- |
| CCDirector | Director |
| CCLayer | Layer |
| CCScene | Scene |
| CCSprite | Sprite |
创建场景示例
Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
初始化方法示例
bool HelloWorld::init()
{
if (!Layer::init())
{
return false;
}
// 3.0 获得导演的单例,Director::sharedDirector() 改为了 Director::getInstance(),但仍向下兼容
// CC_DEPRECATED_ATTRIBUTE static Director* sharedDirector() { return Director::getInstance(); }
Size visibleSize = Director::getInstance()->getVisibleSize(); // 获得显示区域
Point origin = Director::getInstance()->getVisibleOrigin(); // 获得显示的起点坐标
// auto 是 Cocos2d-x 3.0 变动较大的一处
// auto 是自动类型变量
// 比如原来要指定变量是 int 还是 float,现在可以用 auto,在赋值时,编译器会自动识别类型
// 这是 C++11 的新标准,你可以参考 C++11 新标准文档
// CC_CALLBACK_1 是新的事件回调,从 0 - 3 各自有自己的回调参数
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width / 2,
origin.y + closeItem->getContentSize().height / 2));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
// 以前是 cpp(x, y),现在坐标都是 Point,比如颜色 ccWHITE 也改成了 Color3B::WHITE
this->addChild(menu, 2);
auto label = LabelTTF::create("Hello World", "Arial", 24);
label->setPosition(Point(origin.x + visibleSize.width / 2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1, 101);
// 这种事件的创建方式比以前更加明了、直观
// 触摸事件(EventListenerTouch)
// 键盘响应事件(EventListenerKeyboard)
// 加速记录事件(EventListenerAcceleration)
// 鼠标响应事件(EventListenerMouse)
// 自定义事件(EventListenerCustom)
// 移除事件监听器
// 移除一个已经被添加了的监听器:
// _eventDispatcher->removeEventListener(listener);
// 移除当前事件分发器中所有监听器:
// _eventDispatcher->removeAllEventListeners();
auto listener = EventListenerTouchOneByOne::create(); // 创建一个单点触摸事件,EventListenerTouchAllAtOnce 为多点触摸
// 设置这些事件的回调方法
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // 事件调度器
return true;
}
触摸事件处理方法示例
void HelloWorld::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event)
{
printf("move");
}
bool HelloWorld::onTouchBegan(Touch* touch, Event *event)
{
return true;
}
// 通过点击结束区域来设置 label 的位置
void HelloWorld::onTouchEnded(Touch* touch, Event *event)
{
auto location = touch->getLocation();
auto s = getChildByTag(101);
// 以下只是个旋转角度、移动的操作,无关紧要
s->stopAllActions();
s->runAction(MoveTo::create(1, Point(location.x, location.y)));
float o = location.x - s->getPosition().x;
float a = location.y - s->getPosition().y;
float at = (float)CC_RADIANS_TO_DEGREES(atanf(o / a));
if (a < 0)
{
if (o < 0)
at = 180 + fabs(at);
else
at = 180 - fabs(at);
}
s->runAction(RotateTo::create(1, at));
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
auto menuItem = static_cast<MenuItem*>(pSender); // 获得点击的按钮
printf("pSender-tag==%d", menuItem->getTag());
MessageBox("你点击了按钮!!", "提示"); // 提示框
}
Lambda 表达式写法
Lambda 表达式的写法很有趣,下面的代码实现的功能和上面的完全一样:
bool HelloWorld::init()
{
if (!Layer::init())
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize(); // 获得显示区域
Point origin = Director::getInstance()->getVisibleOrigin(); // 获得显示的起点坐标
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
[](Ref *sender) {
auto menuItem = static_cast<MenuItem*>(sender); // 获得点击的按钮
printf("pSender-tag==%d", menuItem->getTag());
MessageBox("你点击了按钮!!", "提示"); // 提示框
});
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width / 2,
origin.y + closeItem->getContentSize().height / 2));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 2);
auto label = LabelTTF::create("Hello World", "Arial", 24);
label->setPosition(Point(origin.x + visibleSize.width / 2,
origin.y + visibleSize.height - label->getContentSize().height));
this->addChild(label, 1, 101);
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [](Touch* touch, Event* event) {
return true;
};
listener->onTouchEnded = [](Touch* touch, Event* event) {
auto location = touch->getLocation();
auto target = static_cast<Node*>(event->getCurrentTarget());
auto s = target->getChildByTag(101);
// 以下只是个旋转角度、移动的操作,无关紧要
s->stopAllActions();
s->runAction(MoveTo::create(1, Point(location.x, location.y)));
float o = location.x - s->getPosition().x;
float a = location.y - s->getPosition().y;
float at = (float)CC_RADIANS_TO_DEGREES(atanf(o / a));
if (a < 0)
{
if (o < 0)
at = 180 + fabs(at);
else
at = 180 - fabs(at);
}
s->runAction(RotateTo::create(1, at));
};
listener->onTouchMoved = [](Touch* touch, Event* event) {
printf("move");
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); // 事件调度器
return true;
}
通过以上内容,你可以全面了解 Cocos2d-x 3.0 的触摸事件处理,以及该版本的一些重要变化和新特性。