Pascal II. 01. Eljárások, függv... 01. Gyakorló feladatok 02. Felsorolt típus, ... 02. Gyakorló feladatok 03. Állományok kezelése 03. Gyakorló feladatok 04. Unitok, CRT unit 04. Gyakorló feladatok 05. DOS unit, rendezé... 05. Gyakorló feladatok 06. Rekurzió, quicksort 06. Gyakorló feladatok 07. Backtracking 07. Gyakorló feladatok 08. GRAPH unit 08. Gyakorló feladatok 09. Kép mozgatása 09. Gyakorló feladatok 10. Winmouse unit 10. Gyakorló feladatok 11. Dinamikus adatsze... 11. Gyakorló feladatok 12. Dinamikus adatsze... 12. Gyakorló feladatok 13. Dinamikus adatsze... 13. Gyakorló feladatok
|
Programozás 2 (Pascal)
9 Kép mozgatása
-
pointer típus
-
getmem, freemem eljárások
-
getimage, putimage eljárások
-
kép másolása
- kép mozgatása a kurzorbillentyűk segítségével
9.1 Pointer típus
A pointer (mutató) típusú változó
egy olyan változó, amely egy memóriacímre
mutat. A pointer típusnak lefoglalt memória mérete
mindössze 4 byte, ez a 4 byte tartalmazza azt a
memóriacímet, ahová a pointer mutat.
9.2 Getmem, freemem eljárások
A programunkban lefoglalhatunk a memóriából
egy tetszőleges méretű szabad területet,
használhatjuk azt, majd később felszabadíthatjuk.
A memória lefoglalását a getmem parancs segítségével végezhetjük el. Például:
getmem(p,1024);
A fenti példa segítségével
lefoglahatunk a memóriából 1024 bájtot
(tehát 1 kB-ot). Ezt a méretet adjuk meg a getmem második
paraméterében. Az első paraméter egy pointer
típusú változó - a getmem ebbe a pointerbe állítja
be a lefoglalt terület elejének a
memóriacímét (tehát a
példánkban az 1024 bájtnyi terület
elejét). Így ennek a pointernek a
segítségével tudunk majd a lefoglalt
területre hivatkozni és dolgozni vele.
Amikor már nincs szükségünk a
lefoglalt területre, illik azt felszabadítani, hogy ne
maradjon lefoglalva a programunk futása után is. A
memória felszabadítását a freemem paracs segítségével végezhetjük el. Pédául:
freemem(p,1024);
A freemem parancs első paramétereként meg
kell adnunk egy pointer típusú változót,
amely a lefoglalt terület elejére mutat. Második
paraméterként megadjuk, hogy attól a
memóriacímtől kezdődően, ahová a pointer mutat,
mennyi bájtnyi területet szeretnénk
felszabadítani. Ügyeljünk arra, hogy ez ugyanannyi
legyen, mint amennyit lefoglaltunk!
9.3 Getimage, putimage eljárások
A getimage és putimage parancsok
segítségével a grafikus képernyőn levő
ábra egy részét (vagy akár az
egészet) átmásolhatjuk a memóriába,
majd visszahelyezhetjük a grafikus képernyőre. Ahhoz, hogy
ezt megtehessük először le kell foglalnuk
számára a szükséges memóriát a
getmem parancs segítségével. Egy kép
másolása tehát a következő fő
lépésekből fog állni:
- Memória lefoglalása a kép mentéséhez. Ehhez szükséges egy pointer (p)
ami a lefoglalt terület elejére mutat. Azt, hogy
mennyi memóriaterületre van szükségünk,
attól függ, mekkora képet szeretnénk a
memóriában tárolni. Szerencsére a
kép méretéből a szükséges
memóriaterület kiszámítására
létezik a pascalban egy függvény: imagesize.
Ennek a függvénynek négy paramétere van, az
első kettő az elmentendő kép (téglalap) bal felső
sarkának a koordinátái, a második kettő
pedig a jobb alsó sarkának koordinátái. Ha
tehát el szeretnénk menteni a memóriába a
grafikus képernyő 10,10,160,160 részét
(tehát egy 150x150-es négyzetnyi területet), akkor a
memóriát a következő paranccsal foglalhatjuk le neki:
getmem(p,imagesize(10,10,160,160));
- Ezek után a képet elmenthetjük a memóriába a p pointertől kezdődően az alábbi parancs segítségével:
getimage(10,10,160,160,p^);
Itt az első négy paraméter a kép
koordinátáit adja meg (bal felső, jobb alsó
sarok). Az ötödik paraméter az a terület a
memóriában, ahová a képet szeretnénk
menteni. Itt megfigyelhetjük, hogy nem p-t, hanem p^-t adtunk meg. Ez azért van, mert a p az maga a pointer, a p^
viszont már az a memóriaterület, ahová a
pointer mutat. Mi most a képet arra a területre akarjuk
menteni, ahová a pointer mutat (ennek mérete pontosan
akkora mint a kép mérete - imagesize(10,10,160,160)),
nem arra a memóriaterületre, ahol a pointer van a
memóriában (ennek ugyanis a területe csupán 4
bájt - a lefoglalt terület
memóriacímét tartalmazza - ide a 4 bájtnyi
helyre nem is férne be).
- A
memóriából a képet a grafikus
képernyőre visszarakhatjuk bármennyiszer a következő
parancs segítségével:
putimage(200,10,p^,copyput);
Az első két paraméter adja meg a kép bal felső
koordinátáját. Ebben az esetben tehát a
kép a 200,10 koordinátától kezdődően lesz
kirakva a képernyőre. A harmadik paraméter a
memória azon területét jelöli, ahol a
képünk van (hasonlóan a getimage-hoz). A negyedik
paraméter pedig a kirajzolás módját
jelöli. Ez utóbbinak főleg akkor van látszatja a képernyőn, ha a
kirakandó kép alatt már van valamilyen rajz. A mi esetünkben a copyput
egyszerűen a már képernyőn levő rajz fölé teszi a mi rajzunkat úgy, hogy az
alatta levő rajz eltűnik. A copyput helyett
kipróbálhatjuk még az orput, andput, xorput,
notput konstansokat is.
- Miután
már nincs szükségünk a lefoglalt
memóriára, a program végén illik azt
felszabadítani:
freemem(p,imagesize(10,10,160,160));
9.4 Kép másolása
Az alábbi példa kirajzol egy mosolygós fejet a
képernyőre, majd azt az előbb említett parancsok
segítségével lemásolja 12-szer a
képernyőre.
program Pelda29;
uses graph, wincrt;
var gd,gm,i,j: integer;
p:pointer;
begin
{ grafika inicializalasa }
gd := d4bit;
gm := m640x480;
initgraph(gd,gm,'');
{ rajzolas }
setcolor(brown);
circle(50,50,40);
setfillstyle(SolidFill,yellow);
floodfill(50,20,brown);
circle(40,50,10);
circle(60,50,10);
setfillstyle(SolidFill,white);
floodfill(40,45,brown);
floodfill(60,45,brown);
setcolor(black);
circle(40,53,5);
circle(60,53,5);
setfillstyle(SolidFill,black);
floodfill(40,53,black);
floodfill(60,53,black);
setcolor(red);
arc(50,50,210,330,30);
{ memoria lefoglalasa }
getmem(p,imagesize(0,0,100,100));
{ kep megjegyzese }
getimage(0,0,100,100,p^);
{ kep kirajzolasa 12-szer }
for i:=1 to 4 do
for j:=1 to 3 do
putimage(i*100,j*100,p^,copyput);
{ memoria felszabaditasa }
freemem(p,imagesize(0,0,100,100));
{ varakozas gombnyomasra }
readkey;
{ grafikus mod bezarasa }
closegraph;
end.
9.5 Kép mozgatása a kurzorbillentyűk segítségével
A következő példa szintén kirajzolja a
mosolygós fejet, de azt most mindig csak a megadott X,Y
koordinátákra rajzolja ki, ami attól függően
fog változni, hogy melyik kurzorbillentyűt (nyilat) nyomtuk meg.
Így tehát úgy fog tűnni, mintha a fejet a
kurzorbillentyűk segítségével mozgatnánk a
képernyőn.
program
Pelda30;
uses graph, wincrt;
var gd,gm,i,j: integer;
p:pointer;
x,y:integer;
ch:char;
begin
x := 0;
y := 0;
{ grafika inicializalasa }
gd := d4bit;
gm := m640x480;
initgraph(gd,gm,'');
{ rajzolas }
setcolor(brown);
circle(50,50,40);
setfillstyle(SolidFill,yellow);
floodfill(50,20,brown);
circle(40,50,10);
circle(60,50,10);
setfillstyle(SolidFill,white);
floodfill(40,45,brown);
floodfill(60,45,brown);
setcolor(black);
circle(40,53,5);
circle(60,53,5);
setfillstyle(SolidFill,black);
floodfill(40,53,black);
floodfill(60,53,black);
setcolor(red);
arc(50,50,210,330,30);
{ memoria lefoglalasa }
getmem(p,imagesize(0,0,100,100));
{ kep megjegyzese }
getimage(0,0,100,100,p^);
{ kep mozgatasa a kurzorbillentyuk segitsegevel }
repeat
ch := readkey;
if ch=#0 then begin
ch := readkey;
case ch of
#72: if y-5>=0 then y:=y-5; {fel}
#80: if y+5<=379 then y:=y+5; {le}
#75: if x-5>=0 then x:=x-5; {balra}
#77: if x+5<=539 then x:=x+5; {jobbra}
end;
putimage(x,y,p^,copyput);
end;
until ch=#27;
{ memoria felszabaditasa }
freemem(p,imagesize(0,0,100,100));
{ grafikus mod bezarasa }
closegraph;
end.
A kurzorbillentyűk megnyomásakor mindig két kódot
kapunk. Először a #0-t, majd a #72, #80, #75, ill. #77-et
attól függően melyik billentyűt nyomtuk meg (fel, le,
balra, jobbra). Ezeket használjuk fel az új
koordináták
kiszámításához. A
fejet mindig 5
pixellel rakjuk arrébb. Az eredeti képet nem kell
letörölnünk, mivel az
új kép felülrajzolja azt. Az eredeti kép
szélein (5 képpontnyi sáv, amit nem rajzol
felül) csak fekete rész van,
így nem fog az új kép alól kilógni
az előtte kirajzolt kép.
|