请参考《Ubuntu18.04搭建Cocos2d开发环境》搭建项目
默认情况下,Cocos2d-x会将鼠标左点击当作触摸。
第一步:在/home/kyun/Desktop/Games/MyGame/CMakeLists.txt文件添加TouchScene.h和TouchScene.cpp:
# add cross-platforms source files and header files
list(APPEND GAME_SOURCE
Classes/AppDelegate.cpp
Classes/TouchScene.cpp
)
list(APPEND GAME_HEADER
Classes/AppDelegate.h
Classes/TouchScene.h
)
第二步:编写TouchScene.h和TouchScene.cpp
TouchScene.h:
#include "cocos2d.h"
class TouchScene : public cocos2d::Layer {
public:
static cocos2d::Scene* createScene();
virtual bool init();
//Touch事件回调方法
virtual bool onTouchBegan(cocos2d::Touch*,cocos2d::Event*);
virtual void onTouchEnded(cocos2d::Touch*,cocos2d::Event*);
virtual void onTouchMoved(cocos2d::Touch*,cocos2d::Event*);
virtual void onTouchCancelled(cocos2d::Touch*,cocos2d::Event*);
CREATE_FUNC(TouchScene);
private:
cocos2d::Label* labelTouchInfo;
};
TouchScene.cpp:
//
// Created by kyun on 20-3-12.
//
#include "TouchScene.h"
USING_NS_CC;
Scene* TouchScene::createScene() {
auto scene = Scene::create();
auto layer = TouchScene::create();
scene->addChild(layer);
return scene;
}
bool TouchScene::init() {
if(!Layer::init()){
return false;
}
// Label标签
labelTouchInfo = Label::createWithSystemFont("Touch or clicksomewhere to begin","Arial",30);
labelTouchInfo->setPosition(Vec2(Director::getInstance()->getVisibleSize().width/2,Director::getInstance()->getVisibleSize().height/2));
// 创建EventListenerTouchOneByOne类型的事件监听器
auto touchListener = EventListenerTouchOneByOne::create();
// 将处理函数绑定到事件监听器上
touchListener->onTouchBegan = CC_CALLBACK_2(TouchScene::onTouchBegan,this);
touchListener->onTouchEnded = CC_CALLBACK_2(TouchScene::onTouchEnded,this);
touchListener->onTouchMoved = CC_CALLBACK_2(TouchScene::onTouchMoved,this);
touchListener->onTouchCancelled = CC_CALLBACK_2(TouchScene::onTouchCancelled,this);
// 将事件监听器注册到节点的_eventDispatcher上
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,this);
this->addChild(labelTouchInfo);
return true;
}
bool TouchScene::onTouchBegan(cocos2d::Touch * touch, cocos2d::Event * event) {
labelTouchInfo->setPosition(touch->getLocation());
labelTouchInfo->setString("You touched here");
return true;
}
void TouchScene::onTouchEnded(cocos2d::Touch * touch, cocos2d::Event * event) {
cocos2d::log("touch ended");
}
void TouchScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event * event) {
cocos2d::log("touch moved");
}
void TouchScene::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event) {
cocos2d::log("touch cancelled");
}
第三步:修改AppDelegate.cpp
#include "TouchScene.h"
...
bool AppDelegate::applicationDidFinishLaunching() {
...
// create a scene. it's an autorelease object
auto scene = TouchScene::createScene();
// run
director->runWithScene(scene);
return true;
}
最后,运行就可以了。
分析TouchScene中的用到的方法
- 关于EventListenerTouchOneByOne事件监听器处理函数的定义
class CC_DLL EventListenerTouchOneByOne : public EventListener
{
public:
typedef std::function<bool(Touch*, Event*)> ccTouchBeganCallback;
typedef std::function<void(Touch*, Event*)> ccTouchCallback;
ccTouchBeganCallback onTouchBegan;
ccTouchCallback onTouchMoved;
ccTouchCallback onTouchEnded;
ccTouchCallback onTouchCancelled;
...
};
我们根据此来定义我们的函数,上面规定了处理函数的返回值和形参顺序。其实我们也可以使用Lambda表达式来定义处理函数,如:
touchListener->onTouchBegan = [](Touch* touch,Event* event)->bool{
// todo
}
完整的例子,我们修改init方法,让其使用lambda表达式来定义处理函数:
//
// Created by kyun on 20-3-12.
//
#include "TouchScene.h"
USING_NS_CC;
Scene* TouchScene::createScene() {
auto scene = Scene::create();
auto layer = TouchScene::create();
scene->addChild(layer);
return scene;
}
bool TouchScene::init() {
if(!Layer::init()){
return false;
}
auto sprite = Sprite::create("logo2.png");
sprite->setAnchorPoint(Vec2(0.5,0.5));
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
sprite->setPosition(Vec2(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = [](Touch* touch,Event* event)->bool{
auto bounds = event->getCurrentTarget()->getBoundingBox();
if(bounds.containsPoint(touch->getLocation())){
std::stringstream touchDetails;
touchDetails <<
"Touched at OpenGL coordinates:" <<touch->getLocation().x << "," << touch->getLocation().y << std::endl<<
"Touched at UI coordinate:"<<touch->getLocationInView().x << "," << touch->getLocationInView().y << std::endl <<
"Touched at local coordinate:" <<
event->getCurrentTarget()->convertToNodeSpace(touch->getLocation()).x << "," <<
event->getCurrentTarget()->convertToNodeSpace(touch->getLocation()).y << std::endl<<
"Touch moved by:" << touch->getDelta().x << "," << touch->getDelta().y;
ccMessageBox(touchDetails.str().c_str(),"Touched");
}
return true;
};
// Add a "touch" event listener to our sprite
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener,sprite);
this->addChild(sprite,0);
this->addChild(labelTouchInfo);
return true;
}
上面的效果就是点sprite后会弹出一个对话框。
- ccMessageBox()弹窗
- touch->getLocationInView()返回在屏幕坐标系(原点在屏幕左上角)中的位置
- touch->getLocation()返回在OpenGL坐标系(原点在屏幕左下角)中的位置
谢谢阅读