Подходы для анимации свойства C # с течением времени? - PullRequest
1 голос
/ 03 января 2011

В настоящее время я пытаюсь анимировать несколько открытых свойств определенных объектов.Обычно они имеют тип float или векторы с плавающей точкой (тип известен во время компиляции).Я хочу иметь возможность:

  1. назначить им статическое значение (MyObject.Duration = 10f;) или
  2. назначить им случайное значение, указав минимальное и максимальное значенияи, необязательно, также вес (MyObject.Duration = new RandomFloat (5f, 20f, 2f);) или
  3. «связывают» это свойство со свойством другого объекта (представьте, что дочерний объект связывает некоторые из его свойствего родительскому объекту, такому как его цвет или размер или sth.) или
  4. присваивает им вид анимации ключевого кадра, определяя переменное число ключевых кадров с временным кодом и значение свойства в этот конкретный момент временикак информация о том, как интерполировать между этими кадрами

Ключевые кадры должны иметь возможность принимать случайные значения для каждого кадра, как для времени, так и для значения свойства.

Что будетпрактический подход для такого рода системы?В настоящее время я думаю о полиморфизме: реализовать базовый класс или интерфейс с открытым методом Value-property и / или GetValue (float time), а затем создать различные подклассы, такие как StaticValue, RandomValue, BindingValue и AnimatedValue, реализующие этот базовый класс или интерфейс,Хотя это не выглядит очень элегантно, и инициализация даже простых объектов становится немного утомительной.

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

Есть предложения по этому поводу?Будучи новичком, я (надеюсь) упускаю какое-то гораздо более изящное и / или практичное решение, чем уже играю: (

Редактировать: Вероятно, следовало упомянуть об этом раньше,но WPF не вариант - он доступен не на всех целевых платформах, поэтому я не могу положиться на него. Я знаю о его мощных возможностях привязки данных и анимации, но мне нужно свернуть свои собственные (или найти какой-то другой легкийальтернативное удовлетворение моих потребностей).

1 Ответ

1 голос
/ 04 января 2011

Я думаю, что полиморфное решение, которое вы описываете, является самым элегантным OO-способом сделать это.Что вы считаете неуместным в этом?

Что касается использования фактических типов данных и типов модификаторов, я предлагаю вам взглянуть на использование неявных перегрузок операторов.

Вы можете определить свой класс со всеминужное вам поведение, но обеспечьте преобразование в / из типа «значение», чтобы вы могли получать / присваивать значения, как если бы это был тип.Пример поможет:

public class MyFloat
{
    float innerValue;

    // private constructor; instantiate using a float directly
    private MyFloat(float innerValue) { this.innerValue = innerValue; }

    public string Description { get { return "some metadata"; } }

    public int NumberOfFrames { get; set; }

    // conversion from MyFloat to float
    public static implicit operator float(MyFloat mine)
    {
        return mine.innerValue; // you can access private members here
    }

    // conversion from float to MyFloat
    public static implicit operator MyFloat(float val)
    {
        return new MyFloat(val); // use the private constructor
    }
}

В этом случае вы можете делать такие вещи:

MyFloat mine = 9f; 
mine.NumberOfFrames = 15;

или…

if(mine > 0f)…

Что касается скукиЯ полагаю, что такой сценарий является идеальным кандидатом для внутреннего DSL / беглого интерфейса.

Вы можете придумать что-нибудь выразительное и лаконичное, например:

var animatedObject = Sprite.with(RandomMotion.animatated_between(0f).and(10f))
    .lasts(4).seconds;
var otherObject = Sprite.with<NoMotion>().starts_at(100, 0);
var yetAnother = Sprite.with(SteadyMotion.at(7f))
    .starts_at(100, 200)
    .weighing(.5f)
    .lasts(15).frames;
...