Вызывать метод только один раз из класса

У меня есть класс формы, в котором есть метод (hitTest(int,int)), который постоянно проверяет, находится ли мышь внутри ее границ или нет. В другом методе я продолжаю проверять, оставалась ли мышь там более 1 секунды.
Если это так, активируйте функцию (посредством уведомления/события), которая запускает анимацию
Если это не так, то не запускать анимацию
Если он уже запустил анимацию и анимация выполняется, но мышь во время этого покидает область, активируйте функцию прерывания (по уведомлению/событию)

//OnLoad _initHover = false;

void update() //called continously in the application per frame
{
if(hitTest(getMouseX(), getMouseY())){
                if(!_initHover){
                    _initHover = true;
                    _hoverStartTime = getCurrentTime(); //start hover time
                    cout<<"Start hist test\n";
                }

                //If it has hovered over the video for 1.0 sec
                if((ofGetElapsedTimef() - _hoverStartTime) > 1.0){
                    cout<<"Hitting continously for 1 sec\n";
                    notificationCenter->postNotification(new AnimationStartNotification);
                }
            }
            else{
                    _initHover = false;
                    notificationCenter->postNotification(new AnimationInterruptNotification);
            }
}

Приведенный выше код работает нормально, но есть логическая проблема, с которой я столкнулся при попытке использовать. Существует несколько экземпляров вышеуказанного класса Shape, и, следовательно, каждый класс также имеет свой метод update(). Курсор мыши, который имеет animationStarthandler и animationStophandlers, является одним классом во всем приложении.

Проблема 1. Таким образом, даже когда одна из фигур просто уведомляет animationStarthandler о срабатывании, другие классы фигур, для которых проверка на попадание имеет значение False, устанавливают анимацию на interrupt, и анимация не запускается.
Проблема 2: когда проверка нажатия завершается успешно и курсор находится в области более 1 sec, проверка нажатия будет продолжать отправлять уведомление о запуске анимации (длительность анимации примерно 1,5 сек.) Как ограничить тест попадания, чтобы запустить анимацию только один раз и продолжать запускать одну и ту же анимацию снова и снова?

Если в основном методе моего приложения я напрямую пытаюсь запустить анимацию, вызвав метод playAnimation в классе указателя, я получаю требуемый результат. Но я хочу передать эту синхронизацию наведения и функциональность анимации самому ShapeClass. Какие-либо предложения?


person user1240679    schedule 21.01.2013    source источник
comment
Означает ли это, что у каждого класса Shape есть отдельный таймер? Обычной практикой при создании анимации является использование единого таймера, который отслеживает общее количество кадров в секунду и одновременно вызывает все перерисовки. Кроме того, я вообще не вижу смысла опрашивать метод Update. Вы должны просто обрабатывать MouseMove, MouseEnter и другие события мыши и вызывать Update оттуда, в то время как отдельный (один) таймер отображает все формы.   -  person Groo    schedule 21.01.2013


Ответы (1)


Я думаю, что вам следует подумать о добавлении нового логического значения, которое содержит информацию о запуске анимации (вызывается в примере кода _animationTriggered). Это не позволяет формам, которые не запустили анимацию, останавливать ее, а анимация, которая ее запустила, повторяла ее несколько раз.

if(hitTest(getMouseX(), getMouseY()))
{
    if(!_initHover)
    {
        _initHover = true;
        _hoverStartTime = getCurrentTime();
        cout<<"Start hist test\n";
    }

    if((ofGetElapsedTimef() - _hoverStartTime) > 1.0)
    {
        if (!_animationTriggered)
        {
            cout<<"Hitting continously for 1 sec\n";
            notificationCenter->postNotification(new AnimationStartNotification);
            _animationTriggered = true;
        }
    }
}
else
{
    if ( _animationTriggered )
    {
        _initHover = false;
        notificationCenter->postNotification(new AnimationInterruptNotification);
        _animationTriggered = false;
    }
}

Не забудьте инициализировать это новое логическое значение в том же месте, что и _initHover.

person Dr_Sam    schedule 21.01.2013
comment
Небольшой комментарий: при проверке запуска анимации я бы сначала проверял логическое значение и только после этого время. Это микрооптимизация, но она может иметь значение в часто вызываемой подпрограмме (и никак не влияет на читаемость/обслуживаемость). - person Bart van Ingen Schenau; 21.01.2013
comment
Прохладно! Это работает. Но есть определенный глюк. Анимация запускается один раз, и в следующий раз, когда я пытаюсь выполнить тест удара и получить анимацию на любой другой фигуре, анимация не запускается. Я проверю свой код, чтобы увидеть, есть ли что-то, что я делаю неправильно. - person user1240679; 21.01.2013
comment
Действительно странно. Вы можете попробовать запустить анимацию из класса указателя (из вашего вопроса) последовательно на разных фигурах и посмотреть, работает ли это. Это может помочь понять, где ошибка. - person Dr_Sam; 21.01.2013