位置: 编程技术 - 正文

cocos2dx-3.0(23) ScrollView 缩放 及 touch新用法

编辑:rootadmin

推荐整理分享cocos2dx-3.0(23) ScrollView 缩放 及 touch新用法,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

转自 在头文件中添加 #include "cocos-ext.h" 在添加使用域 USING_NS_CC_EXT;

2. 添加多继承 public ScrollViewDelegate,如下:

[cpp] view plaincopyclass HelloWorld : public LayerColor, public ScrollViewDelegate 我们转到ScrollViewDelegate里面,发现这是一个抽象基类,里面有两个纯虚函数,我们需要自己实现[cpp] view plaincopy /** * @js NA * @lua NA */ virtual void scrollViewDidScroll(ScrollView* view) = 0; /** * @js NA * @lua NA */ virtual void scrollViewDidZoom(ScrollView* view) = 0; 所以我们还需要在自己的类中添加这两行代码[cpp] view plaincopy//scrollview滚动的时候会调用 void scrollViewDidScroll(extension::ScrollView *view); //scrollview缩放的时候会调用 void scrollViewDidZoom(extension::ScrollView *view); 我们为了达到用鼠标点击图片移动时,出现缩小放大效果且能像相册一样切换图片,那么我们还需要添加触摸事件[cpp] view plaincopy bool onTouchBegan(Touch *touch, Event *pEvent); void onTouchMoved(Touch *touch, Event *pEvent); void onTouchEnded(Touch *touch, Event *pEvent); 下面直接看看在头文件中代码[cpp] view plaincopy#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "extensions/cocos-ext.h" #else #include "cocos-ext.h" #endif #include "cocostudio/CocoStudio.h" #include "CocosGUI.h" USING_NS_CC; USING_NS_CC_EXT; using namespace cocostudio; using namespace ui; #define PHOTO_COUNT class HelloWorld : public LayerColor, public ScrollViewDelegate { public: // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::Scene* createScene(); // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // a selector callback void menuCloseCallback(cocos2d::Ref* pSender); bool onTouchBegan(Touch *touch, Event *pEvent); void onTouchMoved(Touch *touch, Event *pEvent); void onTouchEnded(Touch *touch, Event *pEvent); //scrollview滚动的时候会调用 void scrollViewDidScroll(extension::ScrollView *view); //scrollview缩放的时候会调用 void scrollViewDidZoom(extension::ScrollView *view); //添加触摸 void addListener(); //添加粒子系统test void addParticle(); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); //骨骼动画 Armature *m_armature; //添加UI void addUI(); //添加场景(区别是我自定义的函数) void addMyScene(); private: //根据手势滑动的距离和方向滚动图层 void adjustScrollView(float offset); //void setback(); private: //存放所有图片 Vector< Sprite* > m_spVec; //当前的ScrollView extension::ScrollView *m_scrollView; //touchBegen时的触摸位置 Point m_touchPoint; //当前是第几张图片 int m_currentPage; }; #endif // __HELLOWORLD_SCENE_H__ 上面有很多不是我们这相例子里面的,不过不影响

在来看看源文件里面

[cpp] view plaincopybool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !LayerColor::initWithColor(Color4B(,,,)) ) { return false; } auto visibleSize = Director::getInstance()->getVisibleSize(); auto origin = Director::getInstance()->getVisibleOrigin(); /*auto scrollLayer = LayerColor::create(Color4B(0,0,0,)); scrollLayer->setContentSize(Size(,)); scrollLayer->setAnchorPoint(Point(0.5,0.5)); scrollLayer->setPosition(Point(visibleSize.width/2-, visibleSize.height/2-)); this->addChild(scrollLayer);*/ m_scrollView = extension::ScrollView::create(Size(visibleSize.width, visibleSize.height)); char spriteName[]; Layer *photoLayer = Layer::create(); for(int i = 1; i <= PHOTO_COUNT; &#;&#; i) { memset(spriteName, 0, sizeof(spriteName)); sprintf(spriteName, "XJ%d.jpg", i); auto sprite = Sprite::create(spriteName); sprite->setPosition(Point(visibleSize.width*(i*1.0-0.5), visibleSize.height*0.5)); //缩小一倍 //sprite->setScale(0.5); photoLayer->addChild(sprite); m_spVec.pushBack(sprite); } //设置layer到滚动层容器中 m_scrollView->setContainer(photoLayer); //重新设置滚动层的大小,这点很重要。 m_scrollView->setContentSize(Size(PHOTO_COUNT*visibleSize.width, visibleSize.height)); //设置代理 m_scrollView->setDelegate(this); m_scrollView->setPosition(Point::ZERO); //我们只在水平方向上滚动。 m_scrollView->setDirection(extension::ScrollView::Direction::HORIZONTAL); m_scrollView->setContentOffset(Point(0,0)); this->addChild(m_scrollView); m_currentPage = 0; //注册触摸,和2.x的不同了, 还有一种lambda表达式的写法 /************************************************************************ * lambda表达式的写法 * auto listener1 = EventListenerTouchOneByOne::create(); * listener1->onTouchBegan = [](Touch* touch, Event* event) * { * //dosomething * }; * listener1->onTouchMoved = [](Touch* touch, Event* event) * { * //dosomething * }; * listener1->onTouchEnded = [=](Touch* touch, Event* event) * { * //dosomething * }; * _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); ************************************************************************/ auto listener = EventListenerTouchOneByOne::create(); //设置是否想下传递触摸 listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this); //将触摸监听添加到eventDispacher中去 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this); //注册触摸结束 return true; } 我们在也不需要使用setTouchEnabled这个函数了,你会发现你用了以后,编译时会提示这个函数已经被否决了,可以用setEnable();代替看看如何。

对于上面的触摸我们要重点说说,说完了在继续分析 ScrollView!!!

一、触摸监听listener的创建方式有两种,

1、EventListenerTouchOneByOne2、EventListenerTouchAllAtOnce,顾名思义EventListenerTouchOneByOne的意思单点触摸,EventListenerTouchAllAtOnce是多点触摸而不需要再用设置Delegate的方式来做了。3.0触摸机制还有个不同的地方,只要是放在最上面的那个精灵,那它的触摸优先级就最高。我们用的按钮Menu 就是用这种方式设置触摸优先级的。

二、listener的调试优先级我们进入addEventListenerWithSceneGraphPriority的定义中看一下,有下面这一行代码:

[cpp] view plaincopylistener->setFixedPriority(0);

cocos2dx-3.0(23) ScrollView 缩放 及 touch新用法

它将精灵的触摸优先级设置成0,从这里我们可以引申出两个问题,一个就是当我们要给精灵设置触摸优先级时,

因为0已经被“官府”征用了,另一个问题就是:如果自己想设置精灵的触摸优先级,那应该怎么做呢?下面是提供的另外一种添加listener的方法:

[cpp] view plaincopy_eventDispatcher->addEventListenerWithFixedPriority(listener1 ,fixedPriority); 在第二个参数里设置触摸优先级,这样就可以了。

三、多个目标如何添加触摸监听如果多个精灵都想实现拖动的功能,那么这些精灵都可以使用listener1这一个触摸监听,例如我们有三个精灵,sprite,sprite2,sprite3,他们调用listener1的方式:

[cpp] view plaincopy _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3); 当我们进入到clone函数里面,你会发现他实现了复制触摸函数,也就是clone是专门用来这么干这的[cpp] view plaincopyEventListenerTouchOneByOne* EventListenerTouchOneByOne::clone() { auto ret = new EventListenerTouchOneByOne(); if (ret && ret->init()) { ret->autorelease(); ret->onTouchBegan = onTouchBegan; ret->onTouchMoved = onTouchMoved; ret->onTouchEnded = onTouchEnded; ret->onTouchCancelled = onTouchCancelled; ret->_claimedTouches = _claimedTouches; ret->_needSwallow = _needSwallow; } else { CC_SAFE_DELETE(ret); } return ret; } 四、 删除触摸监听

如果想移除sprite的触摸移动,可以这么做:

[cpp] view plaincopy_eventDispatcher->removeEventListeners(EventListener::Type::TOUCH_ONE_BY_ONE); 看完了新版 touch 我们继续看scrollView中的委托方法, 实现效果是对象在某个坐标范围内移动时会有缩放效果。

[cpp] view plaincopyvoid HelloWorld::scrollViewDidScroll(extension::ScrollView *view) { //往右移动x坐标为正,往左移为负 auto offPos = view->getContentOffset(); //log("offset pos %f %f", offPos.x, offPos.y); for(auto sp : m_spVec) { //获得当前对象的X坐标(不管怎么滚动,这个坐标都是不变的) auto pointX = sp->getPositionX(); //将精灵的 X坐标 &#; 偏移X坐标 float offX = pointX &#; offPos.x; //我的屏幕大小设置为了*,我的图片为*,我让图片居中显示(Point(,) ---> Point(,)) //图片与图片之间的间隔是一个屏幕(),我移动图片时不想让他缩放的太小,即只在-之间缩放,由于要对称,所以 //相应的-也会产生和-之间相同的缩放比例,这样后一种需要用-offx if( offX > && offX <= ) { float scaleX = offX / ; sp->setScale(scaleX); //log("scaleX1 %f",scaleX); } else if( offX > && offX <= ) { float scaleX = ( - offX) / ; sp->setScale(scaleX); //log("scaleX2 %f",scaleX); } else { //对于在-之外的,我们保持同一缩放比例 sp->setScale(*1.0/); } } } 我们应该知道,对象放到滚动层上,那么不管对象在scrollView上如何移动,它获得的坐标都是不会变的(如sp->getPosition()是不变的数&#;),这种情况下,如果我们想实现对象在某个坐标范围内会有缩放效果,那么只是去获取对象的坐标肯定是行不通的,所以肯定要找一个时刻在变化的”参照物”来利用下,该找什么呢?没错,就是scrollView的偏移坐标(scrollView->getContentOffset())!只要scrollView移动一下,那么它的 偏移量也随之改变。我这里就是利用对象的坐标与scrollView的偏移坐标之间不可告人的秘密,从而实现当前的目的。

实现了缩放,怎么去实现图片切换了,我们需要在触摸结束后,来切换ScrollView的偏移来达到切换效果

[cpp] view plaincopybool HelloWorld::onTouchBegan(Touch *touch, Event *pEvent) { m_touchPoint = Director::getInstance()->convertToGL(touch->getLocationInView()); log("begin x = %f, y = %f", m_touchPoint.x, m_touchPoint.y); return true; } 获得一个触摸初始&#;,将来与结束&#;对比来做出一些约束

[cpp] view plaincopyvoid HelloWorld::onTouchEnded(Touch *touch, Event *pEvent) { Point endPoint = Director::getInstance()->convertToGL(touch->getLocationInView()); float distance = endPoint.x - m_touchPoint.x; log("end x = %f, y = %f", endPoint.x, endPoint.y); //当我们移动的距离太小了,默认为不移动,也可以防止不小心碰了一下就切换了 if( fabs(distance) <= ) { log("this is 1"); adjustScrollView(0); } if(fabs(distance) > ) { log("this is 2"); adjustScrollView(distance); } } 去看看adjustScrollView里面实现了什么?

[cpp] view plaincopy<span style="font-family: Arial; font-size: px;">void HelloWorld::adjustScrollView(float offset) { if( offset < 0 ) { &#;&#;m_currentPage; } else if( offset > 0 ) { --m_currentPage; } if( m_currentPage < 0 ) { m_currentPage = 0; } else if( m_currentPage >= PHOTO_COUNT ) { m_currentPage = 1; } auto visibleSize = Director::getInstance()->getVisibleSize(); //注意这里为 负的 visibleSize.width, 我开始写成正的,一直不出效果 Point curPoint(-visibleSize.width * m_currentPage, 0); this->m_scrollView->setContentOffset(curPoint); //setback }</span><span style="font-family:SimSun;font-size:px;"> </span> 此程序依然存在一些bug,比如一下子滑动了很远的距离,那样图片的切换就会变得杂乱无章,这个依然可以在 触摸结束里面使用 distance 来限制,留给以后去完善吧!!

下面看看效果:

cocos2dx中函数指针传递的方法 目的看到群里有个朋友搞了好几天函数指针传递,没搞好。所以写一篇文章,旨在从cocos2dx中帮朋友们找到如何传递指针。旧版本的函数指针传递全局函

cocos2dx 3.3 视频播放的实现-VideoPlayer的使用 最近因为项目需求需要使用到视频播放功能。在3.x版本之前如果需要用到视频播放功能就要使用原生的视频播放实现技术,好在3.x之后官方已经集成了

Bullet(Cocos2dx)之内存泄露检测 编写的程序难免会有内存泄露,为了检测内存泄露,可以采取各种各样的措施,今天向大家介绍一款windows下的内存检测工具VisualLeakDetectorforVisualC去官网

标签: cocos2dx-3.0(23) ScrollView 缩放 及 touch新用法

本文链接地址:https://www.jiuchutong.com/biancheng/372634.html 转载请保留说明!

上一篇:Bullet(Cocos2dx)之优化PhysicsDraw3D

下一篇:cocos2dx中函数指针传递的方法(cocos2d教程)

  • 员工垫付的费用报销会计分录
  • 事业单位资产负责比往年增加表明什么
  • 未分配利润与净利润不相等
  • 出租固定资产的折旧额是什么意思
  • 经营利润和营业利润的区别
  • 水资源税怎么入账
  • 工程项目成本控制的方法
  • 虚开增值税发票的涉税风险如何防范
  • 税收的构成要素包含哪些内容
  • 固定资产的折旧费用计入什么科目
  • 内部往来科目设置在哪类下
  • 资金不需要验资,实收资本怎么入账
  • 离职未收回货款要我承担
  • 电商平台退货退款流程图
  • 汇票 到期
  • 长期股权投资顺流交易固定资产
  • 汇算清缴前取得暂估发票
  • 公司购买商业险多少钱
  • 发票逾期未认证个人要承担责任吗
  • 房地产开发公司怎么做账
  • 劳务公司增值税怎么抵扣
  • 小规模企业如何
  • 国税申报填错了怎么办
  • 什么是应交税费应交增值税科目设置的贷方明细科目
  • 退税入其他收益需要再缴税吗
  • 对账单回复函
  • 投资收益年底结转怎么算
  • 上月预付款项 这月开了发票会计分录
  • 车辆购置税退税条件
  • 小微企业关闭
  • bios如何恢复默认值
  • 红字专用发票信息表
  • u盘重装系统电脑
  • 其他综合收益属于什么科目借贷
  • php删除用户
  • 无法访问您可能的网络
  • PHP:session_regenerate_id()的用法_Session函数
  • 对公账户收款
  • 原材料废料怎么做账
  • php调用其他php
  • 竣工结算审计费用在线计算器
  • transformer中的参数
  • 资产支出加权平均数例题
  • 供热管道属于什么结构类型
  • 个体工商户是否属于企业
  • ibm-db2-admin
  • 企业所得税多预缴了怎么办
  • 平均资产总额与资产总额的关系
  • 资产组可收回金额包含完全商誉吗
  • 提取备用金如何填写现金日记账
  • 餐饮企业原材料采购描述错误的是
  • 人力资源外包服务包括哪些
  • 坏账收不回来如何做分录
  • 未认证的进项税额转出会计分录
  • 国有资产无偿划转税收政策
  • 存货过期报废进项税额怎么处理
  • 成本核算方法是移动加权平均法吗
  • 其他业务收入在资产负债表哪里体现
  • 外汇账户开立成功后,开户行应于
  • 自制原始凭证的填制
  • 台式电脑二级网页打不开怎么办
  • 组策略0x800704ec
  • windows8正版
  • windows10预览版是什么
  • osx安装win10
  • linux系统怎么安装
  • win7微软账户
  • WIN10远程桌面连接一直在配置远程会话
  • cocos2dx 3.17
  • JS实现的base64加密解密完整实例
  • opengl入门教程
  • shell脚本介绍
  • 如何用nodejs搭建服务端
  • 汉诺塔游戏教程
  • js限制字符长度
  • android listview数据动态加载
  • python数据通信
  • javascript中Date format(js日期格式化)方法小结
  • 重庆电子税务局网页版登录
  • 内蒙地税个人所得税标准
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设