Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005
.pdf260 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
//Изменяя координаты этих точек, //мы изменяем и анимационный эффект:
Drawing::Drawing2D::LinearGradientBrush^ myBrush =
gcnew Drawing::Drawing2D::LinearGradientBrush( PointF(0.0f, 0.0f), PointF(Shift_of_Gradient, 200.0f), Color::Red, BackColor);
//Рисуем текст в прямоугольнике: myGraphics->DrawString(drawText, myFont,
myBrush, 0, 0);
//Высвобождаем ресурсы, выделенные объекту
//myGraphics: myGraphics->Dispose();
//Сдвигаем градиент заливки текста
//на шаг Shift_of_Gradient;
//заново начинаем цикл градиентной заливки текста, //когда величина Shift_of_Gradient
//достигнет заданного значения: Shift_of_Gradient = Shift_of_Gradient +
Step_of_Gradient;
if (Shift_of_Gradient == 500)
{
Step_of_Gradient = -5;
}
else if (Shift_of_Gradient == -50)
{
Step_of_Gradient = 5;
}
}
В этом коде главным является вызов перегруженного метода DrawString (класса
Graphics) вида DrawString(String, Font, Brush, PointF).
Чтобы установить значение свойства Interval компонента Timer в зависимости от свойства Value ползунка элемента управления TrackBar, дважды щелкаем элемент управления TrackBar в режиме проектирования. Появляется файл Form1.h с шаблоном, который после записи нашего кода принимает следующий вид.
Листинг 52.4. Метод для элемента управления TrackBar. private:
System::Void trackBar1_Scroll(System::Object^ sender, System::EventArgs^ e)
{
//Включаем таймер Timer (задаем Enabled равным true):
Глава 52. Методика анимации градиентного заполнения текста цветом |
261 |
timer1->Enabled = true;
//Устанавливаем свойство Interval таймера Timer //в зависимости от перемещения ползунка Value: timer1->Interval = trackBar1->Value;
}
Согласно разработанной выше методике, чтобы иметь возможность приостановить (и запустить вновь) процесс анимации на любом рисунке при помощи кнопки Stop Animation, дважды щелкаем эту кнопку в режиме проектирования (рис. 52.1). Появляется файл Form1.h с шаблоном, который после записи нашего кода принимает следующий вид.
Листинг 52.5. Метод для кнопки Stop Animation.
//Объявляем булеву переменную OffOn
//и задаем ей значение, например, false: bool static OffOn = false;
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
//Задаем чередование остановки //и возобновления анимации
//после каждого щелчка кнопки Button: if (OffOn == false)
{
//Приостанавливаем анимацию: timer1->Enabled = false;
//Изменяем значение OffOn на противоположное: OffOn = true;
}
else
{
//Возобновляем анимацию: timer1->Enabled = true;
//Изменяем значение OffOn на противоположное: OffOn = false;
}
}
Листинг 52.6. Метод для компонента PrintDocument.
private: System::Void printDocument1_PrintPage( System::Object^ sender, System::Drawing::Printing::PrintPageEventArgs^ e)
{
//Создаем объект myGraphics класса Graphics:
262 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
Graphics^ myGraphics = this->CreateGraphics(); //Связываем объект myGraphics с текущим принтером: myGraphics = e->Graphics;
//Рисуем четыре граничные линии прямоугольника, //внутри которого будет размещаться текст: myGraphics->DrawLine(gcnew Pen(Color::Red, 3),
boundary_of_rectangle_x, boundary_of_rectangle_y, width_of_rectangle, boundary_of_rectangle_y);
myGraphics->DrawLine(gcnew Pen(Color::Red, 3), boundary_of_rectangle_x, boundary_of_rectangle_y, boundary_of_rectangle_x, height_of_rectangle);
myGraphics->DrawLine(gcnew Pen(Color::Red, 3), boundary_of_rectangle_x, height_of_rectangle, width_of_rectangle, height_of_rectangle);
myGraphics->DrawLine(gcnew Pen(Color::Red, 3), width_of_rectangle, boundary_of_rectangle_y, width_of_rectangle, height_of_rectangle);
//Задаем тип шрифта, размер текста и стиль шрифта: Drawing::Font^ myFont =
gcnew Drawing::Font("Times New Roman", 100, FontStyle::Bold, GraphicsUnit::Point);
//Записываем текст, цвет которого будет изменяться: String^ drawText = "Visual";
//Задаем меру строки текста
//при помощи метода MeasureString: SizeF^ SizeF_of_Text =
gcnew SizeF(myGraphics->MeasureString( drawText, myFont));
//Задаем точку, от которой будет рисоваться текст, //сцентрированный внутри прямоугольника:
PointF^ Start_of_drawPointF =
gcnew PointF(Convert::ToSingle( (width_of_rectangle - SizeF_of_Text->Width) / 2),
Convert::ToSingle(
(height_of_rectangle - SizeF_of_Text->Height) / 2)); //Создаем объект myBrush класса LinearGradientBrush
//и задаем его параметры //для градиентной заливки текста
//двумя цветами (Color::Red, BackColor) //от начальной точки PointF(0.0f, 0.0f) //до конечной точки
//PointF(Shift_of_Gradient, 200.0f); //Изменяя координаты этих точек, //мы изменяем и анимационный эффект:
Drawing::Drawing2D::LinearGradientBrush^ myBrush =
gcnew Drawing::Drawing2D::LinearGradientBrush(
Глава 52. Методика анимации градиентного заполнения текста цветом |
263 |
PointF(0.0f, 0.0f),
PointF(Shift_of_Gradient, 200.0f),
Color::Red, BackColor);
//Рисуем текст в прямоугольнике: myGraphics->DrawString(drawText, myFont,
myBrush, 0, 0);
//Высвобождаем ресурсы, выделенные объекту
//myGraphics: myGraphics->Dispose();
}
Глава 53. Вращающееся градиентное заполнение фигур цветом
Листинг 53.1. Метод для компонента Timer1.
//Объявляем и обнуляем глобальную переменную angle: float static angle = 0;
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
//Создаем объект myGraphics класса Graphics: Graphics^ myGraphics = this->CreateGraphics();
//Задаем два граничных цвета Red и Yellow //градиентной заливки: Drawing::Drawing2D::LinearGradientBrush^
myBrush = gcnew Drawing::Drawing2D:: LinearGradientBrush(
ClientRectangle, Color::Red, Color::Yellow, angle);
//Цветом myBrus заполняем прямоугольник
//с координатами верхнего левого угла (5, 5), //шириной и высотой (700, 400): myGraphics->FillRectangle(myBrush, 5, 5, 700, 400);
//Организовываем циклический процесс вращения: angle = angle + 10;
if (angle >= 360) angle = 0;
//Высвобождаем ресурсы, выделенные объекту
//myGraphics: myGraphics->Dispose();
}
Глава 54. Изображение кругов на воде с использованием двойной буферизации
Листинг 54.1. Шаблон метода Form1_Load с кодом.
//Массив окружностей:
myClass[] Circles = new myClass[100];
//В структуре Point объявляем объект myPoint: Point myPoint;
//Генератор случайных чисел: Random myRandow;
int c, j;
private void myMethod()
{
Circles[c] = new myClass(myPoint); c = c + 1;
if (c >= Circles.Length) c = 0;
}
private void Form1_Load(object sender, EventArgs e)
{
//Используем двойную буферизацию: this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint, true); myRandow = new Random();
myMethod();
}
В панели Properties для элемента управления PictureBox на вкладке Events дважды щелкаем по имени события Paint и в шаблон записываем следующий код.
Листинг 54.2. Шаблон метода pictureBox1_Paint с кодом.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Color myColor = Color.Black; float f; e.Graphics.SmoothingMode =
System.Drawing.Drawing2D.SmoothingMode.HighQuality;
int k;
for (k = 0; k <= c - 1; k++)
{
f = 0.05f * Circles[k].value; e.Graphics.DrawEllipse(new Pen(myColor, f),
266 Жарков В.А. Компьютерная графика, мультимедиа и игры на Visual C++ 2005
Circles[k].pos.X - Circles[k].value, Convert.ToInt32(Circles[k].pos.Y - Cir-
cles[k].value / 4),
Circles[k].value * 2, Convert.ToInt32(Circles[k].value / 2));
Circles[k].value = Circles[k].value + 10;
if (Circles[k].value > 100) Circles[k].Reset();
}
}
Чтобы подключить к работе таймер, дважды щелкаем значок timer1 (ниже формы в режиме проектирования). Появляется файл Form1.h с шаблоном, который после записи нашего кода принимает такой вид.
Листинг 54.3. Метод для компонента Timer1.
private void timer1_Tick(object sender, EventArgs e)
{
myMethod();
Refresh(); j = j + 1;
if (j > myRandow.Next(30))
{
j = 0;
myPoint.X = myRandow.Next(pictureBox1.Width); myPoint.Y = myRandow.Next(pictureBox1.Height); c = 0;
}
}
Ниже автоматически сгенерированного шаблона класса partial class Form1: Form записываем следующий дополнительный класс.
Листинг 54.4. Дополнительный класс.
class myClass
{
public Point pos = Point.Empty; public int value = 0;
public myClass(Point pos)
{
Reset(); this.pos = pos;
}
public void Reset()
{
pos = Point.Empty; value = 0;
Глава 54. Изображение кругов на воде с использованием буферизации |
267 |
}
}
Глава 55. Анимация текста в консольном приложении
Листинг 55.1. Файл Animated text on console.cpp перед записью нашего кода.
//This is the main project file for VC++ application project
//generated using an Application Wizard.
#include "stdafx.h" using namespace System; int _tmain()
{
//TODO: Please replace the sample code below //with your own.
Console::WriteLine(L"Hello World");
}
Листинг 55.2. Файл Animated text on console.cpp после записи нашего кода.
//This is the main project file for VC++ application project
//generated using an Application Wizard.
#include "stdafx.h" using namespace System;
//Мы начинаем записывать код: using namespace System::Timers;
public ref class Timer2
{
public: void myMain()
{
//Вводим таймер myTimer, который генерирует событие //через каждый Interval времени, равный, например, //3000 миллисекундам или 3 секундам:
System::Timers::Timer^ myTimer =
gcnew System::Timers::Timer(3000); myTimer->Elapsed+=
gcnew ElapsedEventHandler(OnTimedEvent); //Чтобы таймер совершил событие только один раз, //в следующей строке убираем символы //: //myTimer->AutoReset = false;
//Запускаем в работу таймер: myTimer->Enabled = true;
//Выводим сообщение, как остановить анимацию: Console::WriteLine(
Глава 55. Анимация текста в консольном приложении |
269 |
"Чтобы остановить анимацию, " "нажмите клавиши c + Enter.");
}
private:
static void OnTimedEvent(Object^ source, ElapsedEventArgs^ e)
{
//Анимационное сообщение: Console::WriteLine
("Введите исходные данные" "и нажмите клавишу Enter:");
}
}; //Мы закончили написание кода.
int _tmain()
{
// TODO: Please replace the sample code below //with your own.
//Мы комментируем нижнюю строку, которая уже была здесь: //Console::WriteLine(L"Hello World");
//Мы начинаем записывать код: //Создаем указатель объекта myT, //чтобы выполнить наш метод myMain(): Timer2^ myT = gcnew Timer2; myT->myMain();
//Организовываем цикл работы таймера при помощи while, //который выключает таймер после нажатия клавиш c+Enter: while(Console::Read()!='c');
//Мы закончили написание кода.
}
