В Opengl есть эта функция dance()
что я хочу переместить объект и обновить экран, а затем снова перемещаться, чтобы он выглядел так, как будто объект постоянно перемещается. Сейчас все, что он делает, - это перемещение, а затем обновляет экран.
Это мое смещение ay_Main:
void window::main () {
static int argc = 0;
glutInit (&argc, nullptr);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize (window::width, window::height);
glutInitWindowPosition (128, 128);
glutCreateWindow (sys_info::execname().c_str());
glutCloseFunc (window::close);
glutEntryFunc (window::entry);
glutDisplayFunc (window::display);
glutReshapeFunc (window::reshape);
glutKeyboardFunc (window::keyboard);
glutSpecialFunc (window::special);
glutMotionFunc (window::motion);
glutPassiveMotionFunc (window::passivemotion);
glutMouseFunc (window::mousefn);
glutMainLoop();
}
Это мой код отображения:
void window::display() {
glClear (GL_COLOR_BUFFER_BIT);
for (auto& object: window::objects) object.draw();
objects.at(selected_obj).draw_border();
mus.draw();
glutSwapBuffers();
}
Это мой код перемещения:
void move (GLfloat delta_x, GLfloat delta_y) {
//center pertains to the object that is drawn
center.xpos += delta_x;
center.ypos += delta_y;
}
И вот мой код танца:
static void dance(){
int x =0; int y=0;
for(;;){
int r1 = rand() % 100;
int r2 = rand() %100;
vertex v = objects.at(selected_obj).get_vertex();
if(v.xpos >= width) break;
if(v.ypos >= height) break;
x=move_pixels+r1; y=move_pixels+r2;
objects.at(selected_obj).move(x,y);
glutPostRedisplay();
}
}
В моем dance()
я хочу, чтобы он перемещался, а затем обновлялся, а затем снова перемещался (например, скорость). Однако он просто перемещается сразу и обновляется, когда это делается.
glutPostDisplay
просто устанавливает флаг, что на следующей итерации цикла события должна вызываться функция отображения.
Здесь самое важное правило программирования, управляемое событиями: никогда не помещайте временные действия, такие как анимация, в цикл воспроизведения, который циклически проходит всю анимацию перед возвратом в систему событий. В вашем случае вы должны разбить свою dance
функцию на незанятую функцию, которая вызывается каждый раз, когда все ожидающие события (включая перерисовку) обрабатываются. Затем вы можете перейти к следующему шагу, обновите анимацию и выполните перерисовку.
move()
вызывается всякий раз, когда нажимается стрелка на клавиатуре. Так как бы я вызывалmove()
несколько раз, не используя цикл, чтобы он имитировал последовательное движение?dance
функции (без реальной петли) идеально подходит для бездействия. Конечно, вам придется поместить состояние в глобальные переменные. В обработчиках событий устанавливаются флаги, управляющие операцией ожидания. Другой подход заключается в том, чтобы отказаться от GLUT и вместо этого использовать среду, в которой у вас есть прямой контроль над циклом событий.