Animation 游戏中的平滑动画
如何创建“平滑”动画?我正在android上开发一个游戏。我知道制作平滑动画的默认方法不是最好的:Animation 游戏中的平滑动画,animation,frame-rate,smooth,Animation,Frame Rate,Smooth,如何创建“平滑”动画?我正在android上开发一个游戏。我知道制作平滑动画的默认方法不是最好的: perFrame() { time = highrestime(); frameTime = time - lastTime; lastTime = time; // now you could use frameTime as delta. this will lead to not real // smooth animations } 我读了一些关
perFrame() {
time = highrestime();
frameTime = time - lastTime;
lastTime = time;
// now you could use frameTime as delta. this will lead to not real
// smooth animations
}
我读了一些关于这个主题的文件。特别是如果你使用物理模拟。著名的文章似乎是这样的:
我创建了一个基本类,如下所示:
public class TimeSystem {
private long mCurrentTime;
private long mAccumulator;
private Simulation mSimulation;
private Renderer mRenderer;
private static float mSimulationDelta = 1000f / 60f;
public TimeSystem(Simulation simulation, Renderer renderer) {
mCurrentTime = System.currentTimeMillis();
mAccumulator = 0;
mSimulation = simulation;
mRenderer = renderer;
}
public void notifyNextFrame() {
long newTime;
long frameTime;
newTime = System.currentTimeMillis();
frameTime = newTime - mCurrentTime;
mCurrentTime = newTime;
if(frameTime > 250)
frameTime = 250;
mAccumulator += frameTime;
// while full steps of simulation steps can be simulated
while(mAccumulator >= mSimulationDelta) {
mSimulation.simulate(mSimulationDelta);
mAccumulator -= mSimulationDelta;
}
// render
mRenderer.render(frameTime / 1000.0f); // frameTime in seconds
}
public interface Simulation
{
void simulate(float delta);
}
public interface Renderer
{
void render(float delta);
}
}
我不是游戏开发方面的专家,但我希望我能理解本文的基础知识。根据需要调用simulate以获得固定的时间步长。问题是,复杂系统中的动画仍然不平滑。在我的程序中,FPS大约是60FPS
测试应用程序是用java for android编写的:
public float x = 40;
public float y = 40;
public float xmove = 0.1f;
public float ymove = 0.05f;
public void simulate(float delta) {
x += xmove * delta;
y += ymove * delta;
if(xmove > 0)
{
if(x > 480)
xmove = -xmove;
}
else if(xmove < 0)
{
if(x < 0)
xmove = -xmove;
}
if(ymove > 0)
{
if(y > 480)
ymove = -ymove;
}
else
{
if(y < 0)
ymove = -ymove;
}
RandomSleep(8);
}
Random rnd = new Random();
public void doDraw(Canvas canvas, float delta) {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(30);
canvas.drawColor(Color.BLUE);
canvas.drawCircle(x, y, 10, paint);
canvas.drawText("" + FPSConverter.getFPSFromSeconds(delta), 40, 40, paint);
RandomSleep(5);
}
public void RandomSleep(int maxMS)
{
try {
Thread.sleep((int)(rnd.nextDouble()*maxMS));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
公共浮点数x=40;
公共浮动y=40;
公共浮动xmove=0.1f;
公共浮动ymove=0.05f;
公共空间模拟(浮动三角形){
x+=xmove*delta;
y+=ymove*delta;
如果(xmove>0)
{
如果(x>480)
xmove=-xmove;
}
否则如果(xmove<0)
{
if(x<0)
xmove=-xmove;
}
如果(i移动>0)
{
如果(y>480)
ymove=-ymove;
}
其他的
{
if(y<0)
ymove=-ymove;
}
随机睡眠(8);
}
随机rnd=新随机();
公共虚空doDraw(画布、浮动三角形){
油漆=新油漆();
油漆。设置颜色(颜色。黑色);
绘制.设置样式(绘制.样式.填充);
油漆.尺寸(30);
画布。drawColor(颜色。蓝色);
画布。画圈(x,y,10,油漆);
canvas.drawText(“+fpscoverter.getFPSFromSeconds(delta),40,40,paint);
随机睡眠(5);
}
公共睡眠(int-maxMS)
{
试一试{
sleep((int)(rnd.nextDouble()*maxMS));
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
随机睡眠总和最大为13毫秒。这似乎是极端的,但对于给定的系统,您不应该感觉到差异。(我试图模拟我的游戏系统,以找出我的实际游戏引擎中的动画不平滑的原因;因此我使用了最坏的情况)
编辑:如果没有直接的答案,也许有人可以指出我如何找出“bug”可能在哪里。我能做些什么来正确分析这些事情呢?我认为这行有一个输入错误:frameTime=lastTime-time;应该是frameTime=time-lastTime;虽然我认为你真正的代码没有这个问题,否则事情就真的完了
我想到的一个问题是,您的模拟步骤需要多长时间?你确定这不是瓶颈吗?也许模拟跟不上渲染器 所以,终于!两周后,我找到了一个简单的解决办法!问题是我使用了System.currentTimeMillis();这个计时器的分辨率似乎不够高,无法制作平滑的动画。我重写了timer类,现在它工作得很好。对于任何有类似问题并希望使用我的代码的人:
public class TimeSystem
{
private long mOldTime;
private long mAccumulator;
private long mNewTime;
private long mFrameTime;
private Simulation mSimulation;
private Renderer mRenderer;
private static final long mSimulationDelta = 1000 * 1000 / 10;
private static final float mSimulationDeltaInMilliseconds = mSimulationDelta / 1000;
private static final long mMaxFrameTime = mSimulationDelta;
public TimeSystem(Simulation simulation, Renderer renderer)
{
mSimulation = simulation;
mRenderer = renderer;
mAccumulator = 0;
mOldTime = System.nanoTime();
}
public void notifyNextFrame()
{
mNewTime = System.nanoTime();
mFrameTime = mNewTime - mOldTime;
mOldTime = mNewTime;
// if FPS is to slow don't produce even more CPU usage
if (mFrameTime > mMaxFrameTime)
mFrameTime = mMaxFrameTime;
mAccumulator += mFrameTime;
// while full steps of simulation steps can be simulated
while (mAccumulator >= mSimulationDelta)
{
mSimulation.simulate(mSimulationDeltaInMilliseconds);
mAccumulator -= mSimulationDelta;
}
// render
mRenderer.render(mFrameTime / 1000f*1000f);
}
public interface Simulation
{
void simulate(float delta);
}
public interface Renderer
{
void render(float delta);
}
}
如果你喜欢,请随意投票:)谢谢。是的,你说得对,应该是frameTime=time-lastTime;我改正了错误。嗯,我不确定。如果我记得在traceview中正确的话,每个调用(模拟和渲染)显示大约600个。问题是什么。这是不可能的。它比对System.currentTimeMillis()的调用稍长一点;但也许我看错了桌子。您应该记住,目前在模拟中只有大约3个对象只执行了几个函数调用。