Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Жарков В.А. - Visual C++ 2005, DirectX 9.0c и Microsoft Agent в компьютерной графике, мультимедиа и играх (Листинги книги) - 2005

.pdf
Скачиваний:
363
Добавлен:
13.08.2013
Размер:
1 Мб
Скачать
☆

260 Жарков В.А. Компьютерная графика, мультимедиа и игры на 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');

//Мы закончили написание кода.

}

Соседние файлы в предмете Программирование на C++