您的位置:首页 > 移动开发 > Cocos引擎

COCOS2D-X 实现图片区域内滚动

2013-06-21 21:27 232 查看

制作游戏过程中也许会碰到这样的需求,写出来给大家分享。 转载请注明,谢谢。
先show一下效果:



实现思路:
通过CCSprite::setTextureRect修改图像显示区间,通过注册定时器任务实时刷新并显示。
废话不多说,上代码。

参考代码如下:
头文件:
class ScollDisplay : public CCNode
{
public:
CREATE_FUNC(ScollDisplay);

// 设置显示对象
void setDisPlayObj(CCSprite *pObj, CCSize dispSize, float speed, EDirection direction = ktLeft, bool bForever = true);

// 开始交替显示
void startShow();

private:
ScollDisplay();
~ScollDisplay();

virtual bool init();

// 接受定时更新
virtual void display(float dt);

protected:
bool m_bIsStarted;
CCRect m_curRect; // 当前的显示区域 通过调整这个来达到滚轴效果
CCSprite *m_pScollObj;
float m_fSpeed; // 每帧滚动速度
EDirection m_direction; // 滚动方向
bool m_bScollEnd; // 滚动结束
bool m_bScollForever; // 不断滚动还是滚动一次
};

代码实现:

//
//  ScollDisplay.cpp
//  Island of Jiang
//
//  Created by apple on 13-6-21.
//
//

#include "ScollDisplay.h"

ScollDisplay::ScollDisplay():m_bIsStarted(false), m_pScollObj(NULL), m_fSpeed(0), m_direction(ktLeft), m_bScollEnd(false), m_bScollForever(true){
}

ScollDisplay::~ScollDisplay()
{
}

// 初始化
bool ScollDisplay::init()
{
return true;
}

// 设置显示对象
void ScollDisplay::setDisPlayObj(CCSprite *pObj, CCSize dispSize, float speed, EDirection direction, bool bForever)
{
CC_RETURN_NONE_IF(!pObj);

m_bIsStarted = false;
m_pScollObj = pObj;
m_curRect   = CCRectMake(0, 0, dispSize.width, dispSize.height); // 初始显示区域
m_fSpeed    = speed;
m_direction = direction;
m_bScollForever = bForever;
m_bScollEnd = false;
}

// 开始交替显示
void ScollDisplay::startShow()
{
// 防止重复
if (m_bIsStarted) {
return;
}

schedule(schedule_selector(ScollDisplay::display));
display(0); // display first
}

// 接受定时更新
void ScollDisplay::display(float dt)
{
// 处理滚动逻辑
if (!m_pScollObj) {
return;
}

// 滚动到位了
if (m_bScollEnd) {
return;
}

CCSize textureSize = m_pScollObj->getTexture()->getContentSizeInPixels();
CCSize winSize = m_curRect.size;

// x最大坐标 = 窗口宽度 - 素材宽度 * 缩放比
float min_X = 0;
float max_X = (textureSize.width * m_pScollObj->getScaleX()) - winSize.width;

// y最大坐标 = 窗口高度 - 素材高度 * 缩放比
float min_Y = 0;
float max_Y = (textureSize.height * m_pScollObj->getScaleY()) - winSize.height;

// 计算偏差 并判断是否需要复位
float fxOffset = 0;
float fyOffset = 0;
switch (m_direction) {
case ktDown:
// first time init
if (!m_bIsStarted) {
m_curRect.origin.y = min_Y;
m_bIsStarted = true;
}

fyOffset += m_fSpeed;
m_curRect.origin.y += fyOffset;
if (m_curRect.origin.y > max_Y) {
if (m_bScollForever) {
m_curRect.origin.y = min_Y;  // 复位
}
else
{
m_bScollEnd = true;
}
return;
}
break;
case ktLeft:
// first time init
if (!m_bIsStarted) {
m_curRect.origin.x = min_X;
m_bIsStarted = true;
}

fxOffset += m_fSpeed;
m_curRect.origin.x += fxOffset;
if (m_curRect.origin.x  > max_X) {
if (m_bScollForever) {
m_curRect.origin.x = min_X; // 复位
}
else
{
m_bScollEnd = true;
}
return;
}
break;
case ktRight:
// first time init
if (!m_bIsStarted) {
m_curRect.origin.x = max_X;
m_bIsStarted = true;
}

fxOffset -= m_fSpeed;
m_curRect.origin.x += fxOffset;
if (m_curRect.origin.x  < min_X) {
if (m_bScollForever) {
m_curRect.origin.x = max_X; // 复位
}
else
{
m_bScollEnd = true;
}
return;
}
break;
case ktUp:
// first time init
if (!m_bIsStarted) {
m_curRect.origin.y = max_Y;
m_bIsStarted = true;
}

fyOffset -= m_fSpeed;
m_curRect.origin.y += fyOffset;
if (m_curRect.origin.y < min_Y) {
if (m_bScollForever) {
m_curRect.origin.y = max_Y;  // 复位
}
else
{
m_bScollEnd = true;
}
return;
}
break;

default:
CCLog("direction [%d] is invalid.", m_direction);
return;
}

// 通过设置特定区域来实现滚动
m_pScollObj->setTextureRect(m_curRect);
}


代码调用:

void GameMenuLayer::onNodeLoaded(cocos2d::CCNode * pNode,  cocos2d::extension::CCNodeLoader * pNodeLoader) {

// scoll upgrade pic
ScollDisplay *scollObj = ScollDisplay::create();
scollObj->setDisPlayObj(m_pUpgrade, CCSizeMake(115, 76), 1.0f);
scollObj->startShow();
this->addChild(scollObj);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Cocos2d-x 图片 滚动