Programozás I. 2. gyakorlat Interakció a grafikus felületen, tagfüggvények Surányi Márton PPKE-ITK 2013.02.25. 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
Nem csak rajzolni tudunk, hanem lehet interaktív alkalmazásokat készíteni interakció: (itt) egér, billentyűzet által beavatkozunk a program működésébe a graphics-ben események segítségével tudjuk kezelni ezeket az esemény típusa: event az event egy struct, aminek vannak adattagjai: type keycode pos_x, pos_y button time 1 / 1
event adattagjai, lehetséges értékek type: esemény típusa: ev_key, ev_mouse, ev_timer keycode: billenytűesemény esetén: billentyű azonosítója pos_x, pos_y: egérmozgatás esetén: az egérkurzor pozíciója button: egéresemény (gomb) esetén: egérgomb azonosítója: btn_left, btn_right, btn_middle, btn_wheelup, btn_wheeldown time: időzítőesemény esetén: a program indítása óta eltelt idő millisec-ben 2 / 1
event adattagjai, lehetséges értékek type: esemény típusa: ev_key, ev_mouse, ev_timer keycode: billenytűesemény esetén: billentyű azonosítója pos_x, pos_y: egérmozgatás esetén: az egérkurzor pozíciója button: egéresemény (gomb) esetén: egérgomb azonosítója: btn_left, btn_right, btn_middle, btn_wheelup, btn_wheeldown time: időzítőesemény esetén: a program indítása óta eltelt idő millisec-ben 2 / 1
event adattagjai, lehetséges értékek type: esemény típusa: ev_key, ev_mouse, ev_timer keycode: billenytűesemény esetén: billentyű azonosítója pos_x, pos_y: egérmozgatás esetén: az egérkurzor pozíciója button: egéresemény (gomb) esetén: egérgomb azonosítója: btn_left, btn_right, btn_middle, btn_wheelup, btn_wheeldown time: időzítőesemény esetén: a program indítása óta eltelt idő millisec-ben 2 / 1
event adattagjai, lehetséges értékek type: esemény típusa: ev_key, ev_mouse, ev_timer keycode: billenytűesemény esetén: billentyű azonosítója pos_x, pos_y: egérmozgatás esetén: az egérkurzor pozíciója button: egéresemény (gomb) esetén: egérgomb azonosítója: btn_left, btn_right, btn_middle, btn_wheelup, btn_wheeldown time: időzítőesemény esetén: a program indítása óta eltelt idő millisec-ben 2 / 1
event adattagjai, lehetséges értékek type: esemény típusa: ev_key, ev_mouse, ev_timer keycode: billenytűesemény esetén: billentyű azonosítója pos_x, pos_y: egérmozgatás esetén: az egérkurzor pozíciója button: egéresemény (gomb) esetén: egérgomb azonosítója: btn_left, btn_right, btn_middle, btn_wheelup, btn_wheeldown time: időzítőesemény esetén: a program indítása óta eltelt idő millisec-ben 2 / 1
Eseményciklus Az eseményciklus a grafikus alkalmazás egyik fő ciklusa. Amíg ez a ciklus fut, addig a program képes eseményeket fogadni. 3 / 1
Példa Példa: Bal egérkattintásra változtassuk meg a képernyő hátterének színét egy új, véletlenszerű színre! #include "graphics.hpp" using namespace genv; const int SX = 400; const int SY = 400; int main() { srand(time(0)); gout.open(sx, SY); 4 / 1
} event ev; while(gin >> ev) { if (ev.button == btn_left) { gout << color(rand() % 256, rand() % 256, rand() % 256) << move_to(0,0) << box(sx,sy) << refresh; } } return 0; 5 / 1
Példa: Bal egérkattintásra rajzoljunk ki egy 20x20-as sárga négyzetet az adott egérpozícióba! Az alkalmazás escape-re lépjen ki! #include "graphics.hpp" #include <algorithm> using namespace genv; const int SX = 640; const int SY = 480; int main() { gout.open(640, 480); 6 / 1
event ev; while (gin >> ev) { if (ev.button == btn_left) { gout << move_to(ev.pos_x, ev.pos_y) << color(255,255,0) << box(20,20) << refresh; } else if (ev.keycode == key_escape) { exit(0); } } } return 0; 7 / 1
Fejlesszük tovább: írjunk a doboz rajzolására, illetve a véletlen szín generálására függvényt! Valamint az enter lenyomására mentse el a képet output.bmp néven! #include "graphics.hpp" #include <algorithm> using namespace genv; void draw_box(int x, int y, color c, int size) { gout << move_to(x, y) << c << box(size, size); } color rand_color() { color ret(rand() % 256, rand() % 256, rand() % 256); return ret; } 8 / 1
int main() { gout.open(640, 480); event ev; while (gin >> ev) { if (ev.button == btn_left) { draw_box(ev.pos_x, ev.pos_y, rand_color(), (rand() % 10) + 20); gout << refresh; } else if (ev.keycode == key_escape) { exit(0); } else if (ev.keycode == key_enter) { gout.save("output.bmp"); } } return 0; } 9 / 1
Timer az időzítőt a gin.timer(int ms) függvénnyel tudjuk beállítani, és elindítani Paraméterként millisec-ben kell megadni a periódust, így minden megadott ms-ben generál egy időzítő eseményt kikapcsolni így lehet: gin.timer(0) időzítőesemény esetén az event type mezője az ev_timer értéket veszi föl a time mező pedig az addig eltelt ezredmásodpercek számát 10 / 1
Timer az időzítőt a gin.timer(int ms) függvénnyel tudjuk beállítani, és elindítani Paraméterként millisec-ben kell megadni a periódust, így minden megadott ms-ben generál egy időzítő eseményt kikapcsolni így lehet: gin.timer(0) időzítőesemény esetén az event type mezője az ev_timer értéket veszi föl a time mező pedig az addig eltelt ezredmásodpercek számát 10 / 1
Timer az időzítőt a gin.timer(int ms) függvénnyel tudjuk beállítani, és elindítani Paraméterként millisec-ben kell megadni a periódust, így minden megadott ms-ben generál egy időzítő eseményt kikapcsolni így lehet: gin.timer(0) időzítőesemény esetén az event type mezője az ev_timer értéket veszi föl a time mező pedig az addig eltelt ezredmásodpercek számát 10 / 1
Timer az időzítőt a gin.timer(int ms) függvénnyel tudjuk beállítani, és elindítani Paraméterként millisec-ben kell megadni a periódust, így minden megadott ms-ben generál egy időzítő eseményt kikapcsolni így lehet: gin.timer(0) időzítőesemény esetén az event type mezője az ev_timer értéket veszi föl a time mező pedig az addig eltelt ezredmásodpercek számát 10 / 1
Timer az időzítőt a gin.timer(int ms) függvénnyel tudjuk beállítani, és elindítani Paraméterként millisec-ben kell megadni a periódust, így minden megadott ms-ben generál egy időzítő eseményt kikapcsolni így lehet: gin.timer(0) időzítőesemény esetén az event type mezője az ev_timer értéket veszi föl a time mező pedig az addig eltelt ezredmásodpercek számát 10 / 1
#include "graphics.hpp" #include <algorithm> #include <sstream> using namespace genv; const int SX = 640; const int SY = 480; int main() { gout.open(sx, SY); event ev; gin.timer(100); std::stringstream ss; 11 / 1
} while (gin >> ev) { if (ev.type == ev_timer) { ss << "Eltelt ezredmasodpercek szama: " << ev.time; gout << move_to(0,0) << color(0,0,0) << box(sx,sy); gout << move_to(20,20) << color(255,255,0) << text( ss.str() ) ss.str(""); } else if (ev.keycode == key_escape) { exit(0); } } return 0; 12 / 1
Feladatok 2-1) Random irányba mozogjanak a dobozok! 2-2) Space leütésére változzon meg a színük! 2-3) Ha egy dobozra rákattintunk, tűnjön el! 13 / 1
Tagfüggvények a draw függvény a típushoz tartozik, vagyis egy művelete a Boxnak. A következő lépésben a függvényeket beemeljük tagfüggvénnyé, ezzel egy lépést tettünk a Box típus egységbezárásáért (enkapszuláció) 14 / 1
Tagfüggvények a draw függvény a típushoz tartozik, vagyis egy művelete a Boxnak. A következő lépésben a függvényeket beemeljük tagfüggvénnyé, ezzel egy lépést tettünk a Box típus egységbezárásáért (enkapszuláció) 14 / 1
Tagfüggvények a tagfüggvények úgyanúgy függvények látják, és módosíthatják a struct értékeit, ezért nem kell külön paraméterben átadni őket tagfüggvény hívása: [változónév].[tagfüggvény neve]() 15 / 1
Tagfüggvények a tagfüggvények úgyanúgy függvények látják, és módosíthatják a struct értékeit, ezért nem kell külön paraméterben átadni őket tagfüggvény hívása: [változónév].[tagfüggvény neve]() 15 / 1
Tagfüggvények a tagfüggvények úgyanúgy függvények látják, és módosíthatják a struct értékeit, ezért nem kell külön paraméterben átadni őket tagfüggvény hívása: [változónév].[tagfüggvény neve]() 15 / 1
struct Car { string name; int fuel; // current amount of fuel (liter) double consumption; // liter / 100km void go( int km ) { fuel -= (consumption / 100) * km; } void refuel( int liter ) { fuel += liter; } };... Car c; c.name = "Toyota"; c.fuel = 0; c.consumption = 5.5; c.refuel(10); c.go(2); 16 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor a konstruktor is egy tagfüggvény, ami a példányosításkor (deklaráláskor) fut le ha nem írunk egy struct-nak konstruktort, akkor fordításkor létrejön egy üres (és paraméternélküli) FONTOS! Ha megírunk egy konstruktort, akkor nem jön létre paraméternélküli! pl. az int-nek is van konstruktora: int a(10); Ekkor a kezdőértéke 10 lesz. 17 / 1
Konstruktor példa struct Person { std::string name; int age; Person(std::string name_, int age_) : name(name_), age(age_) {} }; 18 / 1
Konstruktorok FONTOS! A konstruktornak nincs visszatérési értéke (azt sem kell elé írni, hogy void)! neve mindig meg kell, hogy egyezzen a struct nevével! konstruktort nem lehet külön meghívni, a példányosításkor fut le a konstruktor rövidítése: ctor (ha rákerestek így (is) érdemes) 19 / 1
Konstruktorok FONTOS! A konstruktornak nincs visszatérési értéke (azt sem kell elé írni, hogy void)! neve mindig meg kell, hogy egyezzen a struct nevével! konstruktort nem lehet külön meghívni, a példányosításkor fut le a konstruktor rövidítése: ctor (ha rákerestek így (is) érdemes) 19 / 1
Konstruktorok FONTOS! A konstruktornak nincs visszatérési értéke (azt sem kell elé írni, hogy void)! neve mindig meg kell, hogy egyezzen a struct nevével! konstruktort nem lehet külön meghívni, a példányosításkor fut le a konstruktor rövidítése: ctor (ha rákerestek így (is) érdemes) 19 / 1
Feladatok 2-2-a) Hópihe: egy hópihe egy fehér pixel. Legyen 100 darab hópihe, amik konstans sebességgel "esnek" le. Ha alul kimegy, felül jöjjön be! 2-2-b) Jobbra-balra imbolyogjanak a pihék! (ha oldalt kimegy, a másik oldalon jöjjön be!) 2-2-c) Legyen mélysége: a közelebb álló pihék legyenek nagyobbak és gyorsabban hulljanak! 20 / 1
Feladatok (folyt.) 2-3-a) Egy random pozícióba lerakott doboz kövesse az egeret. 2-3-b) Több doboz is legyen, mindegyik az egeret kövesse! 21 / 1
Házi feladat A honlapon elérhető (lesz). 22 / 1