用 c++ 编写一堆类似的 if 语句的漂亮方法
Pretty way to code a bunch of similar if statements in c++?
我想为精灵制作动画。为此,我有一个自动收报机,可以给我一个以毫秒为单位的时间。根据时间的不同,我希望精灵显示不同的图像。不幸的是,除了一堆if语句之外,我想不出一种简单而漂亮的方法来做到这一点。
if (ticker_.getElapsedTime().asMilliseconds() >= ANIMATION_STEP * 0 &&
ticker_.getElapsedTime().asMilliseconds() < ANIMATION_STEP * 1)
{
sprite_.setTexture(*game_->getResourceManager().getTexture("animation/explosion_00.png"));
}
if (ticker_.getElapsedTime().asMilliseconds() >= ANIMATION_STEP * 1 &&
ticker_.getElapsedTime().asMilliseconds() < ANIMATION_STEP * 2)
{
sprite_.setTexture(*game_->getResourceManager().getTexture("animation/explosion_01.png"));
}
// 10 more of these ...
if (ticker_.getElapsedTime().asMilliseconds() >= ANIMATION_STEP * 13 &&
ticker_.getElapsedTime().asMilliseconds() < ANIMATION_STEP * 14)
{
sprite_.setTexture(*game_->getResourceManager().getTexture("animation/explosion_13.png"));
}
像这样的东西怎么样
int frame = ticker_.getElapsedTime().asMilliseconds() / ANIMATION_STEP;
if (frame < MAX_FRAMES) {
std::string filename = "animation/explosion_"
+ std::to_string(frame) + ".png";
}
鉴于步骤是偶数的,您可以计算使用哪一个:
int step = ticker_.getElapsedTime().asMilliseconds() / ANIMATION_STEP;
您可以进行整数到字符串的转换来使用它来创建文件名,但这使用起来有些尴尬且过于僵化。相反,您可以填充一个文件名数组:
// populate array during program initialization
vector<string> explosion_filenames;
// In your function,
sprite_.setTexture(*game_->getResourceManager().getTexture(explosion_filenames[step]));
甚至更好的是,一系列纹理:
// populate array during program initialization
vector<whatever_the_texture_type_is> explosion_textures;
// In your function,
sprite_.setTexture(*explosion_textures[step]));
如果步骤不均匀,则可以改用有序映射
// I use `int`, but use whatever type is most appropriate
// populate map during program initialization
map<int, texture_type> explosion_textures;
// In your function,
int step = ticker_.getElapsedTime().asMilliseconds();
sprite_.setTexture(*explosion_textures.lower_bound(step)->second);
怎么样:
bool check(std::size_t step)
{
auto tm = ticker_.getElapsedTime().asMilliseconds();
return (tm >= ANIMATION_STEP * step) && (tm < ANIMATION_STEP * (step + 1));
}
for(int i=0; i <n;++i)
{
if (check(i))
{
std::stringstream fname;
fname<<"animation/explosion_"<<
fname<<std::setfill(0)<<std::setw(2)<<i<<".png";
sprite_.setTexture(*game_->getResourceManager().getTexture(fname.str()));
}
}
unsigned frame = ticker_.getElapsedTime().asMilliseconds() / ANIMATION_STEP;
auto digit0 = std::to_string(frame % 10);
auto digit1 = std::to_string(frame / 10);
sprite_.setTexture(*game_->getResourceManager().getTexture("animation/explosion_"+digit1+digit0+".png"));
这里有一些类似 oop 的方法,它可以很容易地扩展到任意数量的animation_files。
这只是一个快速肮脏的原型,但方案应该很清楚。
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
class AnimationManager
{
public:
AnimationManager(float pStepsize) : mStepsize(pStepsize) {}
void registerSprite(std::string pFilename) //assuming that animation files are registered in the right order, alternatively use std::map as backend or something else
{
mFilenames.push_back(pFilename);
}
std::string getFilenameForAnimationStep(float ellapsed_time)
{
if (ellapsed_time < 0) //we dont want go pack in the past
ellapsed_time = 0;
unsigned int step = static_cast<unsigned int>(ellapsed_time/mStepsize); //trunc to int
step = std::min(step, mFilenames.size() - 1); //make shure we use the last registered animation, if we are to fahre in the future
return mFilenames[step];
}
private:
std::vector<std::string> mFilenames;
float mStepsize;
};
int main()
{
AnimationManager my_manager(0.2);
my_manager.registerSprite("step_0.jpq");
my_manager.registerSprite("step_1.jpq");
my_manager.registerSprite("step_2.jpq");
my_manager.registerSprite("step_3.jpq");
//....
//testing
std::cout << my_manager.getFilenameForAnimationStep(-0.5) << std::endl;
std::cout << my_manager.getFilenameForAnimationStep(0.1) << std::endl;
std::cout << my_manager.getFilenameForAnimationStep(0.2) <<std::endl;
std::cout << my_manager.getFilenameForAnimationStep(0.5) << std::endl;
std::cout << my_manager.getFilenameForAnimationStep(0.7) << std::endl;
std::cout << my_manager.getFilenameForAnimationStep(1.7) << std::endl;
system("Pause");
}
相关文章:
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 以在Qt中的IF语句中设置时间延迟
- Craps游戏问题,忽略if语句
- c++:定义if语句中的模板
- C++嵌套的 If 语句中,它无法按预期工作
- 如果条件不相关,我应该更喜欢两个 if 语句而不是 if-else 语句吗?
- 需要有关此 if 语句的帮助
- 转换器练习:跳过 if 语句和 if 语句
- 避免在 C++ 中的 if 语句中递增
- 如果仍然不满足要求,如何使 if 语句重复?
- do while 循环中的 if 语句以 yes 或 no 结尾
- 为什么在此C++代码中触发此 if 语句?
- 如何基于平台在制作文件中制作if语句?
- 在 if 语句中使用 GetKeyState 时,它会跳过条件
- C++ If 语句,从其他语句重复