Хороший способ сделать анимацию с Cocos2D? - PullRequest
3 голосов
/ 21 марта 2010

Я делаю небольшую игру для iphone и получу некоторые подсказки.Давайте представим:

Два фоновых спрайта, движущихся довольно быстро справа налево и движущихся вверх и вниз с помощью акселерометра.

Я думаю, что я не могу использовать анимацию здесь, потому что движение фонапересчитывается в каждом кадре.Поэтому я использую расписание с интервалом 0,025 с и перевожу свои спрайты на каждые часы с помощью:

sprite.position = ccp(x, y);

Так что вот моя проблема: результат медленный, только с этими двумя спрайтами.

Я попытался объявить спрайты в заголовке и получить их с помощью CCNodes и Tag.Это то же самое.

Так что, если кто-нибудь подскажет мне, как лучше всего это сделать, это было бы так здорово.Интересно, не может ли быть проблема в том, что спрайты движутся очень быстро, но я не уверен.

В любом случае, спасибо за ваше время.

J.

Ответы [ 2 ]

3 голосов
/ 21 марта 2010

0,025 равняется 40 кадрам в секунду, что может быть немного круто в зависимости от остальной части вашего игрового цикла. Хорошо подумать о связи между частотой кадров и воспринимаемой скоростью. Когда вы увеличиваете частоту кадров, вы делаете движение более плавным, но только до тех пор, пока вы знаете, как рассчитать движение. Если вы перемещаете объекты на фиксированное расстояние с каждым тактом времени, они будут заикаться, потому что таймер не точен. (Подумайте об этом: 40 кадров в секунду означает 25 мс на кадр. Когда таймер сбрасывается на пять миллисекунд - не так ли? выключено на 10–20 мс.)

Это означает, что вы должны рассчитать дельту в реальном времени из последнего кадра и переместить объекты в соответствии с ней. Немного так:

const int kDesiredModelFramerate = 50; // fps
const double kDesiredFrameTime = 1.0/kDesiredModelFramerate;

double now = CFAbsoluteTimeGetCurrent();
double delta = now - lastFrameTime;
double correction = delta/kDesiredFrameTime;
[object setX:object.x + step*correction];

Это выглядит сложно, но не так. Когда от последнего кадра прошло 40 мс, вы знаете, что вы опоздали на один кадр, поскольку для сохранения желаемой частоты кадров в 50 к / с вы бы хотели, чтобы каждый кадр был менее 20 мс. Поэтому correction будет 0,04 / 0,02 = 2, и обычный шаг движения умножится на 2, чтобы компенсировать отставание. Теперь вы можете изменять частоту кадров по своему усмотрению - воспринимаемая скорость движения останется неизменной, изменится только плавность движения.

<voice class="Simon Peyton Jones"> Имеет ли это смысл? </voice>

Существует отличная статья об игровых циклах , где вы можете прочитать об этом более подробно. Это необходимо прочитать программисту игры. Точный способ реализовать все это в Cocos2D может варьироваться, но суть остается неизменной. Решение этой проблемы должно помочь вам быстро и плавно двигаться.

1 голос
/ 12 июня 2010

Если вы используете Cocos2D и вам нужно найти истекшее время с начала «игры», лучше использовать time_elapsed, как показано ниже. Многие другие методы, которые я попробовал, возвращают очень высокую переменную DOUBLE, что вызывает больше проблем с точностью преобразования в двойное число.

Внести изменения в функцию «тик» в сценах Cocos2D CCLayer

-(void) tick: (ccTime) dt
{
  static float time_elapsed = 0.0;
  time_elapsed += dt;

  ...

  float velocity = 5.0f * cosf(time_elapsed * 2 * M_PI) ;
  jPrism->SetMotorSpeed( velocity );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...