展会信息港展会大全

Cocos2d-x中使用CCScrollView来实现关卡选择实例
来源:互联网   发布日期:2015-09-28 10:40:34   浏览:1851次  

导读: 类似关卡选择的这种功能游戏中经常看到,比如帮助场景,选择关卡,通过滑动的方式选择一些其他的东西等等。今天我们实现关卡的选择是使用CCScrollView这个类。当然还有一些其他的方法,比如使用c...

类似关卡选择的这种功能游戏中经常看到,比如帮助场景,选择关卡,通过滑动的方式选择一些其他的东西等等。今天我们实现关卡的选择是使用CCScrollView这个类。当然还有一些其他的方法,比如使用cocostudio的page view也可以。我先说下整体的思路,CCScrollView这个类是继承自CCLayer的,本身的触摸事件有些bug,所以网上一般将这个层的touch事件处理为false,而使用它的父节点来处理触摸事件,我们也是采用这个做法。先定义一个LevelScene类,将CCScrollView加入进来,然后再定义一个layer层,这个层里边放的就是一些关卡的图片,然后将layer这个层作为CCScrollView的内容添加进去。好了,现在看代码吧。

/*关卡选择类的头文件*/

#ifndef _LEVEL_SCENE_H_

#define _LEVEL_SCENE_H_

#include "cocos2d.h"

//包含以下的头文件

#include "cocos-ext.h"

using namespace cocos2d::extension;

using namespace cocos2d;

class LevelScene : public CCLayer

{

public:

bool init();

CREATE_FUNC(LevelScene);

//以下是注册触摸事件和实现各种的touch函数

void registerWithTouchDispatcher();

bool ccTouchBegan(CCTouch * touch,CCEvent * pEvent);

void ccTouchMoved(CCTouch * touch,CCEvent * pEvent);

void ccTouchEnded(CCTouch * touch,CCEvent * pEvent);

//最后这个函数来校验每个关卡的位置,是各个关卡都位于屏幕的中央

void adjustScrollView(float offset);

private:

//将CCScrollView作为自己的层添加进来

CCScrollView * m_scrollView;

//触摸点的位置

CCPoint m_touchPoint;

//CCScrollView的便宜量

CCPoint m_offsetPoint;

//当前为第几个关卡

int m_nCurPage;

};

#endif

/*关卡选择类的具体实现*/

#include "LevelScene.h"

#include <math.h> //用到了fabs()函数,用来求绝对值的

bool LevelScene::init()

{

bool bRet = false;

do

{

CC_BREAK_IF(!CCLayer::init());

CCSize winSize = CCDirector::sharedDirector()->getWinSize();

//CCScrollView继承自CCLayer,传入的参数是view size的大小

//view size也就是人看到的大小,content size也就是内容的大小

//这里设置为整个屏幕的大小,也就是我们通过设备的整个屏幕去看里边的内容

CCScrollView * scrollView = CCScrollView::create(CCSize(winSize.width,winSize.height));

//等同于如下的语句

/*CCScrollView * scrollView = CCScrollView::create();

scrollView->setViewSize(CCSize(winSize.width,winSize.height));*/

//以下是CCScrollView的一些常用函数,但是我们这里都不会用到,实现的思路不同

//设置是否有反弹的效果,反弹就是当超出scrollview的大小的时候回到原来的位置

//scrollView->setBounceable(true);

//CCScrollView默认锚点是在(0,0)处

//scrollView->ignoreAnchorPointForPosition(false);

//scrollView->setPosition(ccp(winSize.width/2,winSize.height/2));

//设置滑动方向

//kCCScrollViewDirectionHorizontal——水平滑动

//kCCScrollViewDirectionVertical——垂直滑动

//scrollView->setDirection(kCCScrollViewDirectionBoth);

//创建一个CCLayer,将内容添加到CCLayer中,然后将这个layer添加到scrollview中

CCLayer * layer = CCLayer::create();

for(int i = 0;i<5;i++)

{

CCString * string = CCString::createWithFormat("%d.jpg",i+1);

CCSprite * sprite = CCSprite::create(string->getCString());

//将所有的精灵都放到屏幕的中间显示

sprite->setPosition(ccpAdd(ccp(winSize.width/2,winSize.height/2),

ccp(winSize.width*i,0)));

layer->addChild(sprite);

}

//设置scrollView中的内容,必须先设置内容再设置内容的大小

scrollView->setContainer(layer);

//setContentSize()设置内容区的大小

scrollView->setContentSize(CCSize(winSize.width*5,winSize.height));

//我们屏蔽scrollView这个层的触摸,采用其他的实现方法

scrollView->setTouchEnabled(false);

//设置里边内容的偏移量

scrollView->setContentOffset(CCPoint(0,0));

//让本层来接受触摸事件

this->setTouchEnabled(true);

this->addChild(scrollView);

m_scrollView = scrollView;

this->m_nCurPage = 0;

bRet = true;

}

while(0);

return bRet;

}

void LevelScene::registerWithTouchDispatcher()

{

CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);

}

bool LevelScene::ccTouchBegan(CCTouch * touch,CCEvent * pEvent)

{

//用开始的触摸点和scroll的偏移量初始化以下的成员变量

this->m_touchPoint = touch->getLocation();

this->m_offsetPoint = this->m_scrollView->getContentOffset();

//以下的这一点特别要注意,大家可以先注释掉以下的这句话然后运行程序,会发现如果触摸不是很快

//的时候不会有什么问题,但是如果触摸进行的很快,关卡的位置偏移的就不会正确,以下的代码正是解决这个问题到

if((int)this->m_offsetPoint.x%((int)CCDirector::sharedDirector()->getWinSize().width) == 0)

{

return true;

}

return false;

}

/*以下代码的整体含义就是当手指移动的时候,让关卡跟随手指移动,当移动结束的时候,判断结束点和开始

触摸点的位置,对关卡的位置做相应的处理*/

//设置关卡跟随手指的方向移动

void LevelScene::ccTouchMoved(CCTouch * touch,CCEvent * pEvent)

{

CCPoint point = touch->getLocation();

CCPoint direction = ccpSub(point,this->m_touchPoint);

//CCPoint spriteDirection = ccpAdd(this->m_offsetPoint,direction);

//只在x方向偏移

CCPoint spriteDirection = CCPoint(direction.x+this->m_offsetPoint.x,0);

this->m_scrollView->setContentOffset(spriteDirection);

}

//以下的代码是重点,当结束触摸的时候,为了使关卡显示在屏幕的中间,我们需要这么做

void LevelScene::ccTouchEnded(CCTouch * touch,CCEvent * pEvent)

{

CCPoint endPoint = touch->getLocation();

float distance = endPoint.x-this->m_touchPoint.x;

//手指移动的距离小于20的时候,就将偏移量作为0处理

if(fabs(distance) < 20)

{

this->adjustScrollView(0);

}

else

{

//将偏移量作为参数传进来

this->adjustScrollView(distance);

}

}

//调整关卡的最终位置

void LevelScene::adjustScrollView(float offset)

{

CCSize winSize = CCDirector::sharedDirector()->getWinSize();

// 我们根据 offset 的实际情况来判断移动效果

//如果手指往左划,offset大于0,说明页面在减小,往右增大

if (offset < 0)

m_nCurPage ++;

else if (offset > 0)

m_nCurPage --;

//不允许超出最左边的一页和最右边的一页

if (m_nCurPage < 0)

m_nCurPage = 0;

else if (m_nCurPage > 4)

m_nCurPage = 4;

CCPoint adjustPoint = ccp(-winSize.width * m_nCurPage , 0);

//这个函数比setContentOffset多了一个参数,第二个参数是设置时间的,就是用多长的时间来改变偏移量

this->m_scrollView->setContentOffsetInDuration(adjustPoint, 0.3f);

}

bool HelloWorld::init()

{

//////////////////////////////

// 1. super init first

if ( !CCLayer::init() )

{

return false;

}

CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

//添加背景图片

CCSprite * sprite = CCSprite::create("background.png");

sprite->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));

this->addChild(sprite);

//添加CCScrollView层

LevelScene * scrollView = LevelScene::create();

this->addChild(scrollView);

return true;

}

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港