本篇博客继续完善1024这个游戏,上一篇博客添加了基本的UI元素,留下了分数榜场景和新手引导场景,本篇博客我们来做一下新手引导这个场景,用到的类是CCScrollView,关于这个CCScrollView的使用,前面的博客有介绍,不明白的可以去看看,现在我们就利用这个类完成我们的逻辑。关于CCScrollView这里简单的说一下,我们用到的比较重要的俩点一个是视图大小和内容大小的概念,一个是偏移量。视图的大小就是可以看到的区域大小,而内容的大小是放在CCScrollView中的内容,我们只要放进去内容就可以了,不必要设置它的内容大小。视图大小就好比窗口的大小,这是我们去看元素的大小,而内容的大小就是窗口后边的风景了。偏移量很重要,我们使用CCScrollView并不打算实现它的触摸消息,而是将他的触摸置为false,使用CCScrollView所在层来接收触摸消息,然后设置CCScrollView里边内容的偏移量,达到我们最终的目的。

小塔1024——实现新手引导

#ifndef _GUID_SCENE_H_
#define _GUID_SCENE_H_
#include "cocos2d.h"
#include "cocos-ext.h"
//游戏主场景
#include "MainGameScene.h"

using namespace cocos2d;
using namespace cocos2d::extension;

class GuidScene : public CCLayer
{
public:
	static CCScene * scene();
	bool init();
	CREATE_FUNC(GuidScene);
	//和触摸相关的代码
	void registerWithTouchDispatcher();
	bool ccTouchBegan(CCTouch * touch,CCEvent * evt);
	void ccTouchMoved(CCTouch * touch,CCEvent * evt);
	void ccTouchEnded(CCTouch * touch,CCEvent * evt);
private:
	CCSize m_size;
	CCLayer * getContainerLayer();
	//scrollView
	CCScrollView * m_guidView;
	//scrollView偏移量
	CCPoint m_offset;
	//保存刚开始的触摸点
	CCPoint m_firstPoint;
	//当前显示的页数
	int m_curPage;
	//对最终的显示页数做一下调整
	void adjustScrollView(float offset);
	//开始按钮的响应函数
	void startClicked(CCObject * obj);
};

#endif
#include "GuidScene.h"

CCScene * GuidScene::scene()
{
	CCScene * scene = CCScene::create();
	GuidScene * layer = GuidScene::create();
	scene->addChild(layer);

	return scene;
}

bool GuidScene::init()
{
	if(!CCLayer::init())
	{
		return false;
	}

	m_size = CCDirector::sharedDirector()->getWinSize();

	//创建CCScrollView用来实现新手引导的功能
	m_guidView = CCScrollView::create();
	//设置scrollView的可视区域大小为屏幕的大小
	m_guidView->setViewSize(m_size);

	//设置scrollView中的内容
	m_guidView->setContainer(this->getContainerLayer());

	//将scrollView的触摸置为false,使用本层来接受触摸
	m_guidView->setTouchEnabled(false);

	//将scrollView添加到本场景中
	this->addChild(m_guidView);

	//开启触摸
	this->setTouchEnabled(true);

	//设置新手引导刚开始的页数
	this->m_curPage = 0;

	return true;
}

//以下四个函数和触摸相关,不解释
void GuidScene::registerWithTouchDispatcher()
{
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,-128,true);
}

bool GuidScene::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	//将刚开始点击的位置保存下来
	this->m_firstPoint = touch->getLocation();
	//保存原来的偏移量
	m_offset = this->m_guidView->getContentOffset();

	//以下的这一点特别要注意,大家可以先注释掉以下的这句话然后运行程序,会发现如果触摸不是很快
	//的时候不会有什么问题,但是如果触摸进行的很快,关卡的位置偏移的就不会正确,以下的代码正是解决这个问题到
	//代码的含义是只有偏移量为宽度的整数倍时才往下传递消息,放在最终的偏移动作没有执行完毕就再次接受触摸,导致错误
	if((int)this->m_offset.x%((int)m_size.width) == 0)
	{
		return true;
	}

	return false;
}

void GuidScene::ccTouchMoved(CCTouch * touch,CCEvent * evt)
{
	CCPoint point = touch->getLocation();
	//将移动过程中的坐标和刚开始的坐标相减,获得偏移量,因为我们是让新手引导的界面左右滑动
	//所以y方向的偏移量设置为0
	CCPoint offset = ccp(ccpSub(point,m_firstPoint).x,0);

	//如果用户是刚开始时向右滑动的,不允许,因为左边没有内容
	if(offset.x > 0 && this->m_curPage == 0)
		return;
	//也不能在最后一页向左滑动
	else if(offset.x < 0 && this->m_curPage == 4)
		return;

	//设置scrollView的偏移量
	this->m_guidView->setContentOffset(ccpAdd(m_offset,offset));
}

void GuidScene::ccTouchEnded(CCTouch * touch,CCEvent * evt)
{
	CCPoint point = touch->getLocation();
	//将最终手指停止的坐标位置和刚开始的坐标相减,获得偏移量
	CCPoint offset = ccp(ccpSub(point,m_firstPoint).x,0);

	//对最终的显示页数做一下调整
	this->adjustScrollView(offset.x);
}

void GuidScene::adjustScrollView(float offset)
{
	//如果是向左滑动的
	if(offset < 0)
		//改变页数
		this->m_curPage++;
	//向右滑动
	else
		this->m_curPage--;

	//调整一下页数
	if(m_curPage < 0)
		m_curPage = 0;
	else if(m_curPage > 4)
		m_curPage = 4;

	//设置最终的偏移量
	CCPoint adjustPoint = ccp(-m_size.width*m_curPage,0);

	//最后一个参数是偏移过去的时间
	this->m_guidView->setContentOffsetInDuration(adjustPoint,0.2f);
}

CCLayer * GuidScene::getContainerLayer()
{
	//创建一个层,在层上添加我们需要的内容
	CCLayer * layer = CCLayer::create();

	//在layer上边添加我们需要的内容
	for(int i=0;i<5;i++)
	{
		CCString * str = CCString::createWithFormat("help_%d.png",i);
		CCSprite * sprite = CCSprite::create(str->getCString());
		//添加的每张图片的大小和背景图片的大小是相同的,设置位置的时候是将他们相邻依次向右排开
		sprite->setPosition(ccp(m_size.width/2+m_size.width*i,m_size.height/2));
		//添加到层里边
		layer->addChild(sprite);

		//在最后一张图片上添加一个按钮
		if(i == 4)
		{
			//添加开始游戏按钮
			CCMenuItemImage * start = CCMenuItemImage::create("start_normal.png","start_clicked.png",
				this,menu_selector(GuidScene::startClicked));
			CCMenu * menu = CCMenu::create(start,NULL);
			menu->setPosition(ccp(m_size.width/2,m_size.height*0.15));
			sprite->addChild(menu);
		}
	}

	return layer;
}

//开始按钮的响应函数
void GuidScene::startClicked(CCObject * obj)
{
	CCDirector::sharedDirector()->replaceScene(MainGameScene::scene());
}

以上代码就是全部的实现,注释加的很清楚了,大家在昨天的基础上,添加相关的代码,这样就实现了这个新手引导的功能!