cocos2d-x CCSrollView 源代码,可循环的SrollView代码
项目须要。写一个类似于iPhone上面时钟选择的可拉动式循环选择列表,通过集成CCScrollView并更改部分代码。实现了该功能。
假设想充分了解代码,请先阅读源码分析http://blog.csdn.net/u011225840/article/details/30033501
不考虑重构,这是我写的第一版代码,仅仅考虑了功能性。
过两天有时间后。我会将该部分代码重构,希望大家作对照~
#include "cocos2d.h"
#include "cocos-ext.h" using namespace cocos2d;
using namespace cocos2d::extension; #define SCROLL_DEACCEL_RATE 0.95f
#define SCROLL_DEACCEL_DIST 1.0f
enum MovingDirection
{
Left = 1,
Right = 2,
Up,
Down
}; enum Direction
{
CycleDirectionHorizontal=1,
CycleDirectionVertical }; enum Child
{
kLeft = 1,
kMiddle,
kRight
};
class CCCycleScrollView: public CCScrollView
{
public:
CCCycleScrollView();
virtual ~CCCycleScrollView(); static CCCycleScrollView* create(const char* spriteFile,Direction direction = CycleDirectionHorizontal); bool initWithViewSize(const char* spriteFile ,Direction direction = CycleDirectionHorizontal); bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
protected:
//调整三个sprite的位置
void adjustSprite(); void deaccelerateScrolling(float dt); void relocateContainer(); CCPoint findEndPoint();
//有三个一样的sprite来支持循环显示
CCSprite* m_sprite1;
CCSprite* m_sprite2;
CCSprite* m_sprite3; //每一个sprite的size
CCSize m_spriteSize; //上一次触碰点的坐标。用于推断当前移动的方向
CCPoint m_lastPoint;
//当前触碰点的坐标
CCPoint m_nowPoint; //当前偏移相应的位置
float m_nowPositionNum;
//上一次移动后的移动位数
int m_lastPositionNum;
//上一次正向移动是否移动过
bool m_lastPositiveDone;
//上一次反向移动是否移动过
bool m_lastNegtiveDone;
//正在移动的方向
MovingDirection m_moving; //滚动的限定方向
Direction m_direction; //temp
CCLabelTTF* temp1;
CCLabelTTF* temp2;
CCLabelTTF* temp3;
CCLabelTTF* temp4;
CCLabelTTF* temp5;
CCLabelTTF* temp6;
CCLabelTTF* temp7;
CCLabelTTF* temp8;
CCLabelTTF* temp9; void updateTemp(); };
#include "CCCycleScrollView.h" CCCycleScrollView::CCCycleScrollView():
m_sprite1(NULL),
m_sprite2(NULL),
m_sprite3(NULL),
m_lastPoint(ccp(0.0f,0.0f)),
m_nowPoint(ccp(0.0f,0.0f)),
m_lastPositionNum(0),
m_lastPositiveDone(false),
m_lastNegtiveDone(false)
{ } CCCycleScrollView::~CCCycleScrollView()
{ } bool CCCycleScrollView::initWithViewSize(const char* spriteFile ,Direction d )
{
if (CCLayer::init())
{
m_sprite1 = CCSprite::create(spriteFile);
m_sprite1->ignoreAnchorPointForPosition(false);
m_sprite1->setAnchorPoint(ccp(0.0f,0.0f));
CCSize spriteSize = m_sprite1->getContentSize(); temp1 = CCLabelTTF::create();
temp1->setContentSize(CCSizeMake(160,320));
temp1->setFontSize(80);
temp1->setAnchorPoint(ccp(0.5f,0.0f));
temp1->setString("10");
temp1->setPosition(ccp(80.0f,0.0f));
temp1->setTag(kLeft);
m_sprite1->addChild(temp1); temp2 = CCLabelTTF::create();
temp2->setContentSize(CCSizeMake(160,320));
temp2->setFontSize(80);
temp2->setAnchorPoint(ccp(0.5f,0.0f));
temp2->setString("11");
temp2->setPosition(ccp(240.f,0.0f));
temp2->setTag(kMiddle);
m_sprite1->addChild(temp2); temp3 = CCLabelTTF::create();
temp3->setContentSize(CCSizeMake(160,320));
temp3->setFontSize(80);
temp3->setAnchorPoint(ccp(0.5f,0.0f));
temp3->setString("12");
temp3->setPosition(ccp(400.0f,0.0f));
temp3->setTag(kRight);
m_sprite1->addChild(temp3); m_sprite2 = CCSprite::create(spriteFile);
m_sprite2->ignoreAnchorPointForPosition(false);
m_sprite2->setAnchorPoint(ccp(0.0f,0.0f)); temp4 = CCLabelTTF::create();
temp4->setContentSize(CCSizeMake(160,320));
temp4->setFontSize(80);
temp4->setAnchorPoint(ccp(0.5f,0.0f));
temp4->setString("1");
temp4->setPosition(ccp(80.0f,0.0f));
temp4->setTag(kLeft);
m_sprite2->addChild(temp4); temp5 = CCLabelTTF::create();
temp5->setContentSize(CCSizeMake(160,320));
temp5->setFontSize(80);
temp5->setAnchorPoint(ccp(0.5f,0.0f));
temp5->setString("2");
temp5->setPosition(ccp(240.0f,0.0f));
temp5->setTag(kMiddle);
m_sprite2->addChild(temp5); temp6 = CCLabelTTF::create();
temp6->setContentSize(CCSizeMake(160,320));
temp6->setFontSize(80);
temp6->setAnchorPoint(ccp(0.5f,0.0f));
temp6->setString("3");
temp6->setPosition(ccp(400.0f,0.0f));
temp6->setTag(kRight);
m_sprite2->addChild(temp6); m_sprite3 = CCSprite::create(spriteFile);
m_sprite3->ignoreAnchorPointForPosition(false);
m_sprite3->setAnchorPoint(ccp(0.0f,0.0f)); temp7 = CCLabelTTF::create();
temp7->setContentSize(CCSizeMake(160,320));
temp7->setFontSize(80);
temp7->setAnchorPoint(ccp(0.5f,0.0f));
temp7->setString("4");
temp7->setPosition(ccp(80.f,0.0f));
temp7->setTag(kLeft);
m_sprite3->addChild(temp7); temp8 = CCLabelTTF::create();
temp8->setContentSize(CCSizeMake(160,320));
temp8->setFontSize(80);
temp8->setAnchorPoint(ccp(0.5f,0.0f));
temp8->setString("5");
temp8->setPosition(ccp(240.0f,0.0f));
temp8->setTag(kMiddle);
m_sprite3->addChild(temp8); temp9 = CCLabelTTF::create();
temp9->setContentSize(CCSizeMake(160,320));
temp9->setFontSize(80);
temp9->setAnchorPoint(ccp(0.5f,0.0f));
temp9->setString("6");
temp9->setPosition(ccp(400.0f,0.0f));
temp9->setTag(kRight);
m_sprite3->addChild(temp9); if (d==CycleDirectionHorizontal)
{
m_sprite1->setPosition(ccp(-spriteSize.width,0.0f));
m_sprite2->setPosition(ccp(0.0f,0.0f));
m_sprite3->setPosition(ccp(spriteSize.width,0.0f));
m_eDirection = kCCScrollViewDirectionHorizontal;
}
else if(d==CycleDirectionVertical)
{
m_sprite1->setPosition(ccp(0.0f,-spriteSize.height));
m_sprite2->setPosition(ccp(0.0f,0.0f));
m_sprite3->setPosition(ccp(0.0f,spriteSize.height));
m_eDirection = kCCScrollViewDirectionVertical;
} if (!this->m_pContainer)
{
m_pContainer = CCLayer::create();
this->m_pContainer->ignoreAnchorPointForPosition(false);
this->m_pContainer->setAnchorPoint(ccp(0.0f, 0.0f));
this->m_pContainer->addChild(m_sprite1);
this->m_pContainer->addChild(m_sprite2);
this->m_pContainer->addChild(m_sprite3);
} this->setViewSize(CCSizeMake(spriteSize.width,spriteSize.height)); setTouchEnabled(true);
m_pTouches = new CCArray();
m_pDelegate = NULL;
m_bBounceable = true;
m_bClippingToBounds = true;
//m_pContainer->setContentSize(CCSizeZero); m_pContainer->setPosition(ccp(0.0f, 0.0f));
m_fTouchLength = 0.0f; this->addChild(m_pContainer);
//setContentOffset(ccp(-spriteSize.width,0));
/*
m_fMaxInset = ccp(spriteSize.width*300,0);
m_fMinInset = ccp(-spriteSize.width*300,0);
m_bBounceable = true;
*/ m_fMinScale = m_fMaxScale = 1.0f;
m_spriteSize = spriteSize;
m_direction = d;
return true;
}
return false;
} CCCycleScrollView* CCCycleScrollView::create( const char* spriteFile ,Direction d)
{
CCCycleScrollView* pRet = new CCCycleScrollView();
if (pRet && pRet->initWithViewSize(spriteFile,d))
{
pRet->autorelease();
}
else
{
CC_SAFE_DELETE(pRet);
}
return pRet;
} void CCCycleScrollView::ccTouchEnded( CCTouch *pTouch, CCEvent *pEvent )
{ if (!this->isVisible())
{
return;
} if (m_pTouches->count()==1)
{
this->schedule(schedule_selector(CCCycleScrollView::deaccelerateScrolling));
} m_pTouches->removeObject(pTouch); //没有touch时。须要设置状态
if (m_pTouches->count() == 0)
{
m_bDragging = false;
m_bTouchMoved = false; } } void CCCycleScrollView::ccTouchMoved( CCTouch *pTouch, CCEvent *pEvent )
{
CCScrollView::ccTouchMoved(pTouch,pEvent); m_nowPoint = convertToWorldSpace(convertTouchToNodeSpace(pTouch));
CCLog("The last point is %f",m_lastPoint.x);
CCLog("The now point is %f",m_nowPoint.x); if (m_direction==CycleDirectionHorizontal)
{ if (m_nowPoint.x>m_lastPoint.x)
{
m_moving = Right;
m_lastPoint = m_nowPoint;
}
else
{
m_moving= Left;
m_lastPoint = m_nowPoint;
}
m_nowPositionNum = m_pContainer->getPositionX() / m_spriteSize.width;
//CCLog("The nowNum is %d",nowPositionNum);
CCLog("The offset is %f",m_pContainer->getPositionX());
CCLog("The 1 is %f",m_sprite1->getPositionX());
CCLog("The 2 is %f",m_sprite2->getPositionX());
CCLog("The 3 is %f",m_sprite3->getPositionX());
CCLog("The move is %d",m_moving);
}else if (m_direction==CycleDirectionVertical)
{
if (m_nowPoint.y>m_lastPoint.y)
{
m_moving = Up;
m_lastPoint = m_nowPoint;
}
else
{
m_moving= Down;
m_lastPoint = m_nowPoint;
}
m_nowPositionNum = m_pContainer->getPositionY() / m_spriteSize.height;
} adjustSprite(); } bool CCCycleScrollView::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )
{
bool result = CCScrollView::ccTouchBegan(pTouch,pEvent);
m_lastPoint = convertToWorldSpace(convertTouchToNodeSpace(pTouch));
CCLog("The last point is %f",m_lastPoint.x);
if (m_pTouches->count()>1)
{
return false;
}
return result;
} void CCCycleScrollView::adjustSprite()
{ //正在向右移动 if (m_direction==CycleDirectionHorizontal)
{
if (m_moving==Right)
{
if (m_nowPositionNum-m_lastPositionNum>0.5)
{
m_lastPositiveDone=true;
m_lastPositionNum++;
}
//
if (m_lastPositiveDone)
{
m_sprite3->setPosition(ccp(m_sprite3->getPositionX()-m_spriteSize.width*3,0)); CCSprite* temp = m_sprite3;
m_sprite3 = m_sprite2;
m_sprite2 = m_sprite1;
m_sprite1 = temp;
updateTemp();
m_lastPositiveDone = false; } }
else if (m_moving==Left)
{
if (m_lastPositionNum-m_nowPositionNum>=0.5)
{
m_lastNegtiveDone=true;
m_lastPositionNum--;
} if (m_lastNegtiveDone)
{ m_sprite1->setPosition(ccp(m_sprite1->getPositionX()+m_spriteSize.width*3,0)); CCSprite* temp = m_sprite1;
m_sprite1 = m_sprite2;
m_sprite2 = m_sprite3;
m_sprite3 = temp;
updateTemp();
m_lastNegtiveDone=false;
}
}
}else if (m_direction==CycleDirectionVertical)
{
if (m_moving==Up)
{
if (m_nowPositionNum-m_lastPositionNum>0.5)
{
m_lastPositiveDone=true;
m_lastPositionNum++;
} if (m_lastPositiveDone)
{
m_sprite3->setPosition(ccp(0.0f,m_sprite3->getPositionY()-m_spriteSize.height*3));
CCSprite* temp = m_sprite3;
m_sprite3 = m_sprite2;
m_sprite2 = m_sprite1;
m_sprite1 = temp;
m_lastPositiveDone = false; } }
else if (m_moving==Down)
{
if (m_lastPositionNum-m_nowPositionNum>=0.5)
{
m_lastNegtiveDone=true;
m_lastPositionNum--;
} if (m_lastNegtiveDone)
{ m_sprite1->setPosition(ccp(0.0f,m_sprite1->getPositionY()+m_spriteSize.height*3));
CCSprite* temp = m_sprite1;
m_sprite1 = m_sprite2;
m_sprite2 = m_sprite3;
m_sprite3 = temp; m_lastNegtiveDone=false;
}
}
}
} void CCCycleScrollView::updateTemp()
{
if (m_moving==Right)
{
int num = atoi(((CCLabelTTF*)m_sprite2->getChildByTag(kLeft))->getString());
if (num-1==0)
{
num=13;
} ((CCLabelTTF*)m_sprite1->getChildByTag(kLeft))->setString(CCString::createWithFormat("%d",num-3)->getCString());
((CCLabelTTF*)m_sprite1->getChildByTag(kMiddle))->setString(CCString::createWithFormat("%d",num-2)->getCString());
((CCLabelTTF*)m_sprite1->getChildByTag(kRight))->setString(CCString::createWithFormat("%d",num-1)->getCString());
}
else if (m_moving==Left)
{
int num = atoi(((CCLabelTTF*)m_sprite2->getChildByTag(kRight))->getString());
if (num+1==13)
{
num=0;
}
((CCLabelTTF*)m_sprite3->getChildByTag(kLeft))->setString(CCString::createWithFormat("%d",num+1)->getCString());
((CCLabelTTF*)m_sprite3->getChildByTag(kMiddle))->setString(CCString::createWithFormat("%d",num+2)->getCString());
((CCLabelTTF*)m_sprite3->getChildByTag(kRight))->setString(CCString::createWithFormat("%d",num+3)->getCString());
}
} void CCCycleScrollView::deaccelerateScrolling(float dt)
{ //假设刚好在帧開始前 又有一个触摸点发生了began,造成了滚动状态,则取消并返回
if (m_bDragging)
{
this->unschedule(schedule_selector(CCCycleScrollView::deaccelerateScrolling));
return;
} //好玩的东西来咯 float newX, newY;
CCPoint maxInset, minInset;
//CCLOG("The end distance is %f",m_tScrollDistance.x);
//这里我不清楚为啥要出来。我用输出发如今move中。已经将此offset设置过了,不知为何还要设置,求大神解答。
m_pContainer->setPosition(ccpAdd(m_pContainer->getPosition(), m_tScrollDistance)); newX = m_pContainer->getPosition().x;
newY = m_pContainer->getPosition().y; m_tScrollDistance = ccpSub(m_tScrollDistance, ccp(newX - m_pContainer->getPosition().x, newY - m_pContainer->getPosition().y));
m_tScrollDistance = ccpMult(m_tScrollDistance, SCROLL_DEACCEL_RATE);
this->setContentOffset(ccp(newX,newY)); if (m_direction==CycleDirectionHorizontal)
{
m_nowPositionNum = m_pContainer->getPositionX() / m_spriteSize.width; }else if (m_direction==CycleDirectionVertical)
{
m_nowPositionNum = m_pContainer->getPositionY() / m_spriteSize.height;
} this->adjustSprite(); if ((fabsf(m_tScrollDistance.x) <= SCROLL_DEACCEL_DIST &&
fabsf(m_tScrollDistance.y) <= SCROLL_DEACCEL_DIST))
{
this->unschedule(schedule_selector(CCCycleScrollView::deaccelerateScrolling));
//CCLog("stop!!!!");
this->relocateContainer();
}
} void CCCycleScrollView::relocateContainer()
{ //调整位置
m_pContainer->setPosition(findEndPoint());
if (m_direction==CycleDirectionHorizontal)
{
m_nowPositionNum = m_pContainer->getPositionX() / m_spriteSize.width; }else if (m_direction==CycleDirectionVertical)
{
m_nowPositionNum = m_pContainer->getPositionY() / m_spriteSize.height;
} this->adjustSprite(); } cocos2d::CCPoint CCCycleScrollView::findEndPoint()
{
CCPoint nowPoint;
nowPoint.x = m_pContainer->getPositionX(); float interval = (nowPoint.x)/160;
int inter = (int)interval;
CCPoint newPoint;
if (fabsf(interval-inter)>=0.5)
{
if (inter<0)
{
newPoint.x = 160*(inter-1);
}
else
{
newPoint.x = 160*(inter+1);
} }
else
{
newPoint.x = 160*inter;
}
CCLog("The final offset is %f",nowPoint.x);
CCLog("The float is %f , the int is %d",interval,inter);
CCLog("The endpoint is %f",newPoint.x);
return ccp(newPoint.x,0.0f);
}
未重构的代码有些恶心~~
准备将重构后的代码再贴出来,并放在github上以供大家下载測试。
cocos2d-x CCSrollView 源代码,可循环的SrollView代码的更多相关文章
- Netbeans源代码编辑技巧——使用代码补全和代码生成
原文 Netbeans源代码编辑技巧——使用代码补全和代码生成 使用代码补全生成代码 一般来说,代码补全对于自动填充缺失的代码是有帮助的,例如标识符和关键字.截至 NetBeans IDE 6.0,您 ...
- 如何把C++的源代码改写成C代码?而C改C++只需一步!
★ 如何把C++的源代码改写成C代码? C++解释器比C语言解释器占用的存储空间要大,想要在某些特定场合兼容C++代码,同时为了节省有限的存储空间,降低成本,也为了提高效率,将用C++语言写的源程序用 ...
- Cocos2d入门--1--初涉相关属性或代码
Cocos2d vision: cocos2d-x-3.8.1 万丈高楼,起于累土.对于一个游戏框架的学习,其实在于框架功能的使用积累,学会了如何在cocos2d游戏引擎的基础上使用它提供的各种功能 ...
- 【我的Android进阶之旅】Android 源代码中的Java代码中//$NON-NLS-1$ 注释是什么意思?
1.背景 最近在负责公司基础业务和移动基础设施的开发工作,正在负责Lint代码静态检查工作.因此编写了自定义的Lint规则,在编写自定义的Lint规则前,当然是需要去把Google的关于Lint检测的 ...
- C++ 源代码到可执行代码的详细过程
编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序. 源代码-- ...
- linux源代码阅读笔记 get_free_page()代码分析
/* 34 * Get physical address of first (actually last :-) free page, and mark it 35 * used. If no fre ...
- VSS源代码管理器运行代码分析工具的命令
当你发现代码库总是报需要联系管理员运行代码分析工具时,你可以使用命令分析代码库代码解决: To fix the database problems, you can restart the analy ...
- discuz X3.1 源代码阅读,记录代码片段
require_once libfile('function/post'); // /source/function/function_post.php require_once libfile('p ...
- caffe源代码分析--math_functions.cu代码研究
当中用到一个宏定义CUDA_KERNEL_LOOP 在common.hpp中有. #defineCUDA_KERNEL_LOOP(i,n) \ for(inti = blockIdx.x * bloc ...
随机推荐
- C#中byte类型运算
首先看下面一段代码 byte x = 1; byte y = 2; byte z = x + y; Console.WriteLine(z); 可能很多人会说显示结果是3. 其实,这段代码无法运行,因 ...
- 字符数组函数,连接strcat 复制函数strcpy 比较函数strcmp 长度函数 strlen
之前我们学习数据类型的时候,有一个类型 char ,这个类型允许我们在里边放一个字符 char variable1='o'; char variable2='k'; #include <iost ...
- react笔记汇总
1.什么是React? a.React 是一个用于构建用户界面的 JAVASCRIPT 库. b.React主要用于构建UI,很多人认为 React 是 MVC 中的 V. c.React 起源于 F ...
- 牛客noip前集训营(第一场)提高T1
链接:https://www.nowcoder.com/acm/contest/172/A来源:牛客网 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个 ...
- 牛客OI赛制测试赛2 A 无序组数
链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序 ...
- DEV Express中Bar Manager的使用
未排版 在barManager中可以添加多种元素,如皮肤按钮,复选框等,但是下拉菜单却给出了多个冗余的控件. 遗留问题:怎么设置Bar为大图标,查找是否存在Ribbon控件. Bar 1, ...
- Leetcode 222.完全二叉树的节点个数
完全二叉树的节点个数 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最 ...
- msp430项目编程07
msp430中项目---简单计算器 1.扫描键盘工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习
- Python中排序的灵活使用
Python中列表按指定标准排序实例 概述 本题需要先输入机器的数目和任务的数目. 在接下来的n行中每行分别包含机器的最大执行时间和机器所能执行任务的最大强度. 在接下来的n行中每行分别包含任务执行时 ...
- POJ 3666 Making the Grade【DP】
读题堪忧啊,敲完了才发现理解错了..理解题必须看样例啊!! 题目链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110495#pro ...