SDL游戏之路(十)--移动轨迹



移动轨迹


动画类写完了,但是游戏过程中的动画,是不断移动的。很多动画元素是事件触发移动,也有很多动画元素是固定路径不断循环移动的。

为了方便的编写循环移动的动画,写一个移动轨迹的管理类。对制作游戏会方便很多。

#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);


效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值