Реализация анимации в OpenGL - PullRequest
0 голосов
/ 27 февраля 2012

Мне трудно придумать способ реализации анимации, подобной анимации движения, например, перейти на currentX + 3, где вы добавляете только deltaX, а все остальное интерполируется. Что у меня сейчас есть:

Рисунок / OpenGL поток, который отслеживает время рисования и обрабатывает частоту кадров:

public void onDrawFrame(GL10 gl) {

    endingTime = System.currentTimeMillis();
    int timeElapsed = (int) (endingTime - startingTime);

    if (timeElapsed < FRAMEDURATION_MILISEC) {
        try {
            Thread.sleep(FRAMEDURATION_MILISEC - timeElapsed);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    startingTime = System.currentTimeMillis();
    Game.renderGame(gl);
}

И логический поток, который анимирует, изменяя значения x и y GameObjects:

static long RATE = 30l; // times
static long duration = 1000l / RATE;

public void run() {
    lastUpdate = System.currentTimeMillis();

    long dur = duration; // copy

    while (Game.running) {

        long tElapsed = System.currentTimeMillis() - lastUpdate;

        if (tElapsed >= dur) {
            lastUpdate = System.currentTimeMillis();
            Game.updateGame(tElapsed);
        } else {
            try {
                GameLogicThread.sleep(dur - tElapsed);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

Я хотел реализовать класс Animation, в котором я мог бы, например, установить разницу в x для GameObject и применить этот объект Animation к GameObject, чтобы позиция обновлялась либо в чертеже, либо в логическом цикле.

Я не знаю, где я должен это делать или как сохранить какую-то чистую структуру во всем. Кто-нибудь может мне помочь?


РЕДАКТИРОВАТЬ:

Спасибо, теперь я создал класс GLAnimation, в который можно передавать dX, dY, dRotation, dScale и т. Д. Затем он вычисляет скорость, с которой объект должен быть изменен за милсекунду. Этот вызов объекта Анимация применяется к объекту GameObject, поэтому вызовы обновления и рендеринга могут пройти timeElapsed для перемещения объекта. Спасибо zmccord!

1 Ответ

2 голосов
/ 27 февраля 2012

Итак, по сути, вы сейчас говорите о ситуации, когда у вас есть физический поток («логический поток») и графический поток.Я думаю, что первый вопрос, который вы хотите задать себе, - стоит ли разделять их на отдельные темы;действительно ли ваша логика / физика достаточно вычислительно интенсивна, чтобы оказывать негативное влияние на частоту кадров?В простой игре вы сохраните ошибки и усилия, собрав их в одном цикле.Код должен определенно разделяться с разными файлами для каждой категории функциональности, но оба они могут выполняться в одном потоке (пошаговая логика один раз, отрисовка, повтор).

Одна из причин перейти к однопоточномуподход сейчас выглядит так, как будто ваша физика работает с максимально возможной скоростью, что на самом деле не очень хорошая идея;Вы будете использовать много энергии для небольшого повышения точности - возможно, снижение точности, в зависимости от того, как выглядит код вашей игры.Нет особого смысла в том, что ваша физическая частота кадров намного выше, чем ваша графическая частота, если ваша физика не очень сложна и не требует высокой точности.

Мне нравится идея вашего объекта анимации;то, как вы это сделаете, будет во многом зависеть от того, что могут содержать GameObjects или что ваш объект Animation, вероятно, захочет изменить.Я бы предложил написать свой GameObject для соответствия протоколу, который объект Animation может использовать для его изменения;если вы находитесь в C ++, самый простой способ достичь этого - это получить все объекты GameObject, наследуемые от корневого класса GameObject.Тогда ваши объекты Animation могут содержать информацию о том, как изменить GameObject.

Если мы находимся в C ++, я бы предложил:

корневые методы класса GameObject:

  • установить / получить позицию
  • установить / получить ориентацию
  • установить / получить все остальные игровые объекты состояния;размер?цвет?скорость?

root Анимационный класс является виртуальным с одним (виртуальным) методом:

  • применить анимацию к объекту

Затем создать подкласс Animationкорневой класс для создания отдельных анимаций, например, AnimationTranslate может добавить смещение к позиции и углу объекта, или AnimationScale может изменить размер, или AnimationGravity может ускорить объект к нижней части экрана.

Подобные проекты могутбыть сделано на любом объектно-ориентированном языке.Вы могли бы также осуществить это в прямой C с небольшим количеством работы ноги;если вы это сделаете, вы, вероятно, захотите пойти на хитрость, заключающуюся в том, чтобы поместить указатели на функции в ваши структуры.Если вы используете язык с типами сумм, вы можете использовать типы сумм вместо иерархии наследования для анимации;применима та же идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...