C++Builder. Учебный курс
.pdfТаким образом, для создания анимации необходимо выпол нить следующие действия:
-разместить на форме компонент T T im er;
-объявить в файле реализации модуля (или в заголовочном файле) глобальные переменные;
- в обработчике |
события O n C re a te формы инициализиро |
вать эти переменные; |
|
-создать обработчик события O n P a in t формы для рисова ния изображения (в нашем случае шарика);
- в обработчике события O nT im er компонента TTim er из менить значения одной или нескольких глобальных переменных и
вызвать метод I n v a l i d a t e для рисования изображения в новом
месте.
Дополним нашу программу секундомером для фиксации вре мени движения шарика от стенки до стенки. Для этого:
- Разместите на форме два компонента T L a b e l и расположи те их в левом верхнем углу.
- |
Очистите свойство C a p tio n обоих компонентов. |
- |
Объявите в файле реализации модуля глобальные перемен |
ные.
TDateTime t , t l , t 2 ; |
|
|
|
|||
- В |
обработчик события O n C re a te |
формы добавьте опера |
||||
тор. |
|
|
|
|
|
|
t 2 = |
T i m e ( ) ; |
|
|
|
|
|
-И зм ените |
обработчик |
события |
OnTim er |
компонента |
||
T T im er. |
|
|
|
|
||
v o id |
__f a s t c a l l |
T F o r m l: :T im e rlT im e r (TObject |
*Sender) |
|||
{ |
|
|
|
|
|
|
x |
+= |
dx; |
|
|
|
|
t |
= |
T i m e ( ) ; |
|
|
|
|
L a b e l l - > C a p t i o n = T i m e T o S t r (t - t 2 ) ; |
|
|||||
i f |
( x + r > = C l ie n tW i d th | | |
x<=r) |
|
|
{
dx = - d x ;
t l |
= |
t 2 ; |
t2 |
= |
T im e( ); |
L a b e l2 -> C a p tio n = T im e T o S tr ( t2 - tl) ; |
}
I n v a l i d a t e ( );
}
- Запустите приложение и проверьте правильность его работы. Обратите внимание, что при добавлении на форму компонен
тов T L a b e l стало более заметным мерцание изображения.
- Для исключения мерцания добавьте в обработчик события
O n C re a te формы оператор.
F o rm l-> D o u b leB u ffered = tr u e ;
D o u b le B u f f e r e d - это свойство формы, доступное при вы полнении программы. Присваивание этому свойству значения t r u e убирает мерцание при анимации, пусть и не полностью, но результат очень заметен.
-Запустите приложение и проверьте правильность его работы.
-Проведите исследование времени движения шарика в зави
симости от значения свойства I n t e r v a l компонента T T im er.
- Самостоятельно измените текст программы таким образом, чтобы шарик перемещался и в вертикальном направлении.
8.2. Моделирование броуновского движения
Рассмотрим более сложный пример создания анимации - мо делирование броуновского движения.
- Начните новый проект.
Для написания этой программы создадим новый класс T B a ll. Объявление этого класса разместим в заголовочном файле, а определение методов класса - в файле реализации модуля.
-Д л я добавления к проекту нового файла выполните в ко манду F ile - > N e w - > U n it - C + + B u ild e r .
8.2.1.Определение класса TBall
- В заголовочный файл добавьте определение класса T B all.
c l a s s T B a ll
{
p r i v a t e : |
|
|
|
|
|
d o u b le |
x , |
у ; |
/ / |
Координаты шарика |
|
d o u b le |
a l f a ; |
/ / |
Угол |
||
i n t |
d; |
/ / |
Перемещение шарика |
||
i n t |
г ; |
/ / |
Радиус |
шарика |
T C o lo r |
C o lo r ; |
/ / Цвет шарика |
|
|
||||
p u b l i c : |
|
|
|
|
|
|
|
|
T B a l l ( d o u b l e |
|
xx=0, |
d o u b le yy = 0 , d o u b le al= 0 , i n t |
|||||
dd=0, i n t |
|
r r = 0 , |
T C o lo r |
c l = c l B l a c k ) ; |
|
|||
v o i d |
D r a w ( G r a p h ic s : :TBitm ap |
*TheIm age); |
||||||
v o i d |
N ew Coord( ) ; |
|
|
|
|
|||
f r i e n d |
d o u b le |
D i s t ( T B a l l |
a, |
T B all |
b) ; |
|||
f r i e n d |
v o i d |
C la s h ( T B a ll |
& bl, |
T B all |
&b2) ; |
};
Вклассе объявлены:
-конструктор T B a ll, предназначенный для инициализации объектов класса;
-метод Draw - для рисования шарика;
-метод NewCoord - для вычисления новых координат шарика;
-дружественная функция D i s t - для вычисления расстояния между двумя шариками;
-дружественная функция C la s h - для учета столкновения шариков.
- Добавьте команду препроцессора.
#i n c l u d e <G r a p h i c s . hpp>
- Сохраните файл под именем B a l l . h.
Окончательно заголовочный файл будет иметь следующий
вид:
# i f n d e f |
B a llH |
|
|
|
|
# d e f i n e |
B a llH |
|
|
|
|
# i n c l u d e |
< G r a p h i c s . hpp> |
|
|||
class T B a ll |
|
|
|
|
|
{ |
|
|
|
|
|
private: |
|
|
|
|
|
double |
x , у / |
/ / |
Координаты |
шарика |
|
double |
a l f a ; |
/ / |
Угол |
|
|
int |
d; |
|
/ / |
Перемещение |
шарика |
int |
r; |
|
/ / |
Радиус шарика |
T C o lo r C o lo r ; |
/ / Цвет шарика |
|
|
|
||||
public: |
|
|
double yy=0, |
double a l =0, int |
||||
T B a l l (double x x = 0 , |
||||||||
dd=0, |
int r r = 0 , |
T C o lo r |
c l = c l B l a c k ) ; |
|
|
|||
void D r a w ( G r a p h ic s : : TB itm ap |
* T h e Im a g e ); |
|||||||
void N ew Coord( ) ; |
|
|
|
|
|
|||
friend d o u b le |
D i s t ( T B a l l |
a , |
T B a ll |
b ) ; |
||||
friend v o i d |
C l a s h ( T B a l l |
&bl, |
T B a ll |
&b2); |
||||
}; |
|
|
|
|
|
|
|
|
# e n d i f |
|
|
|
|
|
|
|
|
Заголовочный файл начинается с директивы условной компи |
||||||||
ляции |
i f n d e f и директивы d e f i n e . |
Это позволяет исключить |
||||||
зацикливание при циклических директивах |
i n c l u d e , включаю |
щих в различных модулях заголовочные файлы друг друга. Когда в приложении первый раз включается файл B a l l .h , то выполня ются указанные выше первые две директивы и идентификатор B a llH оказывается определен. После этого компилируется текст файла, который находится между строками i f n d e f и e n d if . Но если в результате директив i n c l u d e этот же файл будет вклю чаться еще один раз, то обнаружится, что идентификатор B a llH уже определен, и повторной компиляции файла не произойдет.
8.2.2. |
Определение методов класса TBall |
Методы класса T B a ll и дружественные функции будем оп
ределять в файле реализации модуля B a l l . срр.
-Самостоятельно напишите конструктор класса.
-Для рисования на форме шарика определите метод Draw.
void T B a l l ::Draw (G ra p h ic s : rTBitmap *TheImage)
{
T h e lm a g e - > C a n v a s - > P e n - > C o lo r = C o lo r;
T h e Im a g e - > C a n v a s - > B ru sh - > C o lo r = C o lo r;
T h e lm a g e - > C a n v a s - > E llip s e ( x - r , y - r , x + r, y+r) ;
}
О назначении параметра T h elm ag e будет рассказано в сле
дующем разделе.
- Д л я вычисление новых координат шарика добавьте метод
New Coord.
void T B a l l : : N ew Coord()
{
double x x , y y ;
xx |
= |
x |
+ |
c o s ( a l f a ) * d ; |
yy |
= |
у |
+ |
s i n ( a l f a ) * d ; |
if |
( (xx<=r) |
| | |
(x x + r> = F o rm l-> C lie n tW id th ) ) |
if |
a l f a = M _ P I - a lf a ; |
||
((yy<=r) |
|| |
(y y + r> = F o rm l- > C lie n tH e ig h t) ) |
|
a l f a = - a l f a ; |
|
x |
+= |
c o s ( a l f a ) * d ; |
у |
+= |
s i n ( a l f a ) * d ; |
}
- Самостоятельно разберитесь с работой метода NewCoord.
-Самостоятельно напишите дружественную функцию D is t для определения расстояния между шариками.
- Для учета столкновения шариков добавьте дружественную функцию C la s h .
void C la s h (T B a ll &Ы, |
T B a ll &b2) |
||
{ |
|
|
|
double c; |
|
|
|
if |
( D i s t ( b l , |
b2) < |
b l . r + b 2 . r ) |
{ |
= b l . a l f a ; |
|
|
c |
|
||
b l . a l f a = b 2 . a l f a ; |
|||
b 2 . a l f a = |
c ; |
|
|
b l .NewCoord(); |
|
b 2 .NewCoord() ;
}
}
-Самостоятельно разберитесь с работой метода Clash.
-Добавьте необходимые команды препроцессора.
На этом создание нового класса закончено.
8.2.3.Создание анимации
Переходим уже непосредственно к моделированию броунов ского движения.
-Поместите на форму компонент TTimer. Измените значе
ние свойства Interval на 10.
- Объявите в файле реализации модуля глобальные перемен
ные.
T B a ll |
* b a l l ; |
int n ; |
/ / К оличество шариков |
- Создайте обработчик события OnCreate формы.
void __fastcall T F o rm l: : F o rm C r e a te (T O b je c t * S en d er)
{
/ / Все |
шарики |
имеют одинаковые р ад и у с и ск о р о сть |
|
int |
г , |
d ; |
|
int |
i, j; |
|
|
double |
x , у , |
a l f a ; |
|
T C o lo r |
C l; |
|
|
T B a ll |
c ; |
|
r a n d o m i z e ( ) ; |
|
|
|
||||
n |
= |
2 0; |
|
|
|
|
|
d |
= |
1; |
|
|
|
|
|
r |
= |
10; |
|
|
|
|
|
b a l l |
|
= new T B a l l [ n ] ; |
|
|
|
||
i |
= |
0; |
|
|
|
|
|
while |
(i< n ) |
|
|
|
|||
{ |
x = r |
+ r a n d o m ( C lie n tW id th - 2 *r) |
+ 2; |
||||
|
|||||||
|
у = r |
+ r a n d o m ( C lie n tH e ig h t - 2 * r ) |
+ 2; |
||||
|
a l f a |
= 2*M __PI*random(1001)/1 0 0 0 ; |
|
||||
|
c l |
|
= |
T C o lor(R G B (random (2 5 6 ), random (256), |
|||
|
|
|
|
ra n d o m ( 2 5 6 ) ) ) ; |
|
|
|
c |
= T B a l l (x, y, a l f a , |
d, |
r, c l ) ; |
|
|||
for |
(j =0 ; j <i; j++) |
|
|
|
|||
|
if |
( D i s t ( c , b a l l [ j ]) <= |
2*r) |
|
|||
|
|
break; |
|
|
|
||
if (j |
==i ) |
|
|
|
|||
|
b a l l [ i + + ] = c ; |
|
|
|
|||
} |
|
|
|
|
= true; |
|
|
F o rm l - > D o u b le B u ff e re d |
|
}
-Самостоятельно разберитесь с работой обработчика собы
тий O n C re a te формы.
- Создайте обработчик события O n P a in t формы.
void __fastcall TForml::FormPaint(TObject *Sender)
{
int i;
Graphics::TBitmap *TheImage = new
Graphics::TBitmap();
TheImage->Height = ClientHeight;
TheImage->Width = ClientWidth;
for (i=0; i<n; i++)
b a l l [i] .D raw (TheIm age) ;
TheImage->Canvas->CopyMode = cmSrcCopy;
Canvas->Draw(0, 0, Thelmage);
T h e I m a g e - > F r e e ( ) ;
}
Рассмотрим назначение объекта T h e lm a g e . В строке
G ra p h ic s :: T B it map *TheImage = new G r a p h ic s :: T B itm apO ;
создается объект T h e lm a g e типа T B itm a p . Каждый раз при воз никновении события O n P a i n t изображение сначала рисуется в объекте T h e lm a g e (в оперативной памяти) и только после этого выводится на экран:
Thelm age ->C anvas->C opyM ode = cmSrcCopy;
C a n v a s - > D ra w (0 / 0, T h e lm a g e );
Метод |
F r e e |
освобождает память, |
выделенную объекту |
||||
T h e lm a g e . |
|
|
|
|
|
||
-Создайте обработчик события |
O n T im e r |
компонента |
|||||
T T im e r . |
|
|
|
|
|
|
|
void __fastcall |
T F o rm l: : T im e r lT im e r ( T O b je c t |
* S en d er) |
|||||
{ |
|
|
|
|
|
|
|
double |
x , |
y , |
a l ; |
|
|
||
int |
i , |
j |
; |
|
|
|
|
for |
(i =0; |
i < n ; i ++) |
|
|
|||
b a l l |
[i] |
.New CoordO ; |
|
|
|||
for |
(i =0; |
i < n - 1; i ++) |
|
|
|||
for |
( j = i +l ; |
j < n ; j++) |
|
|
|||
C l a s h ( b a l l [ i ] , b a l l [j ] ) ; |
|
|
|||||
I n v a l i d a t e ( ) ; |
|
|
|
}
- Самостоятельно разберитесь с работой обработчика собы
тия O nT im er компонента T T im er.
- Создайте обработчик события O nC lose формы.
v o i d __ f a s t c a l l T F o rm l: : F orm C lose(T O bject ♦Sender, T C lo s e A c tio n &Action)
{
d e l e t e b a l l ;
}
-Запустите приложение и проверьте правильность его работы.
8.3.Анимация графика
Вэтом примере для рисования графика будем использовать компонент T P a in tB o x .
-Начните новый проект.
- |
Поместите компоненты T T im er и T P ain tB o x . |
- |
Объявите в файле реализации модуля глобальные перемен |
ные.
d o u b le |
xm in |
= |
0, |
xmax = 6, xmx, dx; |
|||
d o u b le |
ym in |
= |
- 1 , |
ушах |
= 1; |
||
i n t |
nx |
= |
6, |
ny |
= |
4; |
|
i n t |
cx |
= |
0, |
cy |
= |
1; |
|
i n t |
x l , |
|
y l , |
x 2, y2, mx, |
my; |
- Самостоятельно измените методы TextOutXY и G rid .
- В |
файле реализации модуля |
формы определите метод |
|
G rap h . |
|
|
|
v o i d __ f a s t c a l l T F o rm l: : G r a p h () |
|
||
{ |
|
|
|
i n t |
i , |
X, Y; |
|
d o u b le h x, h y, x , y ; |
|
||
P a in tB o x l- > C a n v a s - > P e n - > W id th = 1; |
|||
P a in tB o x l - > C a n v a s - > P e n - > C o lo r |
= clR ed ; |
||
hx = |
m x /(x m a x - x m in ); |
|
hy = m y /(y m a x - y m in );
Y = y l + ( y m a x - s in ( x m in ) ) * h y ;
P a in tB o x l - > C a n v a s - > M o v e T o (x l, Y ) ; for (x=xm in; x<=xmx; x+=dx)
{
у = s i n ( x ) ;
X= x l+ ( x - x m in ) * h x ;
Y= y l+ ( y m a x - y ) * h y ;
P a in tB o x l - > C a n v a s - > L in e T o (X , Y ) ;
}
}
- Что изменилось в этой функции?
-Самостоятельно напишите обработчик события O n P a in t
компонента T P a in tB o x .
- Создайте обработчик события O n C re a te формы.
void __f a s t c a l l T F o rm l: : F o rm C r e a te (T O b je c t * S en d er)
{
xmx |
= |
xm in; |
|
dx |
= |
(x m ax - x m in )/ 1 0 0 ; |
|
F o r m l - > D o u b le B u ff e re d = t r u e ; |
|
||
} |
|
|
|
- Создайте обработчик события O nTim er |
компонента |
||
T T im e r. |
|
||
void __fastcall T F o rm l: :T im e r lT im e r ( T O b je c t |
* S en d er) |
{
xmx += d x ;
if (xmx>xmax) xmx = xm in; I n v a l i d a t e ( ) ;
}
- Запустите приложение и проверьте правильность его работы. -Д обавьте на форму три кнопки T B u tto n , назовите их
П уск, П ау за и Стоп и обеспечьте их функциональность в соот ветствии с названием.