Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Компьютерная графика, мультимедиа и игры на Vis...doc
Скачиваний:
5
Добавлен:
01.03.2025
Размер:
2 Мб
Скачать
☆

Глава 58. Управляемый мигающий текст

Листинг 58.1. Метод для элемента управления TrackBar.

private void trackBar1_Scroll(object sender, EventArgs e)

{

timer1.Enabled = true;

timer1.Interval = trackBar1.Value;

}

Чтобы подключить к работе таймер, дважды щелкаем значок для компонента Timer (ниже формы в режиме проектирования). Появляется файл Form13.cs с шаблоном, который после записи нашего кода принимает следующий вид.

Листинг 58.2. Метод для компонента Timer.

//Объявляем булеву переменную myText со значением false:

bool myText = false;

private void timer1_Tick(object sender, EventArgs e)

{

//Программируем анимацию:

if (myText == false)

{

//Задаем чередование черного Black

//и белого White цветов текста

//внутри элемента label1:

this.label1.ForeColor = Color.Black;

//Изменяем значение myText на противоположное:

myText = true;

}

else

{

this.label1.ForeColor = Color.White;

//Изменяем значение myText на противоположное:

myText = false;

}

}

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

По этой методике можно спроектировать анимацию в виде мигания любого текста за счет чередования двух любых цветов текста из длинного списка цветов Visual Studio (рис. 58.1) из структуры Color пространства имен System.Drawing.

Глава 59. Методика изображения летающих предметов

Листинг 59.1. Объявление объекта и глобальных переменных.

//Задаем ширину и высоту прямоугольника,

//внутри которого будет летать мяч:

int width_of_rectangle = 1000;

int height_of_rectangle = 500;

//Верхняя горизонтальная линия прямоугольника отстоит

//от оси 'x' на расстоянии boundary_of_rectangle_у:

int boundary_of_rectangle_у = 15;

//Левая вертикальная линия прямоугольника отстоит

//от оси 'y' на расстоянии boundary_of_rectangle_x:

int boundary_of_rectangle_x = 15;

//Размер мяча size_of_ball, как часть (доля)

//от размеров прямоугольника:

int size_of_ball = 20;

//Величина перемещения мяча size_of_move_of_ball,

//как часть (доля) от размеров мяча:

int size_of_move_of_ball = 5;

//Создаем объект myBitmap класса Bitmap:

private Bitmap myBitmap;

//Объявляем целочисленные переменные:

int position_of_ball_x, position_of_ball_y,

radius_of_ball_x, radius_of_ball_y,

move_of_ball_x, move_of_ball_y,

width_of_bitmap_of_ball, height_of_bitmap_of_ball,

width_of_margin_of_bitmap, height_of_margin_of_bitmap;

Дважды щелкаем по диалоговой панели Form1 в режиме проектирования и в появившийся шаблон записываем следующий наш код.

Листинг 59.2. Метод Form1_Load.

private void Form1_Load(object sender, EventArgs e)

{

//Создаем объект myGraphics класса Graphics

//и стираем другие изображения:

Graphics myGraphics = CreateGraphics();

myGraphics.Clear(BackColor);

//Задаем радиус мяча как дробь (часть)

//от ширины или высоты прямоугольника,

//в зависимости от того, какая дробь меньше:

double radius_of_ball =

Math.Min(width_of_rectangle / myGraphics.DpiX,

height_of_rectangle / myGraphics.DpiY) / size_of_ball;

//Задаем ширину и высоту мяча в DPI (ТОЧКИ НА ДЮЙМ)

//для единиц разрешения изображения

//по горизонтали и вертикали, что идентично значениям

//в направлении осей 'x' и 'y':

radius_of_ball_x = Convert.ToInt32(radius_of_ball *

myGraphics.DpiX);

radius_of_ball_y = Convert.ToInt32(radius_of_ball *

myGraphics.DpiY);

//Высвобождаем ресурсы, выделенные объекту myGraphics:

myGraphics.Dispose();

//Задаем шаг перемещения мяча или в 1 пиксель,

//или как часть (дробь, доля) от размера шара,

//в зависимости от того, какая величина больше.

//Это означает, что на каждом шаге перемещение мяча

//пропорционально его размеру,

//а размер мяча, в свою очередь,

//пропорционален размеру прямоугольника.

//Таким образом, при прочих равных условиях,

//когда размеры прямоугольника уменьшаются,

//перемещение мяча замедляется,

//и когда увеличиваются, перемещение мяча убыстряется:

move_of_ball_x = Convert.ToInt32(Math.Max(1,

radius_of_ball_x / size_of_move_of_ball));

move_of_ball_y = Convert.ToInt32(Math.Max(1,

radius_of_ball_y / size_of_move_of_ball));

//Значение перемещения мяча также определяет

//поле изображения вокруг мяча.

//На каждом шаге перемещение мяча

//равно перемещению поля изображения,

//что позволяет стирать предыдущее изображение мяча

//перед каждым последующим изображением мяча

//без мерцания:

width_of_margin_of_bitmap = move_of_ball_x;

height_of_margin_of_bitmap = move_of_ball_y;

//Определяем фактический размер изображения,

//где нарисован мяч,

//прибавляя поля к размерам мяча:

width_of_bitmap_of_ball = 2 * (radius_of_ball_x +

width_of_margin_of_bitmap);

height_of_bitmap_of_ball = 2 * (radius_of_ball_y +

height_of_margin_of_bitmap);

//Создаем новый рисунок мяча

//соответствующей ширины и высоты:

myBitmap = new Bitmap(width_of_bitmap_of_ball,

height_of_bitmap_of_ball);

//Получаем объект класса Graphics

//для изображения мяча,

//удаляем существующий мяч и рисуем новый мяч.

//Задаем черный цвет Black для мяча,

//чтобы он был лучше виден в книге:

myGraphics = Graphics.FromImage(myBitmap);

myGraphics.Clear(BackColor);

myGraphics.FillEllipse(Brushes.Black, new

Rectangle(move_of_ball_x,

move_of_ball_y, 2 * radius_of_ball_x, 2 *

radius_of_ball_y));

//Высвобождаем ресурсы, выделенные объекту myGraphics:

myGraphics.Dispose();

//Задаем расположение мяча в центре прямоугольника:

position_of_ball_x =

Convert.ToInt32(width_of_rectangle / 2);

position_of_ball_y =

Convert.ToInt32(height_of_rectangle / 2);

}

Чтобы подключить к работе таймер, дважды щелкаем значок для компонента Timer (ниже формы в режиме проектирования). Появляется файл Form1.cs с шаблоном, который после записи нашего кода принимает следующий вид.

Листинг 59.3. Метод для компонента Timer.

private void timer1_Tick(object sender, EventArgs e)

{

//Создаем объект myGraphics класса Graphics:

Graphics myGraphics = CreateGraphics();

//Рисуем четыре граничные линии прямоугольника,

//от которых будет отскакивать летающий мяч:

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, boundary_of_rectangle_у,

width_of_rectangle, boundary_of_rectangle_у);

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, boundary_of_rectangle_у,

boundary_of_rectangle_x, height_of_rectangle);

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, height_of_rectangle,

width_of_rectangle, height_of_rectangle);

myGraphics.DrawLine(new Pen(Color.Red, 3),

width_of_rectangle, boundary_of_rectangle_у,

width_of_rectangle, height_of_rectangle);

//Рисуем изображение мяча на диалоговой панели Form1

//при помощи метода DrawImage:

myGraphics.DrawImage(myBitmap,

Convert.ToInt32(position_of_ball_x -

width_of_bitmap_of_ball / 2),

Convert.ToInt32(position_of_ball_y -

height_of_bitmap_of_ball / 2),

width_of_bitmap_of_ball, height_of_bitmap_of_ball);

//Высвобождаем ресурсы, выделенные объекту myGraphics:

myGraphics.Dispose();

//После изображения мяча с текущими координатами

//увеличиваем координаты мяча

//на шаг перемещения в направлении осей 'x' и 'y':

position_of_ball_x = position_of_ball_x +

move_of_ball_x;

position_of_ball_y = position_of_ball_y +

move_of_ball_y;

//Изменяем направление перемещения мяча по оси 'x',

//когда мяч ударяется о какую-либо из двух

//граничных вертикальных линий прямоугольника:

if (position_of_ball_x + radius_of_ball_x >=

width_of_rectangle)

{

move_of_ball_x = -move_of_ball_x;

//В момент удара подаем звуковой сигнал Beep:

Microsoft.VisualBasic.Interaction.Beep();

}

if (position_of_ball_x - radius_of_ball_x <=

boundary_of_rectangle_x)

{

move_of_ball_x = -move_of_ball_x;

Microsoft.VisualBasic.Interaction.Beep();

}

//Изменяем направление перемещения мяча по оси 'y',

//когда мяч ударяется о какую-либо из двух

//граничных горизонтальных линий прямоугольника:

if (position_of_ball_y + radius_of_ball_y >=

height_of_rectangle)

{

move_of_ball_y = -move_of_ball_y;

Microsoft.VisualBasic.Interaction.Beep();

}

if (position_of_ball_y - radius_of_ball_y <=

boundary_of_rectangle_у)

{

move_of_ball_y = -move_of_ball_y;

Microsoft.VisualBasic.Interaction.Beep();

}

}

В этом коде главным является вызов перегруженного метода DrawImage, который в VC# имеет много видов перегрузки. Здесь использован вид перегрузки номер 13 с сигнатурой: Overloads Public Sub DrawImage(Image, Integer, Integer, Integer, Integer). Этот метод мы уже объясняли в предыдущей главе.

Чтобы установить значение свойства Interval компонента Timer в зависимости от свойства Value ползунка элемента управления TrackBar, дважды щелкаем элемент управления TrackBar в режиме проектирования. Появляется файл Form1.cs с шаблоном, который после записи нашего кода принимает следующий вид.

Листинг 59.4. Метод для элемента управления TrackBar.

private void trackBar1_Scroll(object sender, EventArgs e)

{

timer1.Enabled = true;

timer1.Interval = trackBar1.Value;

}

Согласно разработанной выше методике, чтобы иметь возможность приостановить (и запустить вновь) процесс анимации на любом рисунке при помощи кнопки Stop Animation, дважды щелкаем эту кнопку в режиме проектирования (рис. 59.1). Появляется файл Form1.cs с шаблоном, выше которого объявляем переменную OffOn и присваиваем ей значение false:

//Объявляем булеву переменную OffOn

//и задаем ей значение, например, false:

bool OffOn = false;

После записи нашего кода шаблон принимает вид следующего метода.

Листинг 59.5. Метод для кнопки Stop Animation.

private void button6_Click(object sender, EventArgs e)

{

//Задаем чередование остановки и возобновления анимации

//после каждого щелчка кнопки button2:

if (OffOn == false)

{

//Приостанавливаем анимацию:

timer1.Enabled = false;

//Изменяем значение OffOn на противоположное:

OffOn = true;

}

else

{

//Возобновляем анимацию:

timer1.Enabled = true;

//Изменяем значение OffOn на противоположное:

OffOn = false;

}

}

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

Листинг 59.6. Метод для компонента PrintDocument.

private void printDocument1_PrintPage(object sender,

System.Drawing.Printing.PrintPageEventArgs e)

{

//Создаем объект myGraphics класса Graphics:

Graphics myGraphics = CreateGraphics();

//Связываем объект myGraphics с текущим принтером:

myGraphics = e.Graphics;

//Рисуем четыре граничные линии прямоугольника,

//от которых будет отскакивать летающий мяч:

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, boundary_of_rectangle_у,

width_of_rectangle, boundary_of_rectangle_у);

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, boundary_of_rectangle_у,

boundary_of_rectangle_x, height_of_rectangle);

myGraphics.DrawLine(new Pen(Color.Red, 3),

boundary_of_rectangle_x, height_of_rectangle,

width_of_rectangle, height_of_rectangle);

myGraphics.DrawLine(new Pen(Color.Red, 3),

width_of_rectangle, boundary_of_rectangle_у,

width_of_rectangle, height_of_rectangle);

//Рисуем изображение мяча на диалоговой панели Form1

//при помощи метода DrawImage:

myGraphics.DrawImage(myBitmap,

Convert.ToInt32(position_of_ball_x -

width_of_bitmap_of_ball / 2),

Convert.ToInt32(position_of_ball_y -

height_of_bitmap_of_ball / 2),

width_of_bitmap_of_ball,

height_of_bitmap_of_ball);

//Высвобождаем ресурсы, выделенные объекту myGraphics:

myGraphics.Dispose();

}

Теперь дважды щелкаем кнопку Print (рис. 59.1). Открывается файл Form1.cs с шаблоном, который после записи нашего кода принимает следующий вид.

Листинг 59.7. Метод для кнопки Print.

private void button3_Click(object sender, EventArgs e)

{

//Передаем объекту PrintDialog1 информацию об объекте

//PrintDocument1 при помощи свойства Document:

printDialog1.Document = printDocument1;

//Выводим стандартную панель Print при помощи метода

//ShowDialog для задания параметров печати:

if (printDialog1.ShowDialog() == DialogResult.OK)

printDocument1.Print();

}

Таким образом, по разработанной в данной главе методике можно спроектировать анимацию на экране монитора и печать текущего положения анимации на принтере для любого предмета (в виде мяча, шара, пули и т.п.), летающего в открытом или замкнутом пространстве.