#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double RadReal;
int Angle,X,Y;
int Count,Count2;
for(Count2= 1; Count2< 10; Count2++) {
Angle = random(368);
RadReal = (Angle * M_PI)/180;
for(Count= 1; Count< 100; Count++) {
X = (double)/*<<-------*/(Count*sin(RadReal))+100;
Y = (double)/*<<-------*/(Count*cos(RadReal))+100;
// рисуемэллипсголубымцветом
PaintBox1->Canvas->Brush->Color =clBlue;
PaintBox1->Canvas->Ellipse (X-6,Y-6,X+6,Y+6);
// стираемэллипсбелымцветом
PaintBox1->Canvas->Brush->Color = clWhite;
PaintBox1->Canvas->Rectangle(0,0,200,200);
}
}
}
//---------------------------------------------------------------------------
Если запустить программу на выполнение, то изображение эллипсов будет мерцать, хотя они будут двигаться очень быстро.
Для преодоления этого недостатка в аннимации используют метод двойной буферизации. В этом случае используют две плоскости - одна отображается на экране, а вторая используется для рисования.Далее плоскости меняются местами.
Одним из способов организации двойной буферизации - создание в памяти битовой матрицы в качестве промежуточного буфера. Изображение рисуется в битовой матрице, а по завершению кадра копируется в отображаемый буфер. Рассмотрим предыдущий пример с использованием битовой матрицы.
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragmahdrstop
#include <math.h> // <<--включить библиотеку математических функций
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double RadReal;
int Angle,X,Y;
intCount,Count2;
// создание битовой матрици
Graphics::TBitmap *TheBitmap = new Graphics::TBitmap();
// определяем ее размеры
TheBitmap->Height = 200;
TheBitmap->Width = 200;
for(Count2= 1; Count2< 10; Count2++) {
Angle = random(368); // занести случайное число
RadReal = (Angle * M_PI)/180;
for(Count= 1; Count< 100; Count++) {
X = (double)(Count*sin(RadReal))+100;
Y = (double)(Count*cos(RadReal))+100;
// очистка экрана
TheBitmap->Canvas->Brush->Color = clWhite;
TheBitmap->Canvas->Rectangle(0,0,200,200);
// рисование эллипса
TheBitmap->Canvas->Brush->Color = clBlue;
TheBitmap->Canvas->Ellipse(X-6,Y-6,X+6,Y+6);
// копирование битовой матрици на экран
PaintBox1->Canvas->CopyRect(Rect(0,0,200,200),
TheBitmap->Canvas, Rect(0,0,200,200));
}
}
// освобождаем память выделенную под битовую матрицу
deleteTheBitmap;
}
//---------------------------------------------------------------------------
При запуске примера видно, что эллипсы движутся плавно, но процедура выполняется медленнеее
4.9 Мультимедиа
Мультимедиа - это использования звука и видео в программах. Для работы со звуком (файлами с расширением wav и mid) нужна звуковая карта - Soundblaster.
В файлах с расширением wav записано цифровое представление информации о волновой форме электрического сигнала, соответствующего звуку.
Файлы с расширением mid используются для хранения музыкальных фрагментов. Звук в этих файлах хранится в виде данных о том на каком инструменте исполняются те или иные ноты и как они звучат (цифрой эквивалент дирижерской партитуры).
Файл с расширением avi представляет оцифрованное изображение в виде кадров, которые сменяются с частотой 24 (могут быть отличия в различных системах) кадра в секунду. Обычно видеофайлы сжаты, т.к. занимают достаточно много места в памяти. Для сжатия применяется в основном следующий метод: определяется неподвижная часть изображения, по сравнению к начальному кадру и эта информация сжимается, т.е. сохраняются только отличия одного кадра от другого.
Для проигрывания wav файлов в C++ Builder используется процедура PlaySound. Рассмотрим пример – по нажатию клавиши Button – проигрывается звуковой файл bomb.wav.
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "mmsystem.hpp"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PlaySound("bomb.wav",0,SND_SYNC);
}
//---------------------------------------------------------------------------
Как видно из программы дополнительно введен модуль mmsystem (в котором хранятся константы для функции PlaySound) и вызвана API функция PlaySound, которая имеет три параметра:
Первый параметр - "bomb.wav" типа AnsiString - содержит имя проигрываемого файла.
Второй параметр (в нашем случае 0) применяется, если файл содержится в файле ресурсов.
Третий параметр специфицирует опции, задающие способ воспроизведения звука.
Для проигрывания всех типов мультимедийных файлов можно использовать компонент MediaPlaer.
Рассмотрим пример, проигрывания avi, wav и mid файлов.
На форме расположим компоненты: MainMenu, OpenDialog, MediaPlayer, добавим к меню команду File|Open и в событие меню Open введемкод:
void __fastcall TForm1::Open1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
MediaPlayer1->FileName=OpenDialog1->FileName;
MediaPlayer1->Open();
}
}
Общий вид программы следующий:
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::N2Click(TObject *Sender)
{
if(OpenDialog1->Execute())
{
MediaPlayer1->FileName=OpenDialog1->FileName;
MediaPlayer1->Open();
}
}
//---------------------------------------------------------------------------
Загружая через меню тот или иной мультимедийный файл мы сможем его проигрывать.
В случае, если панель проигрывателя показывать не надо, а проигрывать файл необходимо, то свойство Visible компоненты MediaPlayer нужно установить равным false.
Рассмотрим пример - информационной системы - в зависимости от выбранной радиокнопки проигрывается тот или иной avi файл. Используются компоненты: MediaPlayr, RadioGroup, RadioButton, Panel, Button.
Основная логика программы реализуется в обработке события OnClick кнопки Button. Когда пользователь нажимает кнопку, программа проверяет, какая из радиокнопок выбрана. В зависимости от этого проигрывается один из трех avi-файлов.
//---------------------------------------------------------------------------
#include <vcl\vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MediaPlayer1->Display=Panel1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(RadioButton1->Checked)
MediaPlayer1->FileName="1.AVI";
if(RadioButton2->Checked)
MediaPlayer1->FileName="2.AVI";
if(RadioButton3->Checked)
MediaPlayer1->FileName="3.AVI";
MediaPlayer1->Open();
MediaPlayer1->DisplayRect=Rect(0,0,
Panel1->Width,Panel1->Height);
MediaPlayer1->Play();
}
//---------------------------------------------------------------------------
4.10 Спрайтовая графика
Спрайты - движущиеся картинки небльшого размера, являются одной из главных частей любого игрового или обучающего пакета программ. Рассмотрим несколько примеров использование спрайтов MChSprite из линейки Samples
Компонента MchSpriteBgr.
Данная компонента представляет собой фон на котором происходит движение спрайтов. Одним из основных свойств MchSpriteBgr является свойство Picture – загрузка bmp или gif изображения.
Компонента MchSprite.
Компонента представляет собой собственно спрайт- небольшое bmp -изображение. Для загрузки изображения используется свойство SprSpriteBitmap.
Основные свойства MchSprite:
SprHideAfter – виден или нет спрайт после окончания движения (MChSprite1->SprHideAfter=True - не виден);
SprSetScaleX – масштаб спрайта по оси Х;
SprSetScaleY – масштаб спрайта по оси Y;
Пример – изменение масштаба спрайта при приближении:
Form1->MChSprite2->SprSetScaleX(1+1.0*sin(alpha)); (где alpha - переменнаятипа double);
SprPosFunc – функция пользователя – закон движения спрайта (возвращает координаты движения спрайта) – пример:
//функция пользователя для движения спрайта N 2
TPoint __fastcall Sprite2PosFunc(TDateTime AtTime)
//AtTime – время от начала движения спрайта в секундах
{
doublex,y,alpha;
alpha=2*3.14*(AtTime-Form1->MChSprite2->SprTimeStarted)* 24.0*60.0100.0/(180.0*3.14);
x= Form1->MChSpriteBgr1->ClientWidth /2.0 +
(Form1->MChSpriteBgr1->ClientWidth /3.0)*cos(alpha);
y= Form1->MChSpriteBgr1->ClientHeight /2.0 +
(Form1->MChSpriteBgr1->ClientWidth /3.0)*sin(alpha);
Form1->MChSprite2->SprSetScale(1+1.0*sin(alpha));
return(Point(int(x),int(y)));
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
MChSprite2->SprPosFunc=Sprite2PosFunc;//вызовфункциидвижения
MChSprite2->SprCruise(-1);
}
//---------------------------------------------------------------------------
SprSpriteBitmap – изображениеспрайта;
SprTrColor – цвет спрайта;
SprDragable – если истина, то спрайт можно премещать мышью;
SprColliding – если истина, то вызывается функция пользовыателя для обработки столкновения спрайтов;
SprRefX, SprRefY –соответственно контрольная точка на растре спрайта по оси X и Y;
SprRadiusX ,SprRadiusY радиус столкновения спрайта по оси X и оси Y соответственно;
Основные методы MchSprite.
Метод SprRun (Point (X1, Y1), Point (X2,Y2), t) –делает спрайт видимым при движении из одной позиции (X1, Y1) в другую (X2, Y2) в течении того или иного времени (t).
Пример: (MChSprite1->SprRun(
Point (MChSpriteBgr1->ClientWidth, 0),
Point (0, MChSpriteBgr1->ClientHeight), 3);
Метод SprShowOn (); делает спрайт видимым в текущей позиции.
Метод SprCruise (-1); делает спрайт видимым и его движение задается функцией пользователя SprPosFunc;
Метод SprMoveTo (Point (X, Y); делает спрайт видимым в позиции X, Y.
Пример:
MChSprite6->SprMoveTo (Point (int ((Form1->MChSpriteBgr1->ClientWidth)/2), int((Form1->MChSpriteBgr1->ClientHeight)/2)));
Метод SprShowAt(Point(X,Y); - делает спрайт видимым в точке X,Y.
Метод SprHide – делает спрайт невидимым;
Метод SprStop – останавливает спрайт;
Метод SprGoTo (Point(X,Y),t); - делает спрайт видимым и перемещает в течении t секунд из текущей позиции в позицию X, Y.