移动轨迹
动画类写完了,但是游戏过程中的动画,是不断移动的。很多动画元素是事件触发移动,也有很多动画元素是固定路径不断循环移动的。
为了方便的编写循环移动的动画,写一个移动轨迹的管理类。对制作游戏会方便很多。
#ifndef SKMOVE_H_
#define SKMOVE_H_
#include <vector>
using namespace std;
#include "SkComm.h"
namespace sk_park {
//定义移动类型种类
typedef enum _SK_MOVE_TYPE {
SK_MOVE_TYPE_DEFAULT = 0, SK_MOVE_TYPE_LINE = 1,
} SK_MOVE_TYPE;
class SkMoveType {
public:
SkMoveType();
//重置此移动类型-直线移动,每秒移动的游戏基础坐标值
void ResetLineSpeedForSec(Sint32 x, Sint32 y);
protected:
SK_MOVE_TYPE m_iType;
Sint32 m_iX;
Sint32 m_iY;
friend class SkMove;
};
class SkMove {
public:
//移动类型的时长
vector<Sint32> m_vctMSec;
//移动类型
vector<SkMoveType> m_vctType;
SkMove();
//获取指定时间点,移动轨迹的坐标值
SkPostion * getPostion(Sint64 iMSecTime);
//设置轨迹起点,轨迹移动到终点后,从头移动
void setBeginPos(Sint32 x, Sint32 y);
//设置轨迹开始执行时间点
void setBeginTime(Sint64 iBeginMSec);
//添加轨迹移动类型,与对应的时长
void addMoveType(SkMoveType & stMoveType, Sint32 iMSec);
//清除所有移动类型
void clear();
//重置开始执行时间点
void reset(Sint64 iBeginMSec);
//记录轨迹起点
Sint32 m_iPosX;
Sint32 m_iPosY;
//始执行时间点
Sint64 m_iBeginMSec;
//移动总时长
Sint32 m_iTotalMSec;
private:
SkPostion m_skPos;
vector<Sint32> m_vctLx;
vector<Sint32> m_vctLy;
};
}
extern sk_park::SkMove g_SkMove;
#endif /* SKMOVE_H_ */
#include "pch.h"
#include "SkMove.h"
using namespace sk_park;
SkMoveType::SkMoveType() {
m_iType = SK_MOVE_TYPE_DEFAULT;
m_iX = 0;
m_iY = 0;
}
void SkMoveType::ResetLineSpeedForSec(Sint32 x, Sint32 y) {
m_iX = x;
m_iY = y;
m_iType = SK_MOVE_TYPE_LINE;
}
SkMove::SkMove() {
m_iPosX = 0;
m_iPosY = 0;
m_iBeginMSec = 0;
m_iTotalMSec = 0;
}
SkPostion * SkMove::getPostion(Sint64 iMSecTime) {
if (m_iBeginMSec == 0) {
m_iBeginMSec = iMSecTime;
}
Sint32 iMSec = iMSecTime - m_iBeginMSec;
if (iMSec < 0) {
iMSec = 0;
}
if (m_iTotalMSec > 0) {
Sint32 iMSecTmp = iMSec % m_iTotalMSec;
Sint32 iTmp = 0;
for (int i = 0; i < (int) m_vctMSec.size(); i++) {
int iT = iMSecTmp - iTmp;
iTmp += m_vctMSec.at(i);
if (iTmp >= iMSecTmp) {
Sint32 iTmpX = m_vctLx.at(i);
Sint32 iTmpY = m_vctLy.at(i);
SkMoveType & stMoveType = m_vctType.at(i);
Sint32 iMoveX = 0;
Sint32 iMoveY = 0;
switch (stMoveType.m_iType) {
case SK_MOVE_TYPE_LINE:
iMoveX = iT * stMoveType.m_iX / 1000;
iMoveY = iT * stMoveType.m_iY / 1000;
iTmpX += iMoveX;
iTmpY += iMoveY;
break;
default:
break;
}
m_skPos.x = iTmpX;
m_skPos.y = iTmpY;
return &m_skPos;
}
}
}
return &m_skPos;
}
void SkMove::setBeginPos(Sint32 x, Sint32 y) {
m_iPosX = x;
m_iPosY = y;
}
void SkMove::setBeginTime(Sint64 iBeginMSec) {
m_iBeginMSec = iBeginMSec;
}
void SkMove::addMoveType(SkMoveType & stMoveType, Sint32 iMSec) {
if (iMSec > 0) {
m_iTotalMSec += iMSec;
m_vctMSec.push_back(iMSec);
m_vctType.push_back(stMoveType);
Sint32 iTmpX = m_iPosX;
Sint32 iTmpY = m_iPosY;
if (m_vctLx.size() > 0) {
iTmpX = m_vctLx.back();
iTmpY = m_vctLy.back();
} else {
m_vctLx.push_back(iTmpX);
m_vctLy.push_back(iTmpY);
}
Sint32 iMoveX = 0;
Sint32 iMoveY = 0;
switch (stMoveType.m_iType) {
case SK_MOVE_TYPE_LINE:
iMoveX = iMSec * stMoveType.m_iX / 1000;
iMoveY = iMSec * stMoveType.m_iY / 1000;
m_vctLx.push_back(iTmpX + iMoveX);
m_vctLy.push_back(iTmpY + iMoveY);
break;
default:
break;
}
}
}
void SkMove::clear() {
m_vctMSec.clear();
m_vctType.clear();
m_vctLx.clear();
m_vctLy.clear();
m_iTotalMSec = 0;
}
void SkMove::reset(Sint64 iBeginMSec) {
m_iBeginMSec = iBeginMSec;
}
使用方式:
m_testAnimation.setBeginTime(g_SkGameTimer.m_siGameLastTime);
SkMoveType stMoveType;
m_testMove.setBeginPos(300, 300);
stMoveType.ResetLineSpeedForSec(100, 0);
m_testMove.addMoveType(stMoveType, 4000);
stMoveType.ResetLineSpeedForSec(0, 100);
m_testMove.addMoveType(stMoveType, 4000);
stMoveType.ResetLineSpeedForSec(-100, 0);
m_testMove.addMoveType(stMoveType, 4000);
stMoveType.ResetLineSpeedForSec(0, -100);
m_testMove.addMoveType(stMoveType, 4000);
m_testMove.setBeginTime(g_SkGameTimer.m_siGameLastTime);
//绘制游戏背景
SkPostion * pPos = m_testMove.getPostion(iCurMTime);
SkRect stPos;
stPos.x = 0;
stPos.y = 0;
pSkShow->drawPic(NULL, &m_background, &stPos);
stPos.x = pPos->x;
stPos.y = pPos->y;
pSkShow->drawAnm(NULL, &m_testAnimation, &stPos, iCurMTime);
效果: