缘起
为了我的下一个横向卷轴游戏,所以想设计一个卷轴游戏的卷动背景专用的类。
思路
思路其实是很简单,一般来说卷轴游戏的背景,是一张大张的图,前后可以环状的接合
所以我需要载入一张图片,将其设定为两个图,用前后贴的方式让它看起来有卷动的效果
提供了卷动座标(X或Y),卷动的间隔时间,卷动距离等属性
图形的卷动则是利用两张图的位置互换来模拟
代码
/*
* CBRingScrollImage.h
* CloudBox Cross-Platform Framework Project
*
* Created by Cloud on 2012/4/18.
* Copyright 2012 Orz. All rights reserved.
*
*/
#ifndef _CBRINGSCROLLIMAGE_
#define _CBRINGSCROLLIMAGE_
#include "CBView.h"
class CBImage;
enum ScrollCoordinate
{
ScrollX = 0,
ScrollY = 1
};
class CBRingScrollImage : public CBView
{
private:
CBImage* m_image1;
CBImage* m_image2;
ScrollCoordinate m_scrollCoordinate;
float m_distance;
float m_duration;
float m_swapLocation;
void initial();
void scrollImage(CBView* target);
void resetImage2();
protected:
void draw();
public:
CBRingScrollImage();
CBRingScrollImage(const string& imageName, ScrollCoordinate scrollCoordinate, float distance, float duration);
~CBRingScrollImage();
void startScroll();
void setImage(const string& imageName);
inline const ScrollCoordinate getScrollCoordinate() { return m_scrollCoordinate; }
inline void setScrollCoordinate(ScrollCoordinate scrollCoordinate) { m_scrollCoordinate = scrollCoordinate; }
inline const float getDistance() { return m_distance; }
inline void setDistance(float distance) { m_distance = distance; }
inline const float getDuration() { return m_duration; }
inline void setDuration(float duration) { m_duration = duration; }
};
#endif
/*
* CBRingScrollImage.cpp
* CloudBox Cross-Platform Framework Project
*
* Created by Cloud on 2012/4/18.
* Copyright 2012 Orz. All rights reserved.
*
*/
#include "CBRingScrollImage.h"
#include "CBImage.h"
#include "CBAction.h"
#include "CBEnvironment.h"
CBRingScrollImage::CBRingScrollImage()
:CBView(), m_image1(NULL), m_image2(NULL)
{
initial();
}
CBRingScrollImage::CBRingScrollImage(const string& imageName, ScrollCoordinate scrollCoordinate, float distance, float duration)
:CBView(), m_image1(NULL), m_image2(NULL), m_scrollCoordinate(scrollCoordinate),
m_distance(distance), m_duration(duration)
{
initial();
setImage(imageName);
}
CBRingScrollImage::~CBRingScrollImage()
{
DELETE(m_image1);
DELETE(m_image2);
}
void CBRingScrollImage::initial()
{
this->setWidth(CBEnvironment::getScreenWidth());
this->setHeight(CBEnvironment::getScreenHeight());
}
void CBRingScrollImage::setImage(const string& imageName)
{
m_image1 = new CBImage(imageName);
m_image2 = new CBImage(imageName);
m_image1->moveTo(0, 0);
m_swapLocation = 0;
resetImage2();
}
void CBRingScrollImage::resetImage2()
{
if(m_scrollCoordinate == ScrollX)
{
if(m_distance < 0)
m_image2->moveTo(m_image1->getWidth(), 0);
else if(m_distance > 0)
m_image2->moveTo(m_image1->getX() - m_image1->getWidth(), 0);
}
else if(m_scrollCoordinate == ScrollY)
{
if(m_distance < 0)
m_image2->moveTo(0, m_image1->getHeight());
else if(m_distance > 0)
m_image2->moveTo(0, m_image1->getY() - m_image1->getHeight());
}
}
void CBRingScrollImage::scrollImage(CBView* target)
{
bool isSwap = false;
if(m_scrollCoordinate == ScrollX)
{
m_image1->move(m_distance, 0);
m_image2->move(m_distance, 0);
if((m_image2->getX() <= 0 && m_distance < 0) ||
(m_image2->getX() + m_image2->getWidth() >= this->getWidth() && m_distance > 0))
isSwap = true;
}
else if(m_scrollCoordinate == ScrollY)
{
m_image1->move(0, m_distance);
m_image2->move(0, m_distance);
if((m_image2->getY() <= 0 && m_distance < 0) ||
(m_image2->getY() + m_image2->getHeight() >= this->getHeight() && m_distance > 0))
isSwap = true;
}
if(isSwap)
{
CBImage* temp = m_image1;
m_image1 = m_image2;
m_image2 = temp;
temp = NULL;
resetImage2();
}
}
void CBRingScrollImage::startScroll()
{
CBAction* action = new CBAction(m_duration,REPEAT_ALWAYS);
action->addTriggerEvent(this,&CBRingScrollImage::scrollImage);
action->commit(this);
}
void CBRingScrollImage::draw()
{
if(!this->getVisible())
return;
m_image1->visit();
m_image2->visit();
}