programozás iii

Post on 30-Dec-2015

35 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Programozás III. Ismétlés (Grafikai lehetőségek WPF-ben) Visual utódok. Grafikai lehetőségek WPF-ben. Shape-ek ( System.Windows.Shapes.Shape leszármazottak) Egyszerű, előre elkészített grafikai alakzatok Toolboxban is szerepelnek FrameworkElement utódok: input, fókusz, események… - PowerPoint PPT Presentation

TRANSCRIPT

V 1.0

Programozás III.

Ismétlés (Grafikai lehetőségek WPF-ben)Visual utódok

V 1.0 ÓE-NIK, 2014

Grafikai lehetőségek WPF-ben• Shape-ek (System.Windows.Shapes.Shape

leszármazottak)– Egyszerű, előre elkészített grafikai alakzatok– Toolboxban is szerepelnek– FrameworkElement utódok: input, fókusz, események…– Csak kevés számú (max 100) objektum esetén

• Drawing objektumok (System.Windows.Media.Drawing leszármazottak)– Nincs belső támogatásuk input eseményekhez– Nem képesek maguktól a megjelenésre, hosztoló objektumban

kell őket elhelyezni– Legtöbbször XAML-ból kezeljük– Gyorsabb a Shape-eknél (max néhány 100 objektumig)

• Visual objektumok (System.Windows.Media.Visual)– Legbonyolultabb, leggyorsabb (max kb. 10000 objektumig)– XAML lehetőségek korlátozottak, mindig kódból kezeljük 2

V 1.0 ÓE-NIK, 2014

Visual

• Ahhoz biztosít szolgáltatásokat, hogy a leszármazott típus renderelhető legyen

• Több speciális célú utódosztály: pl. DrawingVisual (2D), Viewport3DVisual (3D)

• Az ezzel való rajzolásnak elsősorban kétféle variációja létezik:– Egy adott grafikusfelület-elem „vizuális gyermekei” (kirajzolandó

objektumok) közé beteszünk újabb Visual objektumokat– Egyedi leszármazott típust definiálunk valamelyik grafikusfelület-

elemből (tipikusan: FrameworkElement), kihasználva, hogy a GUI-elemek maguk is Visual utódok

3

V 1.0 ÓE-NIK, 2014

DrawingVisual• 2D rajzolásra

– RenderOpen() függvényét kell hívni, DrawingContext objektumot ad vissza

• A DrawingContext segítségével „tölthetjük fel” a Visualt (vagy egy DrawingGroupot) tartalommal– Pl. a következő függvények értelmezettek rajta:– DrawEllipse()– DrawRectangle()– DrawGeometry()– DrawImage() …

– A grafikai parancsok igazából nem rajzolnak, hanem csak tárolják/ megadják a kirajzolandó dolgokat (visszatartott módú grafikai rendszer)

– A Visualon belül Drawingok formájában vannak tárolva a rajzok (DrawingGroupban).

– A rajzolás időpontját a rendszer dönti el4

V 1.0 ÓE-NIK, 2014

Visual használat – 1. variáció• Minden Visual utódnak (így a grafikusfelület-elemeknek is)

vannak „vizuális gyermekei” (kirajzolandók)

• Új Visual objektumokat (pl. DrawingVisualokat) kell létrehozni és azokat elhelyezni a „vizuális gyermekek” között

• Kötelező felülírni az új Visualok „tulajdonosában” a VisualChildrenCount, GetVisualChild tulajdonságokat– VisualChildrenCount: adjuk vissza, hogy hány „vizuális gyermek” van.

– GetVisualChild: adjuk vissza az n. „vizuális gyermeket”.

• Lehetséges az új Visual objektumokat az objektumfákban is elhelyezni (AddVisualChild(), AddLogicalChild())– Események és találattesztelés támogatása miatt

5

V 1.0 ÓE-NIK, 2014

Visual használat 1. variáció példapublic partial class MainWindow : Window{ //sokszor nem a MainWindow-ban DrawingVisual visualChild; //csináljuk, hanem egy FrameworkElement public MainWindow() //utódot származtatunk és azt rakjuk { //a MainWindow-ra majd InitializeComponent(); visualChild = new DrawingVisual(); using (DrawingContext context = visualChild.RenderOpen()) { context.DrawEllipse(Brushes.Red, null, new Point(50, 50),10,10); } AddVisualChild(visualChild); AddLogicalChild(visualChild); } protected override int VisualChildrenCount { get { return base.VisualChildrenCount + 1; } } protected override Visual GetVisualChild(int index) { if (index < base.VisualChildrenCount) return base.GetVisualChild(index); else return visualChild; }

6

V 1.0 ÓE-NIK, 2014

Visual használat 2. variáció

• Kihasználjuk, hogy az ablak (vagy bármilyen más GUI elem) is Visual

• Amikor rajzolódik, az OnRender() metódusa hívódik– Ez felülírható, DrawingContext objektumot kap paraméterül, a

DrawingContext-en keresztül tudunk rajzolni a Visualra

• Új rajzolás mindig kikényszeríthető az InvalidateVisual() függvénnyel

class MainWindow : Window //tipikusan ezt sem a MainWindow-ban,{ //hanem pl. FrameworkElement utód... //... //- ablaknál Background=Transparent kell. protected override void OnRender(DrawingContext drawingContext) { drawingContext.DrawGeometry(Brushes.Blue, new Pen(Brushes.Red, 2), geometry); }}

7

V 1.0 ÓE-NIK, 2014

Feladat – Asteroids

8

V 1.0 ÓE-NIK, 2014

• 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.

9

V 1.0 ÓE-NIK, 2014

Transzformációk

• Transform utódokkal reprezentálódnak (transzformációs mátrix)– Forgatás (RotateTransform)– Skálázás (ScaleTransform)– Nyújtás (SkewTransform)– Mozgatás (MoveTransform)– Általános transzformáció (MatrixTransform)– Több transzformáció egymás után (TransformGroup)

10

V 1.0 ÓE-NIK, 2014

Transzformáció alkalmazásai

• GUI-elemeken (FrameworkElement utódok):– LayoutTransform (kihelyezés előtt transzformál)– RenderTransform (kihelyezés után transzformál)

• Geometriákon:– Transform

• Figyelem: nem módosít koordinátákat!– A Transform-ot levéve (xxx.Transform = Transform.Identity) az

eredeti koordinátákon marad az objektum– Metszésnél esetleg gondot okoz

11

V 1.0 ÓE-NIK, 2014

Geometriák metszése (érintésvizsgálat)• Geometriák metsződé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 (GetArea())

• Figyelem: LineGeometry-nak nincs kiterjedése, így a metszet területe 0 – Megoldása a vonal „kiterjesztésével”– geometry.GetWidenedPathGeometry(new Pen(Brushes.Blue, 2))

Geometry intersection = Geometry.Combine(geometry, otherGeometry, GeometryCombineMode.Intersect, null);

return intersection.GetArea() != 0;

12

V 1.0 ÓE-NIK, 2014

Feladat – Flappy Birds Turbo

13

V 1.0 ÓE-NIK, 2014

Megoldási alternatíva

• Minden játékelem Geometry típusú adattagja úgy kerül beállításra, hogy a középpont koordinátája (0;0) legyen

• Kirajzolás/ütközésvizsgálat előtt transzformáljuk a megfelelő pozícióba

TransformGroup tg = new TransformGroup();tg.Children.Add(new TranslateTransform(cx, cy));tg.Children.Add(new RotateTransform(degree, cx, cy));Geometry copy = area.Clone();copy.Transform = tg;return copy.GetFlattenedPathGeometry();

14

V 1.0 ÓE-NIK, 2014

Grafikai lehetőségek WPF-ben

15

Megközelítés Eseménykezelés / rajzolás vezérlése

Használat Objektumok száma

Shape Rajzolt objektumonként külön

XAML + Binding ~100

Drawing Hosztoló objektum kezeli, az összes rajzolt objektumot együtt

XAML + Binding + Converterek (xxx Geometry)

~1000

Visual Hosztoló objektum kezeli, egyedi kirajzoló metódus

CS kód: OnRender + DrawingContext + Geometry

~10000

top related