Tworzenie animacji
Tematem tego artyku│u bΩdzie tworzenie animacji. Nie
jakiego╢ tam przesuwaj▒cego siΩ tekstu. Naszym celem bΩdzie
stworzenie animacji, kt≤ra sk│ada│a siΩ bΩdzie z kilku bitmapek z│▒czonych
w jedn▒ ca│o╢µ i poruszaj▒cych siΩ - bΩdzie to sprawia│o efekt
animacji. Opr≤cz tego w jednym pliku EXE znajdowaµ siΩ bΩd▒
zasoby w postaci tekstu oraz d╝wiΩk WAV.
Ok zacznijmy wiΩc. Przygotuj sobie katalog do kt≤rego
wrzuµ program brcc32.exe - znajduje siΩ on w katalogu z
Delphim: Delphi\Bin. S│u┐y on do kompilacji zasob≤w z postaci *.rc
do *.res. Do tego┐ katalogu skopiuj tak┐e jaki╢ nied│ugi plik d╝wiΩkowy
WAV. Ja nazwa│em go hover.wav. Odpal teraz Delphi i stw≤rz
nowy projekt. Umie╢µ na formie komponent Panel i zmie± jego
kolor t│a na bia│y. Na Panelu umie╢µ komponent Image i zmie±
jego w│a╢ciwo╢µ Align na alClient - spowoduje to
rozci▒gniΩcie komponentu na ca│y obszar panelu. Umie╢µ dodatkowo
na formularzu komponent Button. Szkielet programu mamy gotowy.
Teraz musisz sobie przygotowaµ serie bitmapek. Ja skorzysta│em z 4
bitmapek, kt≤re po po│▒czeniu sprawiaj▒ efekt poruszania d│oni▒
( macha w Twoj▒ stronΩ :)). Uruchom wiΩc edytor zasob≤w - stw≤rz
nowy zas≤b i w│aduj do niego te bitmapy. Je┐eli nie wiesz jak to
zrobiµ poczytaj artyku│ Zasoby. Zas≤b
zapisz w katalogu z programem pod nazw▒ Files.res. Teraz pora
na w│▒czenie do zasobu d╝wiΩk≤w. Poniewa┐ standardowy edytor
zasob≤w Delphi tego nie umo┐liwia trzeba to zrobiµ rΩcznie.
W katalogu z Twoim programem stw≤rz plik wave.rc. Otw≤rz go
za pomoc▒ Notatnika i wpisz taki tekst:
STRINGTABLE
BEGIN
101, "Cze╢µ!"
102, "Jak siΩ masz?"
END
ID_WAVE WAVE "hover.wav"
ZacznΩ od ko±ca: ostatnia linia informuje o w│▒czeniu
do zasob≤w pliku o nazwie "hover.wav" i podstawienie go pod
nazw▒ "ID_WAVE". Poniewa┐ jest to d╝wiΩk typu WAV musimy
zadeklarowaµ typ pliku, czyli "WAVE". Ok, co robi▒ linie
na samej g≤rze. W│▒czaj▒ one do zasobu dwie linie tekstu. Najpierw
pomiΩdzy liniami BEGIN i END trzeba wpisaµ tzw.,
identyfikator, czyli pod jak▒ nazw▒ Delphi ma rozpoznawaµ liniΩ
tekstu. Najpierw piszemy liczbΩ ( jaka ona bΩdzie? Zale┐y od Ciebie
), a nastΩpnie w cudzys│owie wpisujemy tekst, kt≤ry ma byµ do
zasob≤w w│▒czony. Ufff. Gotowe, zapisz plik. Teraz trzeba go
skompilowaµ. W tym celu musisz u┐yµ kompilatora brcc32.exe. Jest
to program DOS'owy wiΩc musisz go uruchomiµ w okienku MS-DOS. W
DOS'ie do katalogu przechodzi siΩ poprzez polecenie:
cd NazwaKatalogu
Natomiast przechodzenie o jeden katalog wy┐ej umo┐liwia
polecenie:
cd..
Je┐eli ju┐ jeste╢ w katalogu wpisz:
brcc32.exe wave.rc
Spowoduje to utworzenie pliku wave.res. Zasoby
s▒ ju┐ gotowe - teraz pozosta│o wpisywanie kodu.
W sekcji Interface masz s│owo kluczowe var.
Odszukaj je i dodaj zmienn▒:
Done : Boolean; // zmienna informuj▒ca, czy animacja jest w ruchu
Teraz r≤wnie┐ w sekcji Interface dodaj takie linie:
const
BName = 'ID_BITMAP'; // pierwszy cz│on nazwy bitmapek
STRING1 = 101; // warto╢µ pierwszego Stringa umieszczonego w zasobach
STRING2 = 102; // warto╢µ drugiego Stringa umieszczonego w zasobach
PamiΩtasz jak podczas pisania zasobu zadeklarowali╢my dwa
Stringi? Oznaczone one by│y ( posiada│y identyfikatory ) 101 i 102.
W programie zamiast pisaµ warto╢ci cyfrowe mo┐na pisaµ s│owa ( │atwiej
zapamiΩtaµ ) w│a╢nie String1 lub String2. Natomiast
sta│a Bname to pierwszy cz│on nazwy bitmapek. Nie wiem jak ty
nazwa│e╢ swoje bitmapy ale ja nazwa│em je: ID_BITMAP1,
ID_BITMAP2 itd. Po prostu do tej zmiennej dodawane bΩd▒ cyferki
oznaczaj▒ce numery bitmap. Teraz pozosta│o jeszcze napisanie
procedury "ButtonOnClick". Wygeneruj wiΩc procedurΩ
OnClick komponentu Button i wpisz do niej takie tekst:
procedure TMainFrm.Button1Click(Sender: TObject);
var
i : Integer;
Buff: array [0..MAX_PATH] of Char; // ta zmienna musi mieµ taka postaµ
begin
while not (Done) do // Je┐eli zmienna Done = False tzn., ze animacja
// jest uruchomiona
begin
{
PΩtla ta powoduje │adowanie po kolei obrazk≤w z zasob≤w. DziΩki temu
odnosi siΩ wra┐enie animacji. Sta│a "BNAME" okre╢la s│owo "ID_BITMAP" do
kt≤rego dodawane s▒ cyfry oznaczaj▒ce numery bitmapy.
}
for i:=1 to 4 do
begin
Application.ProcessMessages; // daj odetchn▒µ systemowi
Sleep(100); // czekaj 100 milisekund ( 1000 milisekund = 1 sek. )
Image1.Picture.Bitmap.LoadFromResourceName( // za│aduj bitmapΩ
hInstance, BName + IntToStr(i));
end;
{
Poni┐sze polecenia kolejno odgrywaj▒ oraz l▒duj▒ tekst z zasobowa.
Pierwsza funkcja "PlaySound" powoduje za│adowanie z zasob≤w muzyki i
odtworzenie jej.
Druga funkcja │aduje z zasob≤w tekst i przypisuje go do zmiennej
"Buff". NastΩpnie tekst ten wy╢wietlony jest na pasku formy.
"STRING1" to sta│a oznaczaj▒ca cyfrΩ 101. Pod to cyfra kryje siΩ
tekst, kt≤ry ma byµ zlasowany z zasob≤w.
}
PlaySound('ID_WAVE', hInstance, SND_ASYNC or SND_RESOURCE);
LoadString(hInstance, STRING1, Buff, SizeOf(Buff));
Caption := Buff;
Sleep(50); // czekaj 50 milisekund
{
Teraz ta petla odtwarza animacje od tylu tzn., idea jest taka
sama jak w poprzedniej petli tyle ze bitmapy ladowane sa od
tylu.
}
for i:=4 downto 1 do
begin
Application.ProcessMessages;
Sleep(100); // czekaj 100 milisekund
Image1.Picture.Bitmap.LoadFromResourceName( // za│aduj bitmapki
hInstance, BName + IntToStr(i));
end;
{ To samo co wyzej tyle, ze ladowany jest inny tekst.... }
PlaySound('ID_WAVE', hInstance, SND_ASYNC or SND_RESOURCE);
LoadString(hInstance, STRING2, Buff, SizeOf(Buff));
Caption := Buff;
end;
end;
No... nie przera┐aj siΩ. WiΩkszo╢µ tej procedury stanowi▒
komentarze. Ca│o╢µ stanowi jedna pΩtla while w kt≤rej wnΩtrzu
znajduj▒ siΩ dwie pΩtle for. Je┐eli zmienna
"Done" nie przybierze warto╢ci False to animacja
odtwarzana bΩdzie w niesko±czono╢µ :) Aha! Do listy uses dodaj
nazwΩ modu│u MMSystem - to ten modu│ odpowiedzialny jest za
odtwarzanie d╝wiΩk≤w poprzez funkcjΩ PlaySound. W funkcji
tej podawana jest nazwa identyfikatora pod kt≤r▒ kryje siΩ d╝wiΩk.
Ale o dzia│aniu tej funkcji poczytaj artyku│ "D╝wiΩki".
Kolejna linia │aduje z zasob≤w tekst. S│u┐y do tego linia
"LoadString", kt≤ra przypisuje liniΩ z zasob≤w do
zmiennej Buff. NastΩpnie ta zmienna przypisana jest na pasku
stanu formy. Drugi cz│on to kolejna pΩtla, kt≤ra │aduje bitmapy od
ty│u co daje efekt animacji. Na samym ko±cu tak┐e nastΩpuje
za│adownie d╝wiΩku i testu.
Teraz pozostaje jeszcze uzupe│nienie procedury "OnClose"
formy. Zmienia ona warto╢µ zmiennej Done na False co
powoduje zako±czenie animacji.
Done := True; // zako±cz animacje i zamknij program....
Ca│y listing powinien wygl▒daµ tak:
(**********************************************************)
(* Resource Test programme for Delphi 5 *)
(* Copyright © 2001 by Adam Boduch *)
(* All rights reserved *)
(* Build: 17 luty 2001 r. *)
(* E-mail: boduch@poland.com *)
(* SERVICE FOR PROGRAMMERS: *)
(* HTTP://WWW.PROGRAMOWANIE.OF.PL *)
(**********************************************************)
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, MMSystem {modu│ umo┐liwiaj▒cey odtwarzanie muzyki };
{ Oto zasoby zawierajace bitmapki oraz muzyke }
{$R FILES.RES}
{$R WAVE.RES}
type
TMainFrm = class(TForm)
Button1: TButton;
Panel1: TPanel;
Image1: TImage;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MainFrm: TMainFrm;
Done : Boolean; // zmienna informuj▒ca, czy animacja jest w ruchu
const
BName = 'ID_BITMAP'; // pierwszy cz│on nazwy bitmapek
STRING1 = 101; // warto╢µ liczbowa pierwszego Stringa umieszczonego w zasobach
STRING2 = 102; // warto╢µ liczbowa drugiego Stringa umieszczonego w zasobach
implementation
{$R *.DFM}
procedure TMainFrm.Button1Click(Sender: TObject);
var
i : Integer;
Buff: array [0..MAX_PATH] of Char; // ta zmienna musi mieµ taka postaµ...
begin
while not (Done) do // Je┐eli zmienna Done = False tzn., ze animacja
//jest uruchomiona
begin
{
Petla ta powoduje ladowanie po kolei obrazkow z zasobow. Dzieki temu
odnosi sie wrazenie animacji. Stala "BNAME" okresla slowo "ID_BITMAP" do
ktorego dodawane sa cyfry oznaczajace numery bitmapy.
}
for i:=1 to 4 do
begin
Application.ProcessMessages; // daj odetchn▒µ systemowi
Sleep(100); // czekaj 100 milisekund ( 1000 milisekund = 1 sek. )
Image1.Picture.Bitmap.LoadFromResourceName( // za│aduj bitmape z zasob≤w
hInstance, BName + IntToStr(i));
end;
{
Ponizsze polecenia kolejno odgrywaja oraz laduja tekst z zasobow.
Pierwsza funkcja "PlaySound" powoduje zaladowanie z zasobow muzyki i
odtworzenie jej.
Druga funkcja laduje z zasobow tekst i przypisuje go do zmiennej
"Buff". Nastepnie tekst ten wyswietlony jest na pasku formy.
"STRING1" to stala oznaczajaca cyfre 101. Pod to cyfra kryje sie
tekst, ktory ma byc zladowany z zasobow.
}
PlaySound('ID_WAVE', hInstance, SND_ASYNC or SND_RESOURCE);
LoadString(hInstance, STRING1, Buff, SizeOf(Buff));
Caption := Buff;
Sleep(50); // czkej 50 milisekund
{
Teraz ta pΩtla odtwarza animacje od tylu tzn., idea jest taka
sama jak w poprzedniej pΩtli tyle ze bitmapy │adowane s▒ od
tylu.
}
for i:=4 downto 1 do
begin
Application.ProcessMessages;
Sleep(100); // czekaj 100 milisekund
Image1.Picture.Bitmap.LoadFromResourceName( // za│aduj bitmapki
hInstance, BName + IntToStr(i));
end;
{ To samo co wyzej tyle, ze ladowany jest inny tekst.... }
PlaySound('ID_WAVE', hInstance, SND_ASYNC or SND_RESOURCE);
LoadString(hInstance, STRING2, Buff, SizeOf(Buff));
Caption := Buff;
end;
end;
procedure TMainFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Done := True; // zako±cz animacje i zamknij program....
end;
end.
Gotowe ╝r≤d│a wraz ze skompilowanym programem mo┐esz ╢ci▒gn▒µ
tutaj:
ResTest.zip ( 150 kB )