今天讲自定义事件和加速计事件
先在头文件完成以下声明
virtual void onExit(); // 为了移除ListenerCustom中的监听器_listener
EventListenerCustom* _listener; // 为了能够最后在onExit中调用移除函数,所以在头文件声明
接着就是在cpp文件中的实现,
/********************************自定义事件**************************************/
auto statusLabel = Label::createWithSystemFont("No custom event 1 received!", "", 20);
statusLabel->setPosition(Point(240, 230));
addChild(statusLabel);
/*
参数一要求给自定义事件命名,为了能够在后面通过事件名字调用自定义事件
参数二是一个事件的回调函数,这里用Lambda函数实现,实现具体作用
*/
_listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){
std::string str("Custom event 1 received, ");
// 因自定义事件中的"getUserData()"函数返回的是一个void*,为了能转换为char*,这里用了static_cast<char*>强制类型转换
char* buf = static_cast<char*>(event->getUserData());
str += buf;
str += " times";
statusLabel->setString(str.c_str());
});
/*
"SceneGraphPriority"和"FixedPriority"两种分发事件区别是
前者跟Node绑定的,在Node的析构函数中会被移除,
后者添加完之后需要手动remove.
*/
// 因为这里不能确定是谁调用自定义事件,并且自定义事件可以利用名字调用,所以就用第二个方法来分发事件和设置优先级
_eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);
// 这里通过MenuItemFont的第二个参数设置了一个Lambda函数调用了自定义事件
auto sendItem = MenuItemFont::create("Send Custom Event 1", [=](Ref* sender){
static int count = 0;
++count;
char* buf = new char[10];
sprintf(buf, "%d", count);
EventCustom event("game_custom_event1"); // 先通过自定义事件名字初始化事件
event.setUserData(buf); // 利用自定义事件中的"setUserData()"设置用户数据
_eventDispatcher->dispatchEvent(&event); // 最后事件分发 还移除在事件分发列表中所有标记为删除的事件侦听器
CC_SAFE_DELETE_ARRAY(buf);
});
sendItem->setPosition(Point(240, 160));
auto menu = Menu::create(sendItem, nullptr);
menu->setPosition(Vec2(0, 0));
menu->setAnchorPoint(Vec2(0, 0));
addChild(menu, -1);
/*******************************************************************************/
最后在onExit函数中remove
void onExit(){
Layer::onExit();
_eventDispatcher->removeEventListener(_listener);
}
接着是加速计事件,其实就是重力感应,这里没有用手机测试,大家参考一下,有条件的可以测试一下,到时告诉我是否正确
/********************************加速计事件*******************************************/
Device::setAccelerometerEnabled(true); // 打开硬件设备
auto sprite = Sprite::create("Images/ball.png");
sprite->setPosition(Point(240, 160));
addChild(sprite);
// 参数是一个函数,这里用Lambda函数实现,里面参数第一个是加速度,第二个点击事件
auto listener = EventListenerAcceleration::create([=](Acceleration* acc, Event* event){
auto ballSize = sprite->getContentSize(); // 精灵面积
auto ptNow = sprite->getPosition(); // 精灵位置
ptNow.x += acc->x * 9.81f; // x轴加速度,设置x轴坐标
ptNow.y += acc->y * 9.81f; // y轴加速度,设置y轴坐标
sprite->setPosition(ptNow);
});
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite);
/**************************************************************************************/
最后退出的时候不要忘了关掉硬件设备,同自定义事件一样下面的函数要在头文件声明
void onExit(){
Layer::onExit();
Device::setAccelerometerEnabled(false);
}
到此,所有的触摸事件就讲完了,希望大家能有所收获。