Можно ли поделиться анимацией обратного вызова в Shady? - PullRequest
2 голосов
/ 11 февраля 2020

Я пытаюсь использовать Shady для представления последовательности кадров изображения. В прошлом я делал это, присваивая атрибуту activulus.page обратный вызов анимации. В обратном вызове, который вызывается Shady один раз для каждого кадра монитора, я сначала проверяю глобальную переменную, которая отслеживает, какой кадр стимула должен отображаться. Если оно положительное, я устанавливаю видимость стимула на True и возвращаю номер кадра; в противном случае я устанавливаю значение False и возвращаю 0. Работает как шарм.

Теперь мне нужно расширить это, потому что мне нужно выбрать одну из нескольких последовательностей для отображения. Поскольку загрузка последовательности может занять некоторое время, я загружаю их все в начале своей программы и связываю каждую с объектом Stimulus. Теперь вот мой вопрос. Нужно ли создавать разные анимационные функции обратного вызова для каждой из последовательностей (число которых является переменным и может быть большим). Или есть более элегантный способ вызывать один анимационный обратный вызов (или что-то подобное), и там я определяю, какой кадр какой последовательности показывать (опять же, на основе текущего значения глобальных переменных)?

1 Ответ

1 голос
/ 11 февраля 2020

Сначала я хочу убедиться в различии терминологии между «обратными вызовами анимации» и «значениями свойства dynamici c». Документы Shady и этот ответ не относятся к тому, что вы используете как «анимационный обратный вызов». Но лучшим решением вашей проблемы, я думаю, может быть использование фактических обратных вызовов анимации.

  • значений свойств Dynamics , или "dynamic" ": некоторым свойствам экземпляров World и Stimulus могут быть назначены вызываемые элементы. Если это так, они вызываются на каждом кадре. Ваш stimulus.page является примером этого (хотя page он не является полноценным «управляемым свойством», т. Е. Обладающим возможностью совместного использования памяти с соответствующим свойством другого экземпляра, он поддерживает назначение «dynamici c») " таким образом). Свойства Dynami c хороши, если вы хотите изменить только несколько аспектов нескольких стимулов за раз, и / или вы хотите, чтобы изменения в одном свойстве были полностью независимы от изменений в другом. Динамически назначаемая функция должна принимать ровно один аргумент (время t в секундах), но (согласно вашему комментарию), который позволяет вам использовать уже связанный метод s (или любой другой) экземпляр), который имеет прототип blah(self, t), поскольку self будет запечен при доступе к нему. Функция также должна возвращать значение - значение * stati c, которое должно быть назначено свойству в этом кадре.

  • Обратные вызовы анимации : каждый Stimulus Экземпляр s (и дополнительно экземпляр World) имеет один «обратный вызов анимации», который занимает слот атрибута s.Animate и который можно изменить с помощью метода s.SetAnimationCallback или его эквивалентного декоратора функции @s.AnimationCallback. В каждом кадре каждый экземпляр World или Stimulus проверяет, имеет ли он свойство .Animate, и, если да, вызывает его. Если вы хотите, чтобы изменения в нескольких свойствах (скажем, s.visible и s.page) были скоординированы друг с другом, то для этого лучше всего использовать обратный вызов анимации, прикрепленный к s. В отличие от динамики, обратный вызов анимации может быть (не связанным) методом , который получает ссылку на s как self, поэтому атрибуты self могут использоваться как «глобальные» (но стимул-экземпляр-специфика c) блокнот. (На самом деле, с помощью обратных вызовов анимации у вас есть выбор: определить их с помощью метода-подобного прототипа blah(self, t) или прототипа с одним аргументом blah(t), похожего на динамический c.) Если динамика работает, то обратные вызовы анимации процедурный: любой возвращаемый аргумент обратного вызова анимации игнорируется.

В любом случае верно (как вы и опасались), что все стимулы, к которым вы прикрепляете callback будет вызывать его, и все стимулы будут вызывать свою динамику в каждом кадре, не проверяя, используются ли те же вызываемые элементы в других случаях. Если вы хотите убедиться, что код не вызывается без необходимости, ваши варианты включают:

  1. Если только один Stimulus должен быть видимым одновременно: каждый Stimulus должен следовать за ним собственный logi c, в своем собственном обратном вызове анимации и / или в его свойствах dynamici c (в зависимости от того, что имеет для вас наибольшее значение). Но когда он должен быть за кадром, не устанавливайте s.visible = False: вместо этого на самом деле есть Stimulus экземпляр s.Leave() сцена и s.Enter() снова, когда это необходимо. Когда вы находитесь на сцене, даже если вы невидимы, ваш обратный вызов анимации и ваша динамика вызывается в каждом кадре. Когда ты за сценой, их не зовут. Это продемонстрировано ближе к концу python -m Shady demo sharing

  2. В качестве альтернативы, вы можете просто выполнить большинство или все ваши анимационные логи c в одном месте. Лучшее место для этого, вероятно, - анимационный обратный вызов World, который определенно вызывается только один раз за кадр, потому что есть только один World. Ссылки на отдельные стимулы всегда можно получить в виде глобальных переменных или по имени из контейнера self.stimuli:

    import Shady
    cmdline = Shady.WorldConstructorCommandLine()
    cmdline.Help().Finalize()
    
    w = Shady.World( **cmdline.opts )   
    w.Stimulus( name='bill', x=-100, size=100, color=[1,0,0] )
    w.Stimulus( name='ben',  x=+100, size=100, color=[0,0,1] )
    
    @w.AnimationCallback
    def Animate( self, t ):
        # top-down control of multiple stimuli:
    
        if self.framesCompleted % 2:
            # self.stimuli is a dict, with all the expected dict capabilities...
            self.stimuli['bill'].visible = True 
            self.stimuli['ben'].visible = False
        else:
            # ...but it supports lazier syntax too:
            self.stimuli.bill.visible = False 
            self.stimuli.ben.visible = True
    
    Shady.AutoFinish( w )
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...