Limbajul C++ si oop abc-doar


realizarea de efecte de animatie este TImageList,definit in "imagelst.h"



Yüklə 1,36 Mb.
səhifə14/18
tarix12.09.2018
ölçüsü1,36 Mb.
#81721
1   ...   10   11   12   13   14   15   16   17   18

realizarea de efecte de animatie este TImageList,definit in "imagelst.h".

EXEMPLU: (vezi si OWL_ABC / owl26 ) Editati fila .cpp astfel:

#include

#include

#include

#define IDB_BITMAP1 1

#define IDB_BITMAP2 2

class Fer1 : Fer1();

~Fer1();

void Paint(TDC& dc,bool erase,Trect& rect);

TSize s1,s2;

TInageList* Imagine1;

TImageList* Imagine2; };

Fer1::Fer1():TWindow(0,0,0) {

Attr.X = 20;

Attr.Y = 20;

Attr.W = 480;

Attr.H = 480;

SetBkgndColor(RGB(250,250,220));

s1 = TSize(100,100);

s2 = TSize(10,10);

Imagine1 = new TImageList(s1,true,10,10);

Imagine2 = new TImageList(s2,true,10,10);

TBitmap img(*GetModule(),1);

TBitmap img2(*GetModule(),2);

Imagine1 -> Add(img);

Imagine2 -> Add(img2);

Imagine1 -> SetBkColor(RGB(250,250,250)); };

Fer1::~Fer1()

{ delete Imagine1;

delete Imagine2; };

void Fer1::Paint(TDC& dc,bool,TRect&)

{ Imagine1 -> Draw(0,dc,20,250,ILD_NORMAL);

Imagine2 -> Draw(0,dc,105,300,ILD_NORMAL);sleep(1);

Imagine2 -> Draw(0,dc,150,280,ILD_NORMAL);sleep(1);

Imagine2 -> Draw(0,dc,200,282,ILD_NORMAL);sleep(1);

Imagine2 -> Draw(0,dc,250,300,ILD_NORMAL);sleep(1);

Imagine2 -> Draw(0,dc,300,320,ILD_NORMAL);

MessageBox("SFARSIT","",MB_OK); };

class Aplicatie1 : public TApplication {

public: Aplicatie1() : TApplication() {};

~Aplicatie1(){};

void InitMainWindow(); };

void Aplicatie1 :: InitMainWindow()

{ MainWindow = new TFrameWindow(0,"text",new Fer1,true); };

int OwlMain(int,char* []){ return Aplicatie1().Run(); }
Eliminati din proiect fila .DEF (cu DeleteNode) si apoi editati fila

.rc astfel incat sa contina imaginile BitMap necesare.Puteti copia fila

owl26.rc,sau puteti utiliza o fila noua (cu desenele d-voastra).


-91-

Pentru a edita fila de resurse puteti utiliza orice fila de tip BitMap

(cu extensia .bmp) sau puteti utiliza editorul C++.In acest caz,alegeti

din meniul File optiunea New,apoi Resource Project si apoi Bitmap.Pentru

a specifica dimensiunile desenului si numarul de culori,alegeti la inceput

butonul Options si complectati in caseta de dialog paleta de culori (2,16,

sau 256) si dimensiunile (Width in Pixels: si Height in Pixels).Apoi

confirmati cu OK si din nou cu OK.La nevoie utilizati din meniul principal

optiunea Bitmap pentru a afisa paleta de culori si paleta de obiecte

pentru desenare.Apoi desenati imaginile dorite (la fel ca si in Paint din

Windows).In final,salvati fila cu extensia .bmp (in acelasi director in

care va fi utilizata).Realizati doua astfel de file .bmp.Apoi,pentru a

include cele doua file in fila de resurse .rc,executati in proiectul

dorit un dublu click stg pe fila .rc,apoi executati un click de mouse

drept pe dirctorul afisat (cel cu numele .rc) si alegeti Add to Project.

Dupa ce introduceti cele doua file,executati un dublu click pe fila .rc

si apoi pe semnul plus.Daca totul este corect,folderul .rc va contine:

--owl26.rc

|

- #define: IDB_BITMAP2 <2>

|

- #define: IDB_BITMAP1 <1>

|

- fila1.bmp (folder)

|

- fila2.bmp (folder)

Daca deschideti cele doua foldere si selectati fila BITMAP,in fereastra

din dreapta se va afisa desenul respectiv.Pentru exemplul owl26 am desenat

un tun si un proiectil,dar puteti utiliza orice desene doriti.

In final,compilati si construiti fiecare nod,apoi verificati toate le-

gaturile dintre module (cu LINK) si executati aplicatia.

Observati ca am definit si un destructor pentru fereastra Fer1.Pentru

a elimina cele doua desene,se poate apela direct destructorul.In cazul

in care desenele se vor utiliza in mod repetat,se va apela fie constructo-

rul fie destructorul.Observati ca si obiectul Aplicatie1 are un destructor

distinct.Practic,fiecare modul sau obiect din aplicatie are constructorul

si destructorul sau.Pentru a elimina din proiect doar un anumit modul,sau

doar un anumit obiect,se va apela destructorul respectiv.Pentru a elibera

complet memoria,se va apela destructorul obiectului de tip TApplication.

Deschideti fila si studiati obiectul TImageList.

Obiectul TImageList are opt constructori distincti,astfel incat permite o

gama foarte larga de implementari.Deasemenea,metoda Add() are supraincar-

cate patru variante diferite,astfel incat sa poata adauga imagini BitMap

sau Icon cat mai usor.Pentru desenarea obiectelor exista doua versiuni ale

metodei Draw,iar pentru deplasarea imaginilor contine metodele mecanismu-

lui de tip Drag and Drop (BeginDrag,DragEnter,DragMove,DragLeave,EndDrag).

In exemplul owl26 am utilizat cel mai simplu mecanism posibil.Observati

ca este necesara o procedura speciala pentru definirea contextului de

dispozitiv grafic.Prin conventie,aceasta procedura se denumeste Paint,

pentru a fi cat mai usor de identificat.Se pot adauga algoritmi pentru

deplasarea unuia dintre obiecte(sau a ambelor obiecte).Incercati sa adau-

gati un buton de culisare pentru reglarea tirului.


-92-

Pentru a crea senzatia de deplasare,se utilizeaza o imagine denumita

masca (mask) cu aceleasi dimensiuni,dar colorata in culoarea de fond.Masca

se va suprascrie peste imaginea anterioara,pentru a sterge "urmele".

EXEMPLU: (vezi si OWL_ABC / owl27 ) Editati fila .cpp astfel:

#include

#include

#include

#define IDB_BITMAP1 1

#define IDB_BITMAP2 2

class Fer1 : public TWindow {

public: Fer1();

~Fer1();

void Paint(TDC& dc,bool erase,TRect& rect);

TSize s1,s2;

TImageList* Imagine1; TImageList* Imagine2; };

Fer1::Fer1():TWindow(0,0,0) {

Attr.X = 20;Attr.Y = 20; Attr.W = 480; Attr.H = 480;

s1 = TSize(200,200); s2 = TSize(200,200);

Imagine1 = new TImageList(s1,true,10,10);

Imagine2 = new TImageList(s2,true,10,10);

TBitmap img(*GetModule(),1);

TBitmap img2(*GetModule(),2);

Imagine1 -> Add(img);

Imagine2 -> Add(img2);

Imagine2 ->SetBkColor(RGB(250,250,250)); };

Fer::~Fer1()

{ delete Imagine1;

delete Imagine2; };

void Fer1::Paint(TDC& dc,bool,TRect&)

{ Imagine1->Draw(0,dc,20,200,ILD_NORMAL);sleep(1);

Imagine2->Draw(0,dc,20,200,ILD_NORMAL);

Imagine1->Draw(0,dc,150,150,ILD_NORMAL);sleep(1);

Imagine2->Draw(0,dc,150,150,ILD_NORMAL);

Imagine1->Draw(0,dc,200,100,ILD_NORMAL);sleep(1);

Imagine2->Draw(0,dc,200,100,ILD_NORMAL);

Imagine1->Draw(0,dc,250,50,ILD_NORMAL); };

class Aplicatie1 : public TApplication {

public: Aplicatie1() : TApplication() {};

~Aplicatie1(){};

void InitMainWindow(); };

void Aplicatie1::InitMainWindow()

{ MainWindow = new TFrameWindow(0,"text",new Fer1,true); };

int OwlMain(int,char* []) { return Aplicatie1().Run(); }

Pentru fila .rc utilizati doua imagini de tip .bmp de aceeasi dimen-

siune(200/200),cea de a doua imagine fiind complet goala.

Eliminati fila .def,apoi compilati,construiti si executati obiectul.

Observati ca cea de a doua imagine practic suprascrie prima inagine,dupa

fiecare interval de o secunda.Daca nu se specifica o culoare pentru fond

(cu SetBkColor()),atunci inaginea va fi transparenta.Metoda Draw accepta

si urmatoarele stiluri: ILD_BLEND25,ILD_BLEND50,ILD_TRANSPARENT si eventual

ILD_OVERLAYMASK pentru a determina modul de suprapunere a imaginilor.


-93-

Pentru a putea deplasa imaginea cu ajutorul tastelor,se poate adauga o

metoda specializata de tipul EvKeyDown.

EXEMPLU: (vezi si OWL_ABC / owl28 ) Editati fila .cpp astfel:

#include

#include

#define IDB_BITMAP1 1

#define IDB_BITMAP2 2

int xxx=150;int yyy=150;int xxx1=150;int yyy=150;

class Fer1 : public TWindow {

public: Fer1(); ~Fer1();

void Paint(TDC& dc,bool,erase,TRect& rect);

void EvKeyDown(uint key,uint repeatCount,uint flags);

TSize s1,s2;

TImageList* Imagine1; TImageList* Imagine2;

DECLARE_RESPONSE_TABLE(Fer1); };

DEFINE_RESPONSE_TABLE1(Fer1,TWindow)

EV_WM_KEYDOWN,

END_RESPONSE_TABLE;

Fer1::Fer1(): TWindow(0,0,0) {

Attr.X = 20; Attr.Y = 20; Attr.W = 480; Attr.H = 480;

s1 = TSize(100,100); s2 = TSize(100,100);

Imagine1 = new TImageList(s1,true,10,10);

Imagine2 = new TImageList(s2,true,10,10);

TBitmap img(*GetModule(),1);TBitmap img2(*GetModule(),2);

Imagine1 -> Add(img);Imagine2 -> Add(img2);

Imagine2 -> SetBkColor(RGB(250,250,250)); };

Fer1::~Fer1() { delete Imagine1;delete Imagine2; };

void Fer1::Paint(TDC& dc,bool,Trect&)

{ Imagine1->Draw(0,dc,xxx,yyy,ILD_NORMAL); };

void Fer1::EvKeyDown(uint key,uint,uint)

{ TClientDC dc(*this); switch (key)

{ case VK_UP: xxx1=xxx;yyy1=yyy-50;

Imagine2->Draw(0,dc,xxx,yyy,ILD_NORMAL);

Imagine1->Draw(0,dc,xxx1,yyy1,ILD_NORMAL);break;

case VK_DOWN: xxx1=xxx;yyy1=yyy+50;

Imagine2->Draw(0,dc,xxx,yyy,ILD_NORMAL);

Imagine1->Draw(0,dc,xxx1,yyy1,ILD_NORMAL);break;

case VK_LEFT: xxx1=xxx-50;yyy1=yyy;

Imagine2->Draw(0,dc,xxx,yyy,ILD_NORMAL);

Imagine1->Draw(0,dc,xxx1,yyy1,ILD_NORMAL);break;

case VK_RIGHT: xxx1=xxx+50;yyy1=yyy;

Imagine2->Draw(0,dc,xxx,yyy,ILD_NORMAL);

Imagine1->Draw(0,dc,xxx1,yyy1,ILD_NORMAL);break; };

xxx=xxx1;yyy=yyy1; };

class Aplicatie1 : public TApplication {

public: Aplicatie1() : TApplication() {}; ~Aplicatie1() {};

void InitMainWindow(); };

void Aplicatie1::InitMainWindow()

( MainWindow = new TFrameWindow(0,"text",new Fer1,true); };

int OwlMain(int,char* []) { return Aplicatie1().Run(); }

In timpul executiei,utilizati tastele cu sageti pentru a deplasa imaginea.


-94-

Pentru deplasare,se pot utiliza si metodele "Drag and drop" astfel:

EXEMPLU: (vezi si OWL_ABC / owl29 ) Editati fila .cpp astfel:

#include

#include

#include

#define IDB_BITMAP1 1

int xxx=150;int yyy=350;int xxx1=150;int yyy1=150;

class Fer1 : public TWindow {

public: Fer1(); ~Fer1();

void Paint(TDC& dc,bool erase,TRect& rect);

void EvRButtonDown(uint,TPoint&);

TSize s1;

TImageList* Imagine1;

DECLARE_RESPONSE_TABLE(Fer1); };

DEFINE_RESPONSE_TABLE1(Fer1,TWindow)

EV_WM_RBUTTONDOWN,

END_RESPONSE_TABLE;

Fer1::Fer1():TWindow(0,0,0) {

Attr.X =20; Attr.Y = 20; Attr.W = 480; Attr.H = 480;

s1 = TSize(100,100);

Imagine1 = new TImageList(s1,true,10,10);

TBitMap img(*GetModule(),1);

Imagine1 -> Add(img); };

Fer1::~Fer1() { delete Imagine1; };

void Fer1::Paint(TDC& dc,bool,Trect&)

{ Imagine1 -> Draw(o,dc,xxx,yyy,ILD_NORMAL); };

void Fer1::EvRButtonDown(uint,TPoint&)

{ TClientDC dc(*this); xxx1=xxx;yyy1=yyy-50;

ShowCursor(FALSE);SetCapture();UpdateWindow();

Imagine1->SetDragCursorImage(0,0,0);

Imagine1->BeginDrag(0,0,0);

Imagine1->DragEnter(*this,xxx,yyy);

Imagine1->DragMove(xxx1,yyy1);sleep(2);

Imagine1->DragLeave(*this);Imagine1->EndDrag();

ReleaseCapture();ShowCursor(TRUE);xxx=xxx1;yyy=yyy1; };

class Aplicatie1 : public TApplication {

public: Aplicatie1() : TApplication() {};

~Aplicatie1(){};

void InitMainWindow(); };

void Aplicatie1::InitMainWindow()

{ MainWindow = new TFrameWindow(0,"text",new Fer1,true); };

int OwlMain(int,char* []){ return Aplicatie1().Run(); }

Compilati,construiti si executati exercitiul.La fiecare click de mouse

cu butonul drept,imaginea va fi deplasata timp de 2 secunde.La fiecare

click saltul va fi din ce in ce mai mare,deoarece se acumuleaza difernta

din variabila yyy1.

In acest exemplu,am utilizat evenimentul RButtonDown,dar se poate uti-

liza orice alt eveniment Windows.In multe situatii,metodele DRAG AND DROP

pot fi impartite in mai multe proceduri,astfel incat la apasarea butonului

sa se efectueze selectia imaginii,iar la eliberarea butonului sa se faca

deplasarea si operatiile de stergere pentru imaginea anterioara.


-95-

Pentru a aplica metodele DRAG AND DROP,este necesar ca imaginea sa fie

stocata temporar intr-un tampon de memorie.In acest exemplu,si in multe

alte situatii,s-a utilizat tamopnul de memorie destinat cursorului.Pentru

acest scop,cursorul a fost invalidat temporar (observati ca in timpul ope-

ratiei de DRAG cursorul dispare) iar imaginea a fost stocata temporar cu

SetDragCursorImage().Dupa epuizarea operatiilor,cursorul trebuie reactivat

cu ShowCursor(True).Acest gen de implementare este foarte avantajos,pentru

ca nu necesita alocarea de memorie suplimentara,dar prezinta si un mic

inconvenient.In situatiile in care aplicatia se blocheaza in timpul unei

operatii de DRAG,cursorul este invalidat si aplicatia nu poate fi depanata

sau actualizata.Singura solutie este oprirea si repornirea calculatorului.

Operatiile de grafica animata nu ridica probleme atunci cand se lucreza

cu o singura imagine grafica.Pe masura ce se utilizeaza tot mai multe

obiecte si imagini grafice,memoria de operare devine din ce in ce mai

incarcata iar la un anumit moment dat,incep sa apara suprascrieri.Din

acest motiv,trebuie tinuta o evidenta foarte stricta a operatiilor efec-

tuate si o gestiune/operatie a memoriei consumate.Obiectele care nu mai

sunt necesare de loc,vor fi eliberate complet apeland destructorul,iar

cele care urmeaza sa fie utilizate din nou,vor fi doar inactivate temporar

sau vor fi pur si simplu suprascrise (sterse prin suprapunerea unui alt

obiect grafic).Este bine sa lasati o marja de siguranta,astfel incat dupa

ce calculati toate operatiile ce urmeaza sa fie executate,sa mai ramana

inca suficient loc in memoria de operare si pentru restul variabilelor,

pentru gestiunea proceselor,pentru expandarea unor obiecte sau baze de

date etc.Nu va lansati la operatii foarte complexe.Este bine sa verificati

pas cu pas,fiecare operatie introdusa in program.Dupa fiecare etapa rezol-

vata,efectuati o copie de siguranta a proiectului,astfel incat sa puteti

reveni cat mai usor la o atapa anterioara de dezvoltare.Uneori,de la un

anumit punct,se vor putea ramifica mai multe variante,dintre care urmeaza

sa alegeti varianta cea mai buna,in functie de evolutia ulterioara a

proceselor (este greu de anticipat care va fi solutia cea mai buna).

Pentru programele si aplicatiile mari,este bine lucrati modular.Fiecare

astfel de modul,va fi mult mai usor de depanat,dar mai ales,va putea fi

utilizat in mai multe programe.In timp,prin cumularea acestor module,pro-

gramarea unei aplicatii noi va fi asemenatoare cu un joc de "puzzle" in

care nu trebuie decat sa alegeti piesele de care aveti nevoie pentru a

realiza tabloul complet.

Dupa adaugarea fiecarui modul,compilati,executati si eventual depanati

programul.Daca adaugati mai multe module dintr-un singur pas,va fi mult

mai greu de verificat legaturile si eventualele situatii de supraincarcare

a unor identifcatori sau definitii.Verificati cu atentie fiecare modul.

Chiar daca modulul functioneaza perfect in alta aplicatie,este posibil ca

in programul d-voastra sa nu functioneze,sau sa functioneze incorect.De

obicei este o problema legata de "mediul de operare".Cu alte cuvinte,in

spatiul de vizibilitate comuna exista doi sau mai multi identificatori

"supraincarcati",sau pur si simplu exista mai multe obiecte care exploa-

teaza competitiv aceleasi mesaje Windows,aceleasi tampoane de memorie sau

aceiasi registri de procesor.Prin adaugarea succesiva a modulelor,ope-

ratiile de verificare si control vor fi mult mai usor de realizat.

Dupa ce programul merge "perfect",rugati un cunoscut sau un coleg sa-l

verifice.In multe cazuri va descoperii "lacune" la care nu v-ati gandit.


-96-

Pentru a repeta unele operatii la intervale mai mici de o secunda,se

pot utiliza cronometrele.In OWL,cronometrul este inclus in fereastra de

tip TWindow cu ajutorul functiei SetTimer (urmata de KillTimer).

EXEMPLU: (vezi si OWL_ABC /owl30 ) Editati fila .cpp astfel:

#include

#include

#define IDB_BITMAP1 1

#define IDB_BITMAP2 2

int xxx=150;int yyy=350;int xxx1=150;int yyy1=150;

class Fer1: public TWindow {

public: Fer1();~Fer1();

void Paint(TDC& dc,bool erase,TRect& rect);

void EvTimer(uint id);

TSize s1,s2;

TImageList* Imagine1;TImageList* Imagine2;

DECLARE_RESPONSE_TABLE(Fer1);

DEFINE_RESPONSE_TABLE1(Fer1,TWindow)

EV_WM_TIMER,

END_RESPONSE_TABLE;

Fer1::Fer1():TWindow(0,0,0) {

Attr.X = 20;Attr.Y = 20;Attr.W = 480;Attr.H = 480;

s1 = TSize(100,100); s2 = TSize(100,100);

Imagine1 = new TImageList(s1,true,10,10);

Imagine2 = new TImageList(s2,true,10,10);

TBitmap img(*GetModule(),1); TBitmap img2(*GetModule(),2);

Imagine1 -> Add(img); Imagine2 -> Add(img2);

Imagine2 -> SetBkColor(RGB(250,250,250)); };

Fer1::~Fer1() { delete Imagine1; delete Imagine2;KillTimer(1); };

void Fer1::Paint(TDC& dc,bool,TRect&)

{ Imagine1 -> Draw(0,dc,xxx,yyy,ILD_NORMAL);

SetTimer( 1,50); };

void Fer1::EvTimer(uint)

{ TClientDC dc(*this);

xxx1=xxx;yyy1=yyy-1;

Imagine2 ->Draw(0,dc,xxx,yyy,ILD_NORMAL);

Imagine1 ->Draw(0,dc,xxx1,yyy1,ILD_NORMAL);

xxx=xxx1;yyy=yyy1; };

class Aplicatie1 : public TApplication {

public: Aplicatie1() : TApplication() {};

~Aplicatie1(){};

void InitMainWindow(); };

void Aplicatie1::InitMainWindow()

{ MainWindow = new TFrameWindow(0,"text",new Fer1,true); };

int OwlMain(int,char* []){ return Aplicatie1().Run(); }

Compilati,construiti si executati.Functia KillTimer() a fost amplasata in

destructorul ferestrei Fer1,astfel incat operatiile incluse in procedura

EvTimer se vor repeta atat timp cat fereastra este deschisa (desenul se

va deplasa in sus,la fiecare 50 de milisecunde.Fiecare "timer" are un

numar de ordine,astfel incat sa se poata utiliza simultan mai multe crono-

metre.Atentie la destructori.Orice cronometru neinchis va executa operatii

in fundal,pana la inchiderea calculatorului(consuma memoria de RAM).


-97-

In Win32 nu se pot utiliza simultan mai mult de 32 de cronometre,dar

in sistemele mai mari(Millenium,XP etc.) numarul de cronometre poate fi

mai mare(64-256 in functie de tipul partitiei).Cronometrele se pot utiliza

si pentru procese cu executie multifilara (fiecare cronometru controleaza

Yüklə 1,36 Mb.

Dostları ilə paylaş:
1   ...   10   11   12   13   14   15   16   17   18




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin