using System; using System.Collections.Generic; using System.Drawing; using System.Text; namespace cForm { class xPoint { // Собственный статический генератор случайных чисел. // Используется в конструкторе. public static Random rnd = new Random(); // Цвет объекта. public Color xColor; // Текущая позиция. Относительные значения координат X и Y. public Point p; // Обеспечение перемещения. Текущие значения координат могут // изменяться как по X, так и по Y. public Point direction; // Счетчик циклов сохранения выбранного направления. // Объект на протяжении фиксированного интервала времени может // сохранять ранее избранное направление движения. // В течение n.X "тиков" для X в течение n.Y "тиков" для Y. public Point n; public xPoint(int X, int Y, int Xn, int Yn) { n = new Point(rnd.Next(0, Xn), rnd.Next(0, Yn)); direction = new Point(rnd.Next(-1, 2), rnd.Next(-1, 2)); p = new Point(X, Y); xColor = Color.FromArgb(150, rnd.Next(0, 256), rnd.Next(0, 256), rnd.Next(0, 256)); } // Статический метод. Еще вопрос, где следовало размещать его // объявление... Определение нового положения амебы. // Просматривается ВЕСЬ список. // Ее перемещение ограничивается физическими размерами клиентской области // окна приложения и определяется по двум координатам (X и Y). // В каждый момент она может оставаться на месте, либо изменить // свое положение на один "шаг" по каждой из осей координат // ("вверх" или "вниз" по оси Y и "вперед" или "назад" по оси X). public static void setNextPosition(cForm cf, xPoint[] pt) { int i; float xy; // Итак, определение текущей позиции объекта. // Просмотр массива... for (i = 0; i < pt.Length; i++) { // Сначала разбираемся со значением координаты X. // Вычисляем возможную позицию после перемещения объекта. xy = (float)((pt[i].p.X + pt[i].direction.X) * cf.rPointGet); // Вполне возможно, что это вполне подходящая позиция. // И надо всего лишь проверить две вещи: // 1. не выскочит ли объект за пределы клиентской области окна // приложения, // 2. не настало ли время поменять направление движения. if ( xy < 0 || xy > cf.ClientSize.Width // 1. || pt[i].n.X > cf.NX // 2. ) { pt[i].n.X = 0; // Обнулили счетчик циклов сохранения выбранного направления. // Процедура изменения направления перемещения по оси X. // На ближайшую перспективу объект может переместиться // вперед: pt[i].direction.X == 1, // назад: pt[i].direction.X == –1, // остаться на месте: pt[i].direction.X == 0. // Главное — это не выйти за пределы клиентской области окна приложения. pt[i].direction.X = xPoint.rnd.Next(-1, 2); xy = (float)((pt[i].p.X + pt[i].direction.X) * cf.rPointGet); if (xy >= 0 && xy <= cf.ClientSize.Width) { // Направление выбрано, перемещение произведено. pt[i].p.X += pt[i].direction.X; } else { // Выбранное направление движения приводит к выходу объекта // за пределы клиентской области окна приложения. // На ближайшие cf.NX тактов объект остается неподвижен по оси X. pt[i].direction.X = 0; } } else { // Осуществили очередное перемещение по оси X. pt[i].p.X += pt[i].direction.X; pt[i].n.X++; } xy = (float)((pt[i].p.Y + pt[i].direction.Y) * cf.rPointGet); // Вполне возможно, что это вполне подходящая позиция. // И надо всего лишь проверить две вещи: // 1. не выскочит ли объект за пределы клиентской области // окна приложения, // 2. не настало ли время поменять направление движения. if ( xy < 0 || xy > cf.ClientSize.Height // 1. || pt[i].n.Y > cf.NY // 2. ) { pt[i].n.Y = 0; // Обнулили счетчик циклов сохранения выбранного направления. // Процедура изменения направления перемещения по оси Y. // На ближайшую перспективу объект может переместиться // вверх: pt[i].direction.Y == 1, // вниз: pt[i].direction.Y == -1, // остаться на месте: pt[i].direction.Y == 0. // Главное — это не выйти за пределы клиентской области окна приложения. pt[i].direction.Y = xPoint.rnd.Next(-1, 2); xy = (float)((pt[i].p.Y + pt[i].direction.Y) * cf.rPointGet); if (xy >= 0 && xy <= cf.ClientSize.Height) { // Направление выбрано, перемещение произведено. pt[i].p.Y += pt[i].direction.Y; } else { // Выбранное направление движения приводит к выходу объекта // за пределы клиентской области окна приложения. // На ближайшие cf.NY тактов объект остается неподвижен по оси Y. pt[i].direction.Y = 0; } } else { // Осуществили очередное перемещение по оси Y. pt[i].p.Y += pt[i].direction.Y; pt[i].n.Y++; } } } } } |
Листинг 17.1. |
Закрыть окно |