
Язык программирования:
C#
Среда программирования:
Microsoft Visual Studio 2013
using System; using System.Drawing; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public int len; //длина стороны квадрата public int distance;// расстояние между квадратами public int quantity;//количество квадратов public int counter = 0;//счётчик сдвига public int dxy = 1;//величина сдвига public int color = 0, color2 = 0;//переменные, которые меняют цвет движущейся грани public int dcolor;//величина изменения цвета за смещение public int next_order = -1, cur_order = -1;//переменные хранят номер слоя движущихся квадратов public int[,] order;//массив очерёдности //массивы точек, определяющих соответствующие грани квадратов public PointF[,] left; public PointF[,] right; public PointF[,] top; public PointF[,] bottom; Color coltemp, coltemp2;//цвета движущихся квадратов Pen helppen, mainpen, temppen, temppen2;//окрашивание квадратов: helppen - не сдвинутые, temppen,temppen2 - двигающиеся, mainpen - сдвинутые Bitmap btmp; public Graphics g; public Form1() { InitializeComponent(); } private void Loading(object sender, EventArgs e)//функция инициализации основных значений { len = 22; distance = len * 7 / 2; if (distance % 2 == 1) distance++; dcolor = 3; //предварительно определяем начальный и конечный цвет (после полного прохода они обновляются, установлены экспериментально) coltemp2 = Color.FromArgb(255, 80, 255, 50); helppen = new Pen(Color.FromArgb(255, 80 + 2 * 57, 198, 50), 3); mainpen = new Pen(coltemp2, 3); //определяем количество квадратов относительно размеров экрана quantity = pbox.Width / (len + distance / 2); // четное количество для корректного отображения if (quantity % 2 == 1) quantity++; //инициализируем и заполняем массивы координат left = new PointF[quantity, 2 * quantity]; right = new PointF[quantity, 2 * quantity]; top = new PointF[quantity, 2 * quantity]; bottom = new PointF[quantity, 2 * quantity]; int cm = -(quantity / 2 - 1) * (distance) - len / 2;// постоянный сдвиг (так как координаты смещены к центру picture Box) int sh = 0; // шахматный сдвиг for (int i = 0; i < quantity; i++) for (int j = 0; j < 2 * quantity; j++) { if (j % 2 == 1) sh += distance / 2; else sh -= distance / 2; left[i, j].X = top[i, j].X = sh + cm + i * (distance); left[i, j].Y = top[i, j].Y = cm + j * (distance / 2) - distance / 2; right[i, j].X = bottom[i, j].X = sh + cm + i * (distance) + len; right[i, j].Y = bottom[i, j].Y = cm + j * (distance / 2) + len - distance / 2; top[i, j].X--; bottom[i, j].X++; } Define_order();// определяем порядок движения квадратов timer1.Enabled = true;// включаем таймер } private void Define_order() { order = new int[quantity, 2 * quantity];//инициализируем массив int middle = quantity - 1;// находим "среднюю" строку for (int i = 0; i < quantity; i++) order[i, middle] = (int)Math.Abs(i - middle / 2);//заполняем эту строку от центра (0) к краям //заполняем остальные элементы массива по четвертям for (int i = 0; i < quantity; i++) { int temp = order[i, middle];// значение в соответствующей "средней" строке if (i < quantity / 2)// левая половина { for (int j = middle + 1; j < 2 * quantity - 1; j = j + 2)//нижняя половина { temp++; order[i, j] = order[i, j + 1] = temp; } temp = order[i, middle]; for (int j = middle - 1; j >= 0; j -= 2)//верхняя { temp++; order[i, j] = temp; if (j > 0) order[i, j - 1] = temp; } } else //правая половина { for (int j = middle; j < 2 * quantity - 1; j = j + 2)//нижняя { order[i, j] = order[i, j + 1] = temp; temp++; } temp = order[i, middle]; for (int j = middle; j > 0; j -= 2)//верхняя { order[i, j] = order[i, j - 1] = temp; temp++; } } } } private void Draw_square(int i, int j, Pen pen, int dif = 0)//рисуем отедльный квадрат, если dif=1, то происходит сдвиг { if (dif == 1) { g.DrawLine(pen, left[i, j].X, left[i, j].Y, left[i, j].X, left[i, j].Y + len+1); g.DrawLine(pen, right[i, j].X, right[i, j].Y, right[i, j].X, right[i, j].Y - len); g.DrawLine(pen, top[i, j].X, top[i, j].Y, top[i, j].X + len, top[i, j].Y); g.DrawLine(pen, bottom[i, j].X, bottom[i, j].Y, bottom[i, j].X - len, bottom[i, j].Y); //запоминаем новые координаты точек left[i, j].X -= dxy; right[i, j].X += dxy; top[i, j].Y -= dxy; bottom[i, j].Y += dxy; } else { g.DrawLine(pen, left[i, j].X, left[i, j].Y, left[i, j].X, left[i, j].Y + len); g.DrawLine(pen, right[i, j].X, right[i, j].Y, right[i, j].X, right[i, j].Y - len); g.DrawLine(pen, top[i, j].X, top[i, j].Y, top[i, j].X + len+2, top[i, j].Y); g.DrawLine(pen, bottom[i, j].X, bottom[i, j].Y, bottom[i, j].X - len-2, bottom[i, j].Y); } } private void Draw() { btmp = new Bitmap(pbox.Width, pbox.Height); g = Graphics.FromImage(btmp); g.TranslateTransform((float)pbox.Width / 2, (float)pbox.Height / 2);//сдвигаем начало координат в центр g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; for (int i = 0; i < quantity; i++)//обход всех точек для прорисовки { for (int j = 0; j < 2 * quantity; j++) { if (order[i, j] < cur_order)// если точка в предыдущем слое(уже сдвинута) Draw_square(i, j, helppen); else if (order[i, j] == cur_order)// если точка в текущем слое Draw_square(i, j, temppen, 1);// рисуем с меняющимся цветом и сдвигом if (next_order <= cur_order)// если не начато движение следующего { if (order[i, j] > cur_order) Draw_square(i, j, mainpen);// рисуем следующие слои старым цветом } else //если началось движение следующего слоя (next_order) { if (order[i, j] == next_order) Draw_square(i, j, temppen2, 1);// сдвигаем и меняем цвет для движущегося квадрата else if (order[i, j] > next_order) Draw_square(i, j, mainpen);// остальные без изменений } } } pbox.BackgroundImage = btmp; } private void timer1_Tick(object sender, EventArgs e)//таймер изменяет счётчик и позволяет квадратам двигаться { if (counter > (len / 2 + 1) / 2)//если счётчик больше { next_order = cur_order + 1;// начинаем двигать следующий слой if (counter > len / 2)// если счётчик больше { counter = 0;// обнуляем cur_order++;// текущий слой меняется } } if (counter == (len / 2 + 1) / 2) color2 = 0;//обнуляем цвет для нового движения else if (counter == 0) color = color2;// меняется слой (был next_order, стал cur_order), цвет продолжает изменятся с этого значения color += dcolor; color2 += dcolor; if (dxy > 0)//если движемся от зелёного к желтому { coltemp = Color.FromArgb(255, 80 + 2 * color, 255 - color, 50); coltemp2 = Color.FromArgb(255, 80 + 2 * color2, 255 - color2, 50); } else//от желтого к зелёному { coltemp = Color.FromArgb(255, 190 - 2 * color, 195 + color, 50); coltemp2 = Color.FromArgb(255, 190 - 2 * color2, 195 + color2, 50); } if (cur_order > quantity - 1)//реверс, замена цветов mainpen и helppen { dxy = -dxy; // сбрасываем счётчик слоёв cur_order = -1; next_order = -1; // меняем цвета temppen = mainpen; mainpen = helppen; helppen = temppen; } temppen = new Pen(coltemp, 3); temppen2 = new Pen(coltemp2, 3); counter++; Draw();//функция отрисовки } private void Click_pbox(object sender, EventArgs e) { if (timer1.Enabled == true) { timer1.Stop(); } else timer1.Start(); }// позволяет нажать паузу } }
Прикрепленный файл | Размер |
---|---|
Martyniuk_-_digital_squares.rar | 97.27 кб |