#android #animation
#Android #Анимация
Вопрос:
Я пишу небольшую игру как часть задания по программированию. Мои спрайты / изображения перемещаются так, как я хочу, за исключением того, что они очень отрывистые. Вот как я загружаю изображение:
//missile and paint are private members of the animation thread
missile = Bitmap.createBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.missile));
paint = new Paint();
paint.setAntiAlias(true);
startTime = new Date().getTime();
run
Метод моего потока такой:
@Override
public void run() {
while(running) {
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
updatePhysics();
doDraw(canvas);
}
} finally {
if(canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
updatePhysics
просто выполняет вычисления и сохраняет значение внутри закрытого элемента потока, вызываемого projectilePosition
:
function updatePhysics() {
projectilePosition = interceptionCalculationService.positionAtTime((startTime - new Date().getTime()) / 1000);
}
Затем в моем doDraw
методе я делаю:
private void doDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
...
//I update the position of the missile
canvas.drawBitmap(missile, (int) projectilePosition.getDistance() * 2, (int) (getHeight() - (95 projectilePosition.getHeight())), paint);
canvas.restore();
}
Проблема в том, что анимация очень отрывистая. Ракета следует по правильному пути, но она совсем не гладкая. Я предполагаю, что это потому, что я на самом деле не контролирую интервал при run
вызове метода потока. Как я могу сделать мою анимацию более плавной? Я смотрел TranslateAnimation
, но не могу понять, как это использовать.
Я впервые пишу игру и делаю графику / анимацию, поэтому я не очень хорошо осведомлен о лучших практиках или даже инструментах. Я зашел так далеко, просмотрев множество руководств.
Комментарии:
1. Ваше представление получено из представления или SurfaceView?
2. Это производное от
SurfaceView
.3. Тогда я бы предположил, что вы просто пытаетесь сделать слишком много за кадр… возможно, стоит повысить приоритет фонового потока…
Ответ №1:
Да, метод doDraw вызывается так быстро, как может обрабатывать процессор и позволяет операционная система, что означает, что на него влияют другие процессы, а также означает, что он использует массу процессорного времени. В качестве довольно простого, но не рекомендуемого решения добавьте поток.Спящий режим (50) в вашем цикле while. Посмотрите, как использовать таймеры для анимации.
Комментарии:
1. Я думаю, проблема заключалась в том, что я использовал системное время для вычисления положения моего снаряда. Я добавлю здесь ответ, который описывает, как я это сделал.
Ответ №2:
Мое решение состояло в том, чтобы перестать полагаться на системное время и использовать вызываемую переменную (которая является закрытым членом потока) currentTime
, которая увеличивается в любом doDraw
или updatePhysics
. Так updatePhysics
становится:
function updatePhysics() {
projectilePosition = interceptionCalculationService.positionAtTime(currentTime);
currentTime ;
}
currentTime
инициализируется значением 0 в конструкторе потока. Это сделало мою анимацию плавной.