Использование glutTimerFunc с glutMouseFunc

Я пытаюсь сделать небольшую игру, и в моей игре у меня есть несколько квадратов, и когда пользователь нажимает на эти квадраты, они выделяются. Для достижения этого эффекта я использую glutMouseFunc с glutTimerFunc,

Когда пользователь нажимает на экран, я выбираю пиксель и определяю квадрат, который мне нужно выделить. Как только квадрат определен, я звоню glutTimerFunc, Функция зарегистрирована с glutTimerFunc увеличивайте значение каждого компонента цвета на 0,01, пока они не достигнут одного максимального значения, определенного мной, затем это значение возвращается к минимальному значению.

glutTimerFunc выполнить в течение 60 миллисекунд, и я получаю почти гладкий эффект блеска.

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

Как сделать так, чтобы этот эффект сияния прекратился, даже если я нажму на другой квадрат?

Вот фрагмент кода

void Memoria::shineEffect(GLint value) {

if(value == 1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] += COLOR_INCREASE;
if(colors[selectedSquare][i] >= MAX) {
colors[selectedSquare][i] = MAX;
value = -1;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
else {
if(value == -1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] -= COLOR_INCREASE;
if(colors[selectedSquare][i] <= MIN) {
value = 0;
colors[selectedSquare][i] = MIN;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
}
}

timeWrapper звонки shineEffect если значение, переданное в параметре, равно 1 или -1.

1

Решение

Вы хотите shineEffect функция, чтобы пройти хотя бы один цикл выделения, а затем остановиться, если выделенный элемент изменился. Это скорее проблема дизайна кода пользовательского интерфейса, чем проблема OpenGL или GLUT.

Механика, которую вам нужно реализовать, довольно проста:

  • установить раз и навсегда updateHighlights функция с glutTimerFunc: эта функция будет отвечать за обновление основных моментов всех нажатых элементов,
  • создать очередь элементов: каждый раз, когда элемент был нажат, добавьте его в очередь,

Задача, выполняемая updateHighLights Функция должна быть следующей:

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

Вот еще один, возможно, более гибкий подход к вашей проблеме.

Механизм цикла событий Glut очень прост: у вас есть только один крючок для помещения кода «работы вхолостую», поэтому, вероятно, более гибко установить функцию, которая вызывает список других функций. Этот список может быть затем изменен с помощью набора примитивов для установки или удаления определенных задач, выполняемых во время простоя. Это может быть намного более гибким, чем подход «одной функции» GLUT.

Например, вы можете изолировать ваш текущий код выделения в одной функции с помощью структуры, содержащей элемент для выделения, и заставить функцию удалить себя из списка, когда ее элемент выполняется в цикле выделения и больше не активен.

Поскольку вы используете C ++, должно быть легко объединить все эти функции в классы:

  • один класс для списка незанятых задач
  • один базовый класс для неработающих задач
  • один производный класс незанятых задач с целью выделения квадрата (с полями для квадрата и для активного статуса)
  • один класс для отслеживания активного квадрата, чтобы его можно было легко деактивировать и заменить новым активным. Этот будет доступен для glutMouseFunc функция.
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]