Я пишу приложение wpf music pad, где у меня есть 16 кнопок (Вот пример реальной музыкальной панели https://www.youtube.com/watch?v=3vC5TsSyNjU).
Каждая кнопка воспроизводит другой образец музыки. Это хорошо работает. Но когда пользователь находится в режиме ожидания, я хочу создать простую анимацию, показанную на изображении ниже.
Анимация начинается с кнопки 1 (оживляет цвет фона до белого, а затем возвращается к исходному цвету).
Вот шаги анимации:
Я создал функцию AnimatePad, которая принимает кнопку и запускает цветную анимацию фона после указанного времени. Эта функция работает должным образом.
Чтобы реализовать описанные выше шаги, я вызываю функцию AnimatePad для каждой кнопки. Вот код, который я сейчас использую, и это то, что я хочу улучшить. Я в настоящее время жестко закодировал эти шаги. Если мои кнопки подсчитывают изменения, я должен вернуться и изменить этот код, что является плохой идеей.
double beginMs = 0;
var spd = 300;
var interval = 40;
var toColor = Color.FromRgb(255, 255, 255);
AnimatePad(ref beginMs, spd, pads[0], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[1], toColor);
AnimatePad(ref beginMs, spd, pads[4], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[2], toColor);
AnimatePad(ref beginMs, spd, pads[5], toColor);
AnimatePad(ref beginMs, spd, pads[8], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[3], toColor);
AnimatePad(ref beginMs, spd, pads[6], toColor);
AnimatePad(ref beginMs, spd, pads[9], toColor);
AnimatePad(ref beginMs, spd, pads[12], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[7], toColor);
AnimatePad(ref beginMs, spd, pads[10], toColor);
AnimatePad(ref beginMs, spd, pads[13], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[11], toColor);
AnimatePad(ref beginMs, spd, pads[14], toColor);
beginMs += interval;
AnimatePad(ref beginMs, spd, pads[15], toColor);
Поэтому я хочу более общий способ выбора кнопок для анимации.
Я уверен, что должен быть какой-то алгоритм. Спасибо!
Попробуй это:
var n = (int) Math.Sqrt(pads.Length);
int i = 0, j = 0, k = 0;
for(i = 0; i < n; i++){
k = i;
AnimatePad(ref beginMs, spd, pads[k], toColor);
for(j = 0; j < i; j++){
k += n-1;
AnimatePad(ref beginMs, spd, pads[k], toColor);
}
beginMs += interval;
}
for(i = n-2; i >= 0; i--){
k = (n-i)*n - 1;
AnimatePad(ref beginMs, spd, pads[k], toColor);
for(j = 0; j < i; j++){
k += n-1;
AnimatePad(ref beginMs, spd, pads[k], toColor);
}
beginMs += interval;
}
pads.Length
должна быть квадратом некоторого числа, например 4
, 9
, 16
, 25
, ...
Представьте 2d массив с индексами и суммой их индексов. Если вы добавите индексы каждой кнопки, вы получите сумму. Например, сумма 0,0 штук равна 0. 2,1 индексная сумма равна 3 и так далее.
На шаге 1 выберите кнопки с индексной суммой 0, на шаге 2 выберите кнопки с индексом 1 и т.д.
Я не знаю, что такое массив колодок. Если это всего лишь массив кнопок, то я предлагаю создать сложный тип. Например:
public class PadItem
{
public Button Pad {get; set; }
public int IndexSum {get; set; }
}
Вот пример:
for (int i = 0; i < 7; i++)
{
var stepPads = pads.Where(p => p.IndexSum == i);
beginMs += interval;
foreach (var pad in stepPads)
{
AnimatePad(ref beginMs, spd, pad, toColor);
}
}
pads
должны быть в виде какого-то квадратного массива, было бы проще. В противном случае мы должны определить количество столбцов только из общего количества кнопок (что на самом деле имеет много случаев, таких как 4x4, 2x8, 8x2), если число строк = число столбцов, мы можем использоватьMath.Sqrt
но используя квадрат массив лучше.