cocos2d-x触屏事件(单点触屏)
转自:http://blog.csdn.net/onerain88/article/details/7550009
一般经常用到的触屏的情况有两种:一种是Layer统一接收触屏消息,然后由程序根据需要分发给不同位置的精灵;另一种情况是自定义一个可以接收触屏消息的Sprite,比如类似于Button功能的Sprite,这就需要在定义Sprite的时候就要定义好触屏所触发的操作!
下面就两种情况分别记录一下基本用法:
1.Layer接收触屏消息
用法很简单,只需要覆写父类的4个方法(可以根据需要,但是ccTouchBegan()是必须要覆写的,并且其返回值对触屏事件的传递有影响,后面会总结),并在init()方法中将其添加到CCTouchDispacher中,代码如下
class TouchableLayer: public CCLayer
{
public: virtual bool init(); LAYER_NODE_FUNC(TouchableLayer); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
};
在Layer的init()中添加如下代码,这个Layer就可以接收到触屏消息了
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, , true);
如果想通过这种方式判断具体触摸的Sprite或者区域等信息,就需要自己写判断和分发消息的代码了!
2.自定义可以接收触屏消息的Sprite
这种稍微复杂一些,但是还是比较好理解的,首先要先继承CCSprite或者其父类,以满足精灵形状,位置等信息的要求,另外还需要继承触屏事件委托CCTargetedTouchDelegate,CCTargetedTouchDelegate中定义了接收触屏信息的回调虚函数,而这些虚函数,正是我们需要覆写的部分,代码如下
class TouchableSprite: public CCSprite, public CCTargetedTouchDelegate
{ public:
TouchableSprite();
virtual ~TouchableSprite(); static TouchableSprite *touchSpriteWithFile(const char *file); bool initWithFile(const char *file); virtual void onEnter();
virtual void onExit(); CCRect rect();
bool containsTouchLocation(CCTouch *touch); virtual bool ccTouchBegan(CCTouch *touch, CCEvent *event);
virtual void ccTouchMoved(CCTouch *touch, CCEvent *event);
virtual void ccTouchEnded(CCTouch *touch, CCEvent *event); };
重点在于判断自定义Sprite是否被点击,这时就需要得到精灵所在的矩形了,这时又有两种判断方式
(1)得到触屏所在位置,然后根据精灵所在位置的矩形区域和触屏的点判断是否包含,如果包含,则说明触摸到了Sprite。这里写了一个得到精灵当前所在矩形的方法
CCRect TouchableSprite::rect()
{
CCSize size = getContentSize();
CCPoint pos = getPosition(); return CCRectMake(pos.x - size.width / , pos.y - size.height / , size.width, size.height);
}
然后在每次点击的时候都需要将当前触屏位置转换为GL坐标的位置,然后和Sprite所在矩形做包含判断
bool TouchableSprite::containsTouchLocation(cocos2d::CCTouch *touch)
{
CCPoint touchPoint = touch->locationInView(touch->view());
touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); return CCRect::CCRectContainsPoint(rect(), touchPoint);
}
(2)其实cocos2d为我们提供了一种相对简单的方法,但是原理类似,调用CCNode中定义的convertTouchToNodeSpaceAR()方法,将触屏点转化为相对于结点的相对坐标
(ps:由于默认anchor点是中点,所以每一个Sprite上的相对坐标系是从(-width / 2, -height / 2)为左上角点坐标),所以上面的两个方法需要修改一下
CCRect TouchableSprite::rect()
{
CCSize size = getTexture()->getContentSize(); return CCRectMake(-size.width / , -size.height / , size.width, size.height);
}
bool TouchableSprite::containsTouchLocation(cocos2d::CCTouch *touch)
{
return CCRect::CCRectContainsPoint(rect(), convertTouchToNodeSpaceAR(touch));
}
3.触屏传递顺序
另外需要主要的是
virtual bool ccTouchBegan(CCTouch *touch, CCEvent *event);
方法,其返回值是对此触屏消息有影响的,简单来说,如果返回false,表示不处理ccTouchMoved(),ccTouchEnded(),ccTouchCanceld()方法,而交由后续接收触屏消息的对象处理;如果返回true,表示会处理ccTouchMoved(),ccTouchEnded(),ccTouchCanceld()方法,并且消耗掉此触屏消息。
总结如下:
1.CCLayer 只有一层的情况:
4.自定义触屏事件
1、判断触摸点是否在指定区域内
HelloWorldScene.h
public:
CCRect mPlayBounds; virtual void registerWithTouchDispatcher();
virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
HelloWorldScene.cpp
删除bool HelloWorld::init()下do代码块中的所有代码,替换为:
CC_BREAK_IF(! CCLayer::init());
CCSize size = CCDirector::sharedDirector()->getWinSize();
//实例化一个精灵
CCSprite *mMainMenu = CCSprite::create("items.png", CCRectMake(, , , ));
CC_BREAK_IF(!mMainMenu);
//设置精灵的位置
mMainMenu->setPosition(ccp(size.width / , size.height / ));
this->addChild(mMainMenu); //绘制一个矩形
mPlayBounds = CCRectMake(size.width / - , size.height / + , , );
//设置为可触摸
this->setTouchEnabled(true); bRet = true;
添加两个函数:
void HelloWorld::registerWithTouchDispatcher()
{
//注册触摸监听
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, , true);
} bool HelloWorld::ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event)
{
//取得触摸点
CCPoint location = touch->getLocationInView();
//将触摸点转换为GL坐标系的点
location = CCDirector::sharedDirector()->convertToGL(location); //如果触摸点在矩形范围内则执行代码,切换场景
if (mPlayBounds.containsPoint(location))
{
CCScene *scene = SecondScene::scene();
CCDirector::sharedDirector()->replaceScene(CCTransitionJumpZoom::create(1.0f,scene));
}
return true;
}
cocos2d-x触屏事件(单点触屏)的更多相关文章
- HTML5学习总结-09 拖放和手机触屏事件
一 拖放 拖放(Drag 和 drop)是 HTML5 标准的组成部分.拖放是一种常见的特性,即抓取对象以后拖到另一个位置.在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 课程参考 ht ...
- cocos2dx基础篇(7) 触碰事件
cocos2dx游戏引擎的重点是在于移动设备的跨平台开发,而移动设备上的游戏大部分都是通过屏幕触碰来进行的.比如主菜单的按钮触碰,打飞机中飞机的触碰移动,都需要用到触碰操作.想一想之前讲的菜单按钮CC ...
- 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)
本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...
- JS的Touch事件们,触屏时的js事件
丫的,终于找到了JS在平板电脑上的事件!!! iphone.ipod Touch.ipad触屏时的js事件 1.Touch事件简介 pc上的web页面鼠标会产生onmousedown.on ...
- (转)js的左右滑动触屏事件
原文:http://blog.sina.com.cn/s/blog_6a0a183f0100zsfk.html (2012-01-20 08:55:53) 转载▼ 标签: 移动设备 触屏事件 杂谈 分 ...
- html5 touch事件实现触屏页面上下滑动(二)
五一小长假哪都没去,睡了三天,今天晕晕沉沉的投入工作了,但还是做出了一点点效果 上周用html5的touch事件把简单的滑动做出来了,实现了持续页面上下滑动的效果,参考之前 的文章及代码html5 t ...
- [IOS]自定义长触屏事件
写一个Demo来自定义一个长触屏事件,自定义长按手势. 实现步骤: 1.创建一个自定义手势类,命名为LongPressGestureRecognizer,在创建的时候继承UIGestureRecogn ...
- js触屏事件
js的左右滑动触屏事件,主要有三个事件:touchstart,touchmove,touchend.这三个事件最重要的属性是 pageX和 pageY,表示X,Y坐标. touchstart在触摸开始 ...
- 移动端touch触屏滑动事件、滑动触屏事件监听!
一.触摸事件 ontouchstart.ontouchmove.ontouchend.ontouchcancel 目前移动端浏览器均支持这4个触摸事件,包括IE.由于触屏也支持MouseEvent,因 ...
随机推荐
- 校园网之MentoHUST安装与使用
作用:MentoHUST可以解决校园网锐捷客户端与Windows的兼容性问题,可以解决安装虚拟机之后虚拟机网卡与本地网卡冲突的问题,可以做到愉快的用校园网,并可以愉快的用校园网开Wifi给自己或者小伙 ...
- poj1691(dfs)
链接 dfs了 写得有点乱 #include <iostream> #include<cstdio> #include<cstring> #include<a ...
- poj3368Frequent values(RMQ)
http://poj.org/problem?id=3368 追完韩剧 想起这题来了 想用线段树搞定来着 结果没想出来..然后想RMQ 想出来了 算是离散吧 把每个数出现的次数以及开始的位置及结束的位 ...
- phpstrom 与 xdebug 配合实现PHP单步调试
不说废话,直接开始. 第一步: 安装并配置xdebug 安装 可以从官网直接下载对应php版本的xdebug,下载地址: https://xdebug.org/download.php 配置,典型的 ...
- CodeForces_#354_Div.2_2016.5.25(A+B+C)
A 描述:给出一串数,可以互换任意两个数的位置一次,求最大的数和最小的数的最大距离. 分析:找到最大的数和最小的数的位置,求右边的数到左端点的距离和左边的数到右端点的距离. #include < ...
- 解决 android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
错误日志1: 06-13 10:55:50.410: E/KVLog(1129): Error info:java.lang.ClassCastException: android.widget.Li ...
- clone Control event handlers at run time
var btn2 =newButton(); btn2.Text= btn1.Text; btn2.size = btn1.size; To clone all events of any WinFo ...
- acm位运算应用 搜索
acm位运算应用 搜索 搜索 此处不讲题目,只讲位运算是怎样在这些题中实现和应用的.由于搜索题往往是基于对状态的操作,位运算往往特别有效,优化之后的效果可以有目共睹. 例1.POJ 132 ...
- [Stephen]Export from Excel to ALM
1.根据当前安装的ALM版本和Excel版本到https://hpln.hp.com/page/alm-excel-addin-page中对应的插件进行下载安装,安装时Excel需要关闭.安装成功后, ...
- LoadRunner脚本优化之—参数化迭代介
在LoadRunner的脚本优化时,有时发送给服务器的请求参数化时,服务器返回的内容也会和参数化的内容相对应,例如发送的请求带有查询key=123,则服务器也会返回含有123相关的内容.这时我们在使用 ...