Szoftvertechnolgia s grafikus felhasznli fellet tervezse WPF grafikai

  • Slides: 40
Download presentation
Szoftvertechnológia és grafikus felhasználói felület tervezése WPF grafikai alapok Framework. Element használata 1

Szoftvertechnológia és grafikus felhasználói felület tervezése WPF grafikai alapok Framework. Element használata 1

WPF grafikai alapok – koordináta-rendszer • A WPF-ben használt koordináta-rendszer origója a bal felső

WPF grafikai alapok – koordináta-rendszer • A WPF-ben használt koordináta-rendszer origója a bal felső sarokban van – minden helyzetmegadás a tartalmazó objektum bal felső sarkához képest értendő – Egy objektum helyzetét befolyásolják pl. : Horizontal. Alignment, Margin, Padding, tartalmazó/tartalommenedzser beállításai, … – A fentiekből együtt, ún. Layout (elhelyezési) fázis során áll össze a 2 D pozíciója – nem egyszerűen elérhető és nem (nagyon nehézkesen) állítható! – A Canvas tartalommenedzser támogatja az objektumok adott koordinátákra való elhelyezését 2

WPF grafikai alapok – típusok(System. Windows) • System. Windows névtérben sok egyszerű típus van,

WPF grafikai alapok – típusok(System. Windows) • System. Windows névtérben sok egyszerű típus van, amit főként grafikánál használunk • Nincs megjelenítésük, csak adatreprezentációs célra! • (Struktúrák (érték típusok)) • Point: pont a síkban (2 D) – X, Y • Size: méret – Width, Height • Rect, Int 32 Rect: téglalap a síkban – X, Y, Width, Height, Top, Bottom, Left, Right • Vector: helyvektor a síkban – X, Y, Length. Squared 3

WPF grafikai alapok – színek • Minden színt négy darab 8 bites érték jellemez:

WPF grafikai alapok – színek • Minden színt négy darab 8 bites érték jellemez: • Vörös (R), zöld (G), kék (B) – 0 -255 közötti értékeket vehetnek fel (így összesen 256^3 ≈ 16 millió szín állhat elő). Minél nagyobb a szám, annál nagyobb az adott színkomponens intenzitása. • Alfa – A szín átlátszóságát határozza meg. 0 -255, 0: teljesen átlátszó, 255: teljesen átlátszatlan. • A szín reprezentálására a Color struktúrát használjuk Color color = Colors. Red; Color color = Color. From. Argb(20, 255, 0, 0); 4

WPF grafikai alapok – ecsetek • Forrás: http: //i. msdn. microsoft. com/dynimg/IC 107818. jpg

WPF grafikai alapok – ecsetek • Forrás: http: //i. msdn. microsoft. com/dynimg/IC 107818. jpg 5

WPF grafikai alapok – ecsetek • C# megadás: //előre elkészített ecset: button. Background =

WPF grafikai alapok – ecsetek • C# megadás: //előre elkészített ecset: button. Background = Brushes. Red; //saját ecset előre elkészített színnel: button. Background = new Solid. Color. Brush(Colors. Aqua); //saját ecset saját színnel: Color almost. Red = Color. From. Argb(20, 255, 0, 0); button. Background = new Solid. Color. Brush(almost. Red); • XAML megadás: <Button Background="Alice. Blue" Content="Button". . . /> <Button Background="#FFFF 0000" Content="Button 2". . . /> <Grid. Resources> <Solid. Color. Brush x: Key="kedvenc. Szinem" Color="Azure"/> </Grid. Resources>. . . <Button Background="{Static. Resource kedvenc. Szinem}"></Button> 6

WPF grafikai alapok –Egyéb típusok • Pen – Toll: vonalhúzás – Kitöltés (brush), vastagság,

WPF grafikai alapok –Egyéb típusok • Pen – Toll: vonalhúzás – Kitöltés (brush), vastagság, vonalstílus, vonalvég • Geometry – Tetszőleges geometriai alakzat (absztrakt osztály) – A leszármazottak a lényegesek – System. Windows. Rect vs System. Windows. Media. Rectangle. Geometry vs System. Windows. Shapes. Rectangle – Univerzális geometriai műveletek, akár nagyon összetett geometriai alakzatokkal is (pl. betűből is lehet geometriát csinálni, metszet/unió, spline, etc…) • Drawing – Pen + Brush + Geometry 7

Egyéb geometry-k • Stream. Geometry = sokszögek • Path. Geometry = komplex vonalak halmaza

Egyéb geometry-k • Stream. Geometry = sokszögek • Path. Geometry = komplex vonalak halmaza – Szövegből a Formatted. Text. Build. Geometry(xxx) metódussal • Több Geometry összefogása egy Geometry. Groupba – A Geometry. Group önmaga is Geometry, így tudunk több komponensből álló geometriákat csinálni Ellipse. Geometry ellipszis = new Ellipse. Geometry(new Point(10, 10), 10); Formatted. Text text = new Formatted. Text("Ez itt az ellipszisem. ", Culture. Info. Current. Culture, Flow. Direction. Left. To. Right, new Typeface("Tahoma"), 16, Brushes. Black); Geometry text. Geometry = text. Build. Geometry(new Point(10, 20)); Geometry. Group group = new Geometry. Group(); group. Children. Add(ellipszis); group. Children. Add(text. Geometry); geometry. Drawing. Geometry = group; 8

Képmegjelenítő UI-elem: Image • Image. Source: megjelenített kép – System. Windows. Media. Image. Source

Képmegjelenítő UI-elem: Image • Image. Source: megjelenített kép – System. Windows. Media. Image. Source osztály utódai használhatók • Image. Stretch automatikusan méretez (None, Fill, Uniform. To. Fill) Bitmap. Source (+utódok) Drawing. Image D 3 DImage abcdef 9

Grafikai lehetőségek WPF-ben • Shape-ek (System. Windows. Shape leszármazottak) – Előre elkészített, egyszerű vezérlők

Grafikai lehetőségek WPF-ben • Shape-ek (System. Windows. Shape leszármazottak) – Előre elkészített, egyszerű vezérlők – Toolboxban is szerepelnek (Rectangle, Ellipse. . . ) – Input, fókusz, események, adatkötés kezelése objektumonként… – Csak kevés számú (max ~100) objektum esetén • Drawing objektumok (System. Windows. Media. Drawing leszármazottak) – Nem képesek maguktól a megjelenésre, hosztoló objektumban kell őket elhelyezni ( Image. Source = new Drawing. Image(xxx) ) – Nincs belső támogatásuk input eseményekhez, a hosztoló objektum kezeli a saját eseményeit – XAML-ből, kevés adatkötéssel és converterrel is kezelhető – Gyorsabb a Shape-eknél (max ~1000 objektum) • Visual objektumok (System. Windows. Media. Visual) – Legbonyolultabb, leggyorsabb (max ~10000 rajzolt objektum) – Rajzolt objektum nem kell memóriában tárolni szinte semmit – Mindig kódból kezeljük nehéz szép kódot írni! 10

Grafikai lehetőségek WPF-ben Megközelítés Eseménykezelés / rajzolás vezérlése Használat Objektumok száma Shape Rajzolt objektum

Grafikai lehetőségek WPF-ben Megközelítés Eseménykezelés / rajzolás vezérlése Használat Objektumok száma Shape Rajzolt objektum = vezérlő; vezérlőnként külön XAML + Binding ~100 Drawing Hosztoló objektum (kép) kezeli az összes rajzolt objektumot együtt XAML + Binding ~1000 + Converterek (xxx Drawing) Visual Hosztoló objektum kezeli, egyedi kirajzoló metódus, rajzolt felület használata „rajzlap”-ként CS kód: ~10000 On. Render + Drawing. Context + Geometry 11

Visual használat class Main. Window : Window // ablaknál Background=Transparent kell { protected override

Visual használat class Main. Window : Window // ablaknál Background=Transparent kell { protected override void On. Render(Drawing. Context drawing. Context) { drawing. Context. Draw. Geometry(Brushes. Blue, new Pen(Brushes. Red, 2), geometry); } } • Tipikusan ezt nem a Main. Window-ban , hanem egyedi Framework. Element utódban használjuk – Az On. Render() felülírásával a rajzoló rendszer által még végrehajtandó grafikai parancsokat adhatjuk ki – Drawing. Context rajzlap, amire rajzolunk – Nem azonnali rajzolás (retained mode) • Új rajzolás mindig kikényszeríthető az Invalidate. Visual() függvénnyel Ezt render-en belül SOHA NEM SZABAD meghívni 12

Framework. Element szabályok • Üres (nem rajzolt) területen nem lehet egér-eseményt elkapni – A

Framework. Element szabályok • Üres (nem rajzolt) területen nem lehet egér-eseményt elkapni – A legelső rajzolt objektum legyen egy nagy háttér-téglalap • Billentyűzet-esemény nem rendelhető hozzá – Az ablakhoz viszont igen, a tartalmazó ablak referenciáját pedig elérjük a Window. Get. Window(this) segítségével (nem elegáns, de ebben a félévben nekünk ez megfelelő) – VAGY: Focusable=true és a vezérlő a billentyű-eseményeket is megkapja (ha épp rajta van a keyboard focus!) • Törekedjünk a szépen rétegzett használatára – Nagyon könnyű rosszul karbantartható kódot írni hozzá – Cél: Game. Model + Logic + Control – View. Modelt nem használunk most… • Gyakorló feladatok: a prezentáció végén 13

GUI-elem többszálú kezelése • Windows-os grafikusfelület-elemekhez általában nem lehet hozzányúlni, csak a létrehozó szálról

GUI-elem többszálú kezelése • Windows-os grafikusfelület-elemekhez általában nem lehet hozzányúlni, csak a létrehozó szálról (GUI szál) – Még közvetve sem – Kevés kivétel (néhány függvény, Property. Changed esemény) • Általános megoldás: Invoke – Visszahívás kérése a GUI száltól (Blokkoló! Deadlock veszély!) Dispatcher. Invoke(() => { label. Content =. . . ; list. Box. Items. Add(. . . ); }); • Task segítségével: alternatív Task scheduler – Default: Thread Pool Task Scheduler – Megoldható, hogy az új taskot a GUI-szál ütemezőjére rakjuk 14

GUI-elem többszálú kezelése • GUI task ütemező – Referencia „megszerzése” a GUI szálján –

GUI-elem többszálú kezelése • GUI task ütemező – Referencia „megszerzése” a GUI szálján – Task. Scheduler. From. Current. Synchronization. Context() Task<int> task. With. Return. Value = Task. Run(() => { Thread. Sleep(1000); return 6; }); task. With. Return. Value. Continue. With( t => text. Box 1. Text = "Result: " + t. Result, Cancellation. Token. None, Task. Continuation. Options. Only. On. Ran. To. Completion, Task. Scheduler. From. Current. Synchronization. Context()); 15

System. Windows. Threading. Dispatcher. Timer • Műveletek adott időközönkénti végrehajtására használjuk (Game. Logic, automata

System. Windows. Threading. Dispatcher. Timer • Műveletek adott időközönkénti végrehajtására használjuk (Game. Logic, automata akciók) – Interval: tulajdonság, amelynek segítségével megadhatjuk, hogy a timer milyen gyakran jelezzen (Time. Span típusú) – Start(), Stop(): Függvények elindításra, leállításra – Tick: Esemény, ami jelzi, hogy a megadott időtartam letelt (a jelzéssel együtt az időtartam mérése újraindul) • Sok más Timer típus van – ne keverjük! – – System. Timers. Timer Szálbiztos, nagyon pontos System. Threading. Timer Külön Threadpool szálon, nem szálbiztos System. Windows. Forms. Timer Windows forms komponens System. Web. UI. Timer Periodikus webpage postback (szinkron/aszinkron) – System. Windows. Threading. Dispatcher. Timer WPF Szálbiztos, Dispatcher. Thread-en futó timer 16

Órai Feladat: Pong 17

Órai Feladat: Pong 17

Flappy Bird 18

Flappy Bird 18

Transzformációk • Transform utódokkal reprezentálódnak (transzformációs mátrix) – Forgatás (Rotate. Transform) – Skálázás (Scale.

Transzformációk • Transform utódokkal reprezentálódnak (transzformációs mátrix) – Forgatás (Rotate. Transform) – Skálázás (Scale. Transform) – Nyújtás (Skew. Transform) – Mozgatás (Translate. Transform) – Általános transzformáció (Matrix. Transform) – Több transzformáció egymás után (Transform. Group) 19

Transzformációalkalmazása • Framework. Element + Layout manager (Grid, Stack. Panel…) – Layout. Transform (kihelyezés

Transzformációalkalmazása • Framework. Element + Layout manager (Grid, Stack. Panel…) – Layout. Transform (kihelyezés előtt transzformál) – Render. Transform (kihelyezés után transzformál) • Geometry – Geometry geo = new Rectangle. Geometry(xxx); – geo. Transform = new xxx. Transform(xxx); – Figyelem: nem módosítja az eredeti geometry koordinátákat – Geometry result = geo. Get. Flattened. Path. Geometry() – Transzformáció törlése: geo. Transform = Transform. Identity; • Drawing. Context – Drawing. Context. Push. Transform(new Translate. Transform(xxx)); – Drawing. Context. Draw. XXX(xxx); – Drawing. Context. Pop(); 20

Transzformációalkalmazása (a játékainkban) • Minden játékelem Geometry típusú adattagja úgy is beállítható, hogy a

Transzformációalkalmazása (a játékainkban) • Minden játékelem Geometry típusú adattagja úgy is beállítható, hogy a középpont koordinátája (0; 0) legyen • Ekkor kirajzolás/ütközésvizsgálat előtt transzformálnunk kell a megfelelő pozícióba/irányba • Lassabb (a folyamatos újraszámolás miatt), de sokkal könnyebbé teszi a modellezést / programozást 21

Geometriák metszése (érintésvizsgálat) • Geometriák metszésének vizsgálatához az elmetszéssel létrejött új geometriát létre kell

Geometriák metszése (érintésvizsgálat) • Geometriák metszésének vizsgálatához az elmetszéssel létrejött új geometriát létre kell hozni (Geometry. Combine()), majd a területét vizsgálni (Get. Area ()) Geometry intersection = Geometry. Combine(geometry, other. Geometry, Geometry. Combine. Mode. Intersect, null); return intersection. Get. Area() != 0; • Figyelem: Line. Geometry-nak nincs kiterjedése, így a metszet területe 0 – Megoldása a vonal „kiterjesztésével” – Geometry result = geometry. Get. Widened. Path. Geometry(new Pen(Brushes. Blue, 2)) – A toll színe nem használt, csak a vonalstílus/vastagság 22

Órai Feladat: Flappy Birds Turbo 23

Órai Feladat: Flappy Birds Turbo 23

Class Bird : Game. Item 24

Class Bird : Game. Item 24

Class Pipe : Game. Item 25

Class Pipe : Game. Item 25

Órai Feladat: Laby the Ultimate Labyrinth 26

Órai Feladat: Laby the Ultimate Labyrinth 26

Single-responsibility classes • Az eddigi megoldások kombinálása ÉS – Erőforrások (egyéb file-ok) kapcsolása (ne

Single-responsibility classes • Az eddigi megoldások kombinálása ÉS – Erőforrások (egyéb file-ok) kapcsolása (ne vigyük túlzásba!) – Képek betöltése: BMP/PNG/JPG Image. Brush – Tiled Brush: fal kirajzolása, Tile vs Pixel koordináták – Hatékonyabb render folyamat • Builder Design Pattern • Image. Brush mentése Dictionary-be • Drawing (Brush + Pen + Geometry) elmentése változóba – Egérkattintás csak rajzolt területen működik nagy háttérkép – Billentyűzet feliratkozás a tulajdonos ablak Key. Down eseményére – Game. Control frissítése • Game. Control alapú (timer/keydown) • Game. Logic alapú (amikor a logic eseménnyel kéri) 27

Tiled brush? 28

Tiled brush? 28

Saját vezérlő létrehozása • XAML-ből mindegyik ugyanúgy használható – Nulla paraméteres konstruktor kötelező •

Saját vezérlő létrehozása • XAML-ből mindegyik ugyanúgy használható – Nulla paraméteres konstruktor kötelező • Örökléssel: Framework. Element ősből – Minden eddigi játék igazából saját vezérlő volt – Ugyanilyen szabályokkal az ablakot nem kitöltő, a layout-ban normálisan elhelyezkedő/használható vezérlő is készíthető – Ablak-eseményre feliratkozás / Message. Box nem javasolt • Örökléssel: Tetszőleges vezérlő ősből – Meglévő vezérlő kibővítése extra funkciókkal • Kompozícióval: User control – Meglévő vezérlőkből új vezérlő összeállítása – A Logical tree-n egyetlen vezérlőként látszódik – Pl. Numeric. Up. Down = Text. Box + Button 29

Tulajdonságok elérése XAML-ből • Tulajdonságok / események a szokásos módon használhatóak – <local: Up.

Tulajdonságok elérése XAML-ből • Tulajdonságok / események a szokásos módon használhatóak – <local: Up. Down. Control Is. Down="True" Is. Down. Changed="Up. Down. Control_Is. Down. Changed„ • Adatkötés: Is. Down="{Binding Path=Points. Down}" – Az adatkötés NEM egyszerű tulajdonsággal működik – Dependency Property-ket használ – Úgy kell elképzelni, ha pl. egy bool típusú Dependency property egy globális tárolóban lenne tárolva: public static Dictionary<Up. Down. Control, bool> Is. Down. Property public bool Is. Down { get { return Is. Down. Property[this]; } set { Is. Down. Property[this] = value; } } 30

Dependency Property public static readonly Dependency. Property Is. Down. Property = Dependency. Property. Register(xxx);

Dependency Property public static readonly Dependency. Property Is. Down. Property = Dependency. Property. Register(xxx); public bool Is. Down { get { return (bool)Get. Value(Is. Down. Property); } set { Set. Value(Is. Down. Property, value); } } Dependency. Property. Register( nameof(Is. Down), typeof(bool), typeof(Up. Down. Control), new Framework. Property. Metadata() { Binds. Two. Way. By. Default = true } ); 31

Órai feladat: Up. Down. Control + Sorted. LB 32

Órai feladat: Up. Down. Control + Sorted. LB 32

Szoftvertechnológia és grafikus felhasználói felület tervezése Gyakorló feladatok 33

Szoftvertechnológia és grafikus felhasználói felület tervezése Gyakorló feladatok 33

Otthoni gyakorlás: Simple. Laby 34

Otthoni gyakorlás: Simple. Laby 34

Otthoni gyakorlás: Simple. Laby • Ha a játékos végzett az adott pályával, automatikusan töltődjön

Otthoni gyakorlás: Simple. Laby • Ha a játékos végzett az adott pályával, automatikusan töltődjön be egy másik • Minden pályánál mérjük az időt, ami alatt megoldja a játékos (System. Diagnostics. Stopwatch osztály) • Lehessen megjeleníteni a pályák megoldási idejét (Geometry. Drawinggal rajzolt) grafikonon egy új ablakban 35

Otthon gyakorlás: Asteroids 36

Otthon gyakorlás: Asteroids 36

Otthon gyakorlás: Asteroids • Asteroids szabályok: – Játékos csak foroghat és lőhet. – Az

Otthon gyakorlás: Asteroids • Asteroids szabályok: – Játékos csak foroghat és lőhet. – Az aszteroida véletlenszerű irányba egyenletesen mozog, ha a képernyő szélére ér, visszatér a másik oldalon – Ha a játékos lövése eltalál egy aszteroidát, az eltűnik. (Nehezebb verzió: két kisebb és gyorsabban mozgó részre válik szét, egy bizonyos mérethatárig. ) – Ha a játékos lövése a képernyő szélére ér, visszatér a másik oldalon. Viszont a lövés csak bizonyos ideig „él”, egy idő után eltűnik. 37

Otthoni gyakorlás: Chaos Frogger 38

Otthoni gyakorlás: Chaos Frogger 38

Otthoni gyakorlás: Chaos Frogger • Az akadályok vagy oldalirányba, vagy fel-le mozognak. Ha elérnek

Otthoni gyakorlás: Chaos Frogger • Az akadályok vagy oldalirányba, vagy fel-le mozognak. Ha elérnek a pálya szélére, ott visszafordulnak. • A sebességük véletlenszerűen változik • Vannak speciális akadályok, amik felgyorsítanak, ha a játékos a közelükben van • A játékosnak három élete van kezdetben, és a jobb alsó sarokban található célig kell eljutnia. Ha hozzáér egy akadályhoz, elveszít egy életet. 39

Otthoni gyakorlás: Tic Tac Toe – Szabályok: A játékosok felváltva teszik le a jelöléseiket.

Otthoni gyakorlás: Tic Tac Toe – Szabályok: A játékosok felváltva teszik le a jelöléseiket. Amelyiküknek előbb összegyűlik 3 jelölése vízszintesen, függőlegesen vagy átlósan, az győz. – Ha betelik a pálya anélkül, hogy 3 összegyűlne bármelyik játékosnak, akkor egyikük sem győzött. 40