[Qboy原创]

在Cocos2dX 3.0 中已经实现一些牛逼的滚动层,但是对于有一些需要实现循环滚动的要求确没有实现,笔者在前段时间的一个做了一个游戏,需求是实现在少有的(13个)英雄中进行循环滚动层,即用户可以无限的向一个方向滚动,当到最后时,由前面的进行重复出现。

如下图:

为了满足以上需求,我第一反应就想到了采用大学数据结构中所学的双向链表。想想还真称靠谱诶。那就说干就干吧。

1、定义双向链接表结构:

struct CycNode{//构建双向链表结构

CycNode* preNode;//前一个节点

cocos2d::gui::ImageView* node; //所对应的Node

CycNode* nextNode;//后一个节点

};

2、定义回调函数

由于在本游戏中拖拽还有一些事件,所以需要向外暴露一些事件。定义如下:

class CycScrollDelegate{

public:

virtual void dragBeginNode(cocos2d::Node* node,cocos2d::Touch* touch) = 0; //开始拖拽时拖拽的节点

virtual void dragMoveNode(cocos2d::Node* node,cocos2d::Touch* touch) = 0; //拖拽移动时拖拽的节点

virtual void dragEndNode(cocos2d::Node* node,cocos2d::Touch* touch) = 0; //拖拽结束后拖拽的节点

};

其实以上事件都会在层的Touch事件中实现

3、定义实现类

.h文件:

class CycScrollView:public cocos2d::gui::Widget{

CC_SYNTHESIZE(float, scrollHeight, ScrollHeight);//设置滚动时的高度限制 CC_SYNTHESIZE(CycScrollDelegate*, owerner, Owerner);

private:

CycNode* pFirstCycNode;

cocos2d::Node* selNode;

Size winSize;

bool canScroll;

public:

virtual void onExit();

virtual bool init();

CREATE_FUNC(CycScrollView);

public:

void loadScrollView(std::vector<cocos2d::gui::ImageView*> listNode); //真实加载循环滚动条中的Vector文件

};

.cpp 文件

(1)实现双向链表,并将双向链表构成环状

for (cocos2d::gui::ImageView* n: listNode) {//定义成双向链表节点

CycNode* cycnode = new CycNode();

cycnode->node = n;

n->setUserData(&cycnode);//将节点反向回双向链表

cycnode->preNode = pcycNode;

if(pcycNode){

pcycNode->nextNode = cycnode;

}

pcycNode = cycnode;

if(pFirstNode==NULL){

pFirstNode = cycnode;

}

}

(2)将节点设定相应的锚点和坐标,并添加到Widge上

int index=0;

for (cocos2d::gui::ImageView* n: listNode) {

n->setAnchorPoint(Point::ZERO);

n->setPosition(Point(index*C_WIDTH,0));

addChild(n);

index++;

}

canScroll = C_WIDTH*listNode.size()>winSize.width;//设定是否需要循环滚动,如果小于可视化大小的话,则不需要滚动。

(3)注册页面的Touch事件,回调相应的Touch事件。

auto listener = EventListenerTouchOneByOne::create();

listener->setSwallowTouches(true);

listener->onTouchBegan = [this](Touch* touch,Event* e){

curPoint = touch->getLocation();

curPoint = convertToNodeSpace(curPoint);

selNode = nullptr;

if(owerner){

CycNode* pcurNode = pFirstCycNode;

do {

Size nodeSize = pcurNode->node->getSize();

Point p = pcurNode->node->getPosition();

Rect r = Rect(p.x, p.y, nodeSize.width, nodeSize.height);

if(r.containsPoint(curPoint)){

selNode = pcurNode->node;

owerner->dragBeginNode(pcurNode->node, touch);

break;

}

pcurNode=pcurNode->nextNode;

} while (pcurNode!=pFirstCycNode);

}

if(curPoint.y>0&&curPoint.y<scrollHeight){

return true;

}

return false;

};

listener->onTouchMoved = [this](Touch* touch,Event* e){

if(!canScroll){

return;

}

Point newPoint = touch->getLocation();

newPoint = convertToNodeSpace(newPoint);

float deltaX = newPoint.x-curPoint.x;

CycNode* pmoveFirst = NULL;

CycNode* pcurNode = this->pFirstCycNode;

int index = 0;

float y;

if(deltaX<0){//向左移

float maxX = 0;

do {

Point nPoint = (pcurNode->node)->getPosition();

float preX = nPoint.x;

if(preX>maxX&&preX<=winSize.width){

pmoveFirst = pcurNode;

maxX = preX;

y=nPoint.y;

}

index++;

pcurNode = pcurNode->nextNode;

}while (pcurNode!=pFirstCycNode);

pmoveFirst->nextNode->node->setPosition(Point(maxX+C_WIDTH,y));

}

if(deltaX>0){//向右移

float minX = 1200;

float y;

do {

Point nPoint = (pcurNode->node)->getPosition();

float preX = nPoint.x;

if(preX<minX&&preX>=0){

pmoveFirst = pcurNode;

minX = preX;

y=nPoint.y;

}

index++;

pcurNode = pcurNode->nextNode;

}while (pcurNode!=pFirstCycNode);

pmoveFirst->preNode->node->setPosition(Point(minX-C_WIDTH,y));

}

if(pmoveFirst){

pcurNode=pmoveFirst;

do {

Point nPoint = (pcurNode->node)->getPosition();

float newX = nPoint.x+deltaX;

(pcurNode->node)->setPosition(Point(newX,y));

pcurNode = pcurNode->nextNode;

}while (pcurNode!=pmoveFirst);

}

if(owerner&&selNode){

owerner->dragMoveNode(selNode, touch);

}

curPoint = newPoint;

};

listener->onTouchEnded=[this](Touch* touch,Event*){

Point newPoint = touch->getLocation();

newPoint = convertToNodeSpace(newPoint);

if(owerner&&selNode){

owerner->dragEndNode(selNode, touch);

}

};

listener->onTouchCancelled=[this](Touch* touch,Event*){

Point newPoint = touch->getLocation();

newPoint = convertToNodeSpace(newPoint);

if(owerner&&selNode){

owerner->dragEndNode(selNode, touch);

}

};

_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

 4、后续

在本例已大体体现了需求,如果有需要比如上下滚动的可以相应的进行调整修改,其他的需求进行酌情进行增减。另外,在本例中也没有实现IOS中滚动层滚动手势加速功能(目前也还没有想好,有思路的朋友可以告诉我哦)。

转载于:https://blog.51cto.com/qboy1987/1422214

Cocos2dx中利用双向链表实现无限循环滚动层相关推荐

  1. unity实现图片轮播效果_unity 背景无限循环滚动效果

    背景无限循环滚动效果如下示: 步骤如下: 导入背景图片后,设置图片的格式,如下图: 2.图片格式也可以设置是Texture格式,但是Wrap Mode 一定要是Repeat[重复发生]:然后记得App ...

  2. 【Android】ViewPager实现无限循环滚动

    最近做的一个项目,客户要求在ViewPager实现的主页面中滑动到最后一页后继续滑动能返回到第一页,也就是实现无限循环滚动,效果如下: 看了下ViewPager没有滑到尽头的回调方法,因此想到的解决方 ...

  3. JQuery图片无限循环滚动源码

    平常项目中经常用到图片循环滚动,所以就写些必要的CSS定位,JS基本算法,最后就封装成JQuery图片无限循环滚动插件类,其实本质上是li块无限循环滚动,li块里面不管是图片还是其它内容,都OK的. ...

  4. Swiper:无限循环滚动时出现空白页/页面内容不刷新

    问题描述 使用Swiper插件实现列表的无限循环滚动效果,记录遭遇的两个问题:①滚动到某页时界面显示空白:②用id唯一标识列表中需要动态改变的值,在改变某一id的div内容后,页面显示内容并未改变 问 ...

  5. ios之实现自动无限循环滚动视图(1)

    ios之实现自动无限循环滚动视图(1) 前言 效果展示 功能 分析 全部代码 前言 ios实现无限循环滚动主要有两种办法,都利用了UIScrollView,第一种是创建一个很大的UIScrollVie ...

  6. 在线直播系统源码,横向无限循环滚动的单行弹幕效果

    在线直播系统源码,横向无限循环滚动的单行弹幕效果实现的相关代码 实现思路分析 要实现上面的效果,我们先拆分下实现要素: 1.弹幕布局是从屏幕的右侧向左侧滚动,单个弹幕之间的间距是固定的(设计要求) 2 ...

  7. Unity3d学习笔记-无限循环滚动背景(完整的商店广告牌组件)

    在游戏项目中我们常常看到商城的广告牌,几张广告图片循环滚动,类似跑马灯,现在我将讨论一种实现方法,并提供一个管理类,大家可以直接使用. 实现原理:背景图片循环滚动的原理很简单:两张图片向一个方向移动, ...

  8. [jQuery基础] jQuery动效案例(二) -- 图标特效、无限循环滚动(简易轮播图)

    图标特效 实现效果展示 实现步骤 第一步(实现静态效果) CSS部分 *{margin: 0;padding: 0; } ul{list-style: none;width: 400px;height ...

  9. 文字/图片向上无限循环滚动

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

最新文章

  1. #@python常见的代码自己编写问题
  2. python绘制雷达图-使用Python绘制雷达图
  3. slidingmenu 中view使用练习
  4. 又一次回到追寻梦想的地方
  5. 一分钟明确 VS manifest 原理
  6. 全链路数据血缘在满帮的实践
  7. 实现服务器和客户端数据交互,Java Socket有妙招
  8. SAP License:SAP 清帐介绍
  9. php报错处理,关于升级php7后的报错处理
  10. 16-微信小程序商城 购物车首页底部菜单(微信小程序商城开发、小程序毕业设计、小程序源代码)(黄菊华-微信小程序开发教程)
  11. RPG游戏之龙腾世纪魔术师养成攻略
  12. 年薪30W+,数据库工程师凭什么?
  13. 关于回溯法的递归与非递归-----N皇后问题
  14. 人工智能新风口上,网易是否能够突围?
  15. 美团2020后台校招题目--美团骑手包裹区间分组
  16. matlab输出箱线图的五个特征值_Matlab绘制箱线图
  17. eclipse简介及下载
  18. 解决video更多选项按钮点击无反应以及操控video标签的控制按钮
  19. 如何利用手机访问电脑本地的localhost?
  20. 也许你在到处找PS,不妨来这里看看

热门文章

  1. Java面试题详解一:面向对象三大特性
  2. WEB前端开发工程师 学习第二天 边框
  3. 自定义异常并抛出,捕获
  4. Vue打包项目图片等静态资源的处理
  5. halcon算子翻译——compose3
  6. 杭电 4907 Task schedule ·
  7. iOS开发--完整项目
  8. java.util.concurrent.atomic原子操作类包
  9. python模块文件的扩展名不一定是py_Python导入:导入没有.py扩展名的模块?
  10. java 枚举获取key_「Java必修课」HashMap性能很好?问过我EnumMap没