Я решил головоломку 8, используя алгоритм BFS, и сохранил необходимые ходы в массиве, а затем преобразовал эти числа либо в 0, чтобы сказать, что пустое пространство нужно переместить вверх, либо в 1 вниз, либо в 2 влево, либо в 3 вправо. Я понятия не имею, как мне анимировать 8 квадратов, решающих головоломку, с помощью соответствующих движений из BFS. я знаю, как использовать таймер и как делать анимацию в целом, но не знаю, как последовательно анимировать правильный квадрат в нужное время. Им всегда нужно переместиться на 80 пикселей в любом заданном направлении. если кто-то может указать мне в правильном направлении, я был бы признателен.
OpenGL перенасыщена анимацией решения 8 головоломок
Ответы (2)
Я не понимаю, как вы можете написать что-то, чтобы решить эту головоломку, но при этом не знаю, как поддерживать простой счетчик для анимации значения.
Допустим, у вас есть частота F
, которая равна количеству движений в секунду, и время T
, которое представляет собой количество секунд с момента начала анимации.
Идея состоит в том, что ход M
начинается с T*F*M
и имеет продолжительность 1
(или меньше, если вам нужны паузы между ходами).
Теперь вам просто нужна функция интерполяции для смешивания значений. Линейная интерполяция (LERP) проще всего, но вам может понадобиться функция сплайна для ускорения/замедления в конечных точках. Как бы вы это ни делали, функция просто принимает начальную точку, конечную точку и относительную позицию t
, которая находится между 0 и 1.
double blend( double from, double to, double t )
{
// linear interp:
return from * (t-1.0) + to * t;
}
Итак, вы просто вычисляете t
, вычисляя дробную часть fmod(T*F*M, 1.0)
. Если у вас есть продолжительность менее 1
, вы не меняете 1.0
в этом вызове fmod
. Вы просто фиксируете его до своей продолжительности D
, а затем делите на D
.
Когда мне нужно сделать что-то подобное, я использую переменную, чтобы сохранить оставшееся время анимации движения. И чтобы знать, какую часть вы хотите переместить в сторону, я рекомендую вам использовать стек с такой структурой:
struct commands{
int piece;
int direction;
struct commands next;
};
Прежде всего, вы складываете все команды, необходимые для решения головоломки, затем, при анимации, вы сбрасываете переменную, сохраняя оставшееся время равным 80, и внутри функции времени:
void move_piece(int a){
//Move the piece 1 pixel to the side you want
switch(stack->direction){
//Move the piece to x+1
case 0:
piece[stack->piece].x++;
break;
//Move the piece to y+1
case 1:
piece[stack->piece].y++;
break;
case 2:...
...
}
time--;
if(time==0){
//The piece is in it's place
//Go to the next piece
time=80;
}
glutTimerFunc(20, move_piece, 0); //Change 20 to change the speed of the animation
}
Это просто пример того, как вы могли бы это сделать. Я не знаю, как вы сохраняете положение фигуры, в примере, я полагаю, это было в структуре.