Pascal I.      Pascal II.      Delphi       Linkek     
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:

  1. 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));
         
  2. 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).
       
  3. 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.
         
  4. 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.

       

(C) 2004-2013, PaedDr. Végh Ladislav, Komárno, Szlovákia