上一遍我们已经把osr的全部数据读出来了,虽然有些还不能看,但是至少全部的数据已经读取完毕了。这章我们来讲讲LifeBarGraph和TimeStamp。
##LifeBarGraph
在上一章我们读取出来的LifeBarGraph是下面这样的:
2254|1,4681|1,7548|1,9974|1,12181|1,15492|1,30489|1,32916|1,35135|1,37769|1,39988|1,42197|1,44386|1,47034|1,49220|1,51445|1,53629|1,55862|0.98,58614|1,60710|1,62901|1,65121|1,67437|0.99,69533|1,71695|...
ppy原文:Life bar graph: comma separated pairs u┃v, where u is the time in milliseconds into the song and v is a floating point value from 0 - 1 that represents the amount of life you have at the given time (0 = life bar is empty, 1= life bar is full).
大概意思就是LifeBar 是以逗号(,)分隔的形如"u|v"的字符串,其u是时间(毫秒),v是HP百分比
搞这么复杂,其实就是一个结构体啦
struct osrLifeBar
{
int time; //时间(毫秒)
float life; //生命值[0,1]
}
std::vector<osrLifeBar> LoadOsrLifeBar(const std::string str)
{
std::vector<osrLifeBar> LifeBar;
std::vector<std::string> lifeVec = split(LifeBarGraph.GetString().c_str(), ',');
for each (std::string var in lifeVec)
{
std::vector<std::string> vec= split(str, '|');
LifeBar lifebar;
lifebar.time = xtoi(vec[0].c_str());
lifebar.life = xtof(vec[1].c_str());
LifeBar.push_back(lifebar);
}
return LifeBar;
}
- 我原来是把osrLifeBar写成了一个类的,但是这样贴代码有些麻烦,就临时改成结构体+函数的形式了,思路是一样的:就是用split分割字符串。没有实际运行过不知道能不能跑,哈哈。
##TimeStamp
ppy的OSU是用C#写的,TimeStamp是C#中的DateTime.Ticks属性的值。DateTime.Ticks指的是从0001年1月1日0时0分0秒后所经过的时间,单位是100纳秒(0.1微秒)。在C#中可以直接用DateTime来把DateTime.Ticks转成年月日时分秒,那么如何在C++里实现呢?
在C/C++中有专门的时间类型time_t(其本质是__int64)。巧了,DateTime.Ticks也是一个8字节的数据。这就是我把TimeStamp定义成__int64的原因。虽然大小是一样的但是其含义却完全不同。time_t是格林威治时间,表示从1970年1月1日00:00:00所经过的秒数。
废话完了,上代码。
std::string str ;
if (TimeStamp > 621355968000000000)
{
tm local_time;
char str_time[1024] = { 0 };
time_t t = (TimeStamp - 621355968000000000) / 10000000;
localtime_s(&local_time, &t);
strftime(str_time, sizeof(str_time), "%Y-%m-%d,%H:%M:%S", &local_time);
str = "TimeStamp=" + str_time;
}
说明:
- (TimeStamp - 621355968000000000) / 10000000:这是0001年1月1日00:00:00到1970年1月1日00:00:00的DateTime.Ticks(在C# 里将两日期相减得到的);除以10000000是把单位100纳秒化为秒
- localtime_s():把time_t t转化为tm(关于struct tm的资料请自行百度)
- strftime():格式化时间的函数
这段代码的作用其实就是把DateTime.Ticks先转为time_t再转为struct tm,最后格式化为字符串。