C++/SDL/OpenGL 中的平滑动画出现问题
我一直在使用 C++/SDL/OpenGL 制作 2D 平台游戏的动画,我和我的团队达到了需要确定玩家的每个动画(行走、跑步等)都需要不同的帧速率的地步。对于我们的概念,但我使用游戏编程一体机作为平滑动画的示例,并在书中推荐使用限制运动和帧变化的变量。
为了澄清我的意思,我在 Sprite 类中包含以下参数:
std::vector< Vector2f > delayMovementSprite;
std::vector< int > frameDelayPerAnimation;
GLfloat countX, countY;
其中向量delayMovementSprite 包含每个帧中不同动画和 countX 增量的所有值,直到它等于或大于向量delayMovementSprite 中对应的值。
像这样的事情:
void Sprite::movePosXWithSpeed()
{
playerMoveInX = false || playerMoveInX;
countX++;
if ( countX > delayMovementSprite.at(getCurrentState()).x )
{
countX = 0;
if ( handlerAnimation->getAnimationDirection() == SpriteData::RIGHT )
{
if ( position.x + getSpeedX() + width < 6368.f )
{
position.x += getSpeedX();
playerMoveInX = true;
return;
}
}
else if ( position.x + getSpeedX() + width > 0 )
{
position.x += getSpeedX();
playerMoveInX = true;
return;
}
playerMoveInX = false;
}
}
对于帧,我有一个类 Animation 来处理以下信息:
Uint32 frameRate, oldTime;
int frameDelay;
int frameCount;
在动画函数中,我执行以下操作,就像 Sprite 中的 MoveX 一样:
int Animation::animate()
{
if( oldTime + frameRate > SDL_GetTicks() )
{
return -1;
}
oldTime += frameRate;
frameCount++;
if ( frameCount > frameDelay )
{
animationAlreadyEnd = false;
frameCount = 0;
currentFrame += incrementFrame;
if( currentFrame > maxFrames)
{
animationAlreadyEnd = true;
currentFrame = returnFrame;
}
}
return currentFrame;
}
我完成了所有这些工作,并且一切都执行得很好,但是在游戏的某些点动画看起来不太流畅,而在其他点则很流畅。
我留下了“游戏玩法”的视频,以便每个人都能明白我的意思。
http://www.youtube.com/watch?v=uoxKEYzwkcQ
我目前在游戏的执行速度一般为 60 FPS。
如果有人需要更多信息,请随时询问。
I been working in the animation of a 2D platformer game in C++/SDL/OpenGL, and my team and I reach the point where we need to establish that every animation of the player (Walking, Running, etc..) needs a different framerate for our concept, but I use as a guideline the Game Programming All In One as a example for the smooth animation, and in the book recommend have variables that limits the movement and the changes of frames.
To clarify what I mean I have in my Sprite class these parameters:
std::vector< Vector2f > delayMovementSprite;
std::vector< int > frameDelayPerAnimation;
GLfloat countX, countY;
Where the vector delayMovementSprite contains all the values for the differents animations and countX increment in every frame until it's equal or greater than the value that correspond in the vector delayMovementSprite.
Something like this:
void Sprite::movePosXWithSpeed()
{
playerMoveInX = false || playerMoveInX;
countX++;
if ( countX > delayMovementSprite.at(getCurrentState()).x )
{
countX = 0;
if ( handlerAnimation->getAnimationDirection() == SpriteData::RIGHT )
{
if ( position.x + getSpeedX() + width < 6368.f )
{
position.x += getSpeedX();
playerMoveInX = true;
return;
}
}
else if ( position.x + getSpeedX() + width > 0 )
{
position.x += getSpeedX();
playerMoveInX = true;
return;
}
playerMoveInX = false;
}
}
And for the frames I have a class Animation which handles the following information:
Uint32 frameRate, oldTime;
int frameDelay;
int frameCount;
And in the function that animates I do the following, much like the MoveX in Sprite:
int Animation::animate()
{
if( oldTime + frameRate > SDL_GetTicks() )
{
return -1;
}
oldTime += frameRate;
frameCount++;
if ( frameCount > frameDelay )
{
animationAlreadyEnd = false;
frameCount = 0;
currentFrame += incrementFrame;
if( currentFrame > maxFrames)
{
animationAlreadyEnd = true;
currentFrame = returnFrame;
}
}
return currentFrame;
}
I got working all that and everything executes apparently fine, but in some points of the game the animation doesn't look really smooth when in other points it is.
I leave the video of the "gameplay" so everyone could see what I mean.
http://www.youtube.com/watch?v=uoxKEYzwkcQ
I currently using during the execution of the game a general Timer in 60 FPS.
If anyone needs more information, don't hesitate in ask.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
乍一看
Animation::animate
看起来不太正确。让我解释一下:假设您有固定的显示帧速率(对于基于精灵的游戏,这将保持不变),您需要从帧计数器到精灵帧的线性映射。如果你把它画出来,那就是一条线。在本例中,离散采样网格上的一个。每当人们想到“离散线采样”时,就应该想到“Bresenham”,事实上,如果您想保留增量方案,您可以而且应该使用 Bresenham 算法来推进动画。另一种可能性是,简单地评估仿射方程f_anim = framerate_anim/framerate_game * (framecounter_game - startframe_animation)
。At first look
Animation::animate
doesn't look right. Let me explain: Assuming you have a fixed display frame rate (for a sprite based game this will hold), you want a linear mapping from frame counter to sprite frame. If you graph this, this was a line. And in this case one over a discrete sampling grid. Whenever one thinks "discrere line sampling" one should think "Bresenham", and in fact you can and should use Bresenham's algorithm for advancing your animation, if you want to keep a incremental scheme. The other possibility was, simply evaluating the affine equationf_anim = framerate_anim/framerate_game * (framecounter_game - startframe_animation)
.