Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

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

Hasonló előadás


Az előadások a következő témára: "Ismétlés (Grafikai lehetőségek WPF-ben) Visual utódok"— Előadás másolata:

1 Ismétlés (Grafikai lehetőségek WPF-ben) Visual utódok
Programozás III. Ismétlés (Grafikai lehetőségek WPF-ben) Visual utódok

2 Grafikai lehetőségek WPF-ben
A grafikai keretrendszerek között azonosítunk azonnali és visszatartott módúakat Retained (visszatartott) mód: A grafikai primitívekből (vonalak, alakzatok…) készített jelenetet valamilyen formában a memóriában tartja, minden frame rajzolásánál a tárolt modell alapján keletkeznek a rajzolási parancsok. Az alkalmazás alakzatokat adhat hozzá vagy vehet el. Immediate (azonnali) mód: A keretrendszer nem tárolja a jelenetet, minden frame rajzolásánál az alkalmazás közvetlenül adja ki a rajzolási parancsokat. Az összes kirajzolandó dolog számon tartása az alkalmazás feladata. A WPF visszatartott módú grafikai rendszert biztosít Immediate mode: GDI/GDI+, Direct2D, Direct3D Retained mode: WPF, Direct3D (3.0 után megszüntették a retained mode-ot)

3 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ú (néhány 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 1000 objektumig) Visual objektumok (System.Windows.Media.Visual) Legbonyolultabb, leggyorsabb (max néhány objektumig) XAML lehetőségek korlátozottak, mindig kódból kezeljük

4 Visual Ahhoz biztosít szolgáltatásokat, hogy a leszármazott típus renderelhető legyen DrawingVisual (2D), Viewport3DVisual (3D) kifejezetten rajzoláshoz De minden ablakra rajzolódó objektum is Visual utód VisualChildrenCount, GetVisualChild() – rajzolódáskor a vizuális fát ezekkel követi végig a WPF Többféleképpen használják alacsony szintű rajzolásra GUI-elemben újabb Visualok tárolása (VisualChildrenCount, GetVisualChild() override, esetleg AddVisualChild() hívás) GUI elem kirajzolódásakor végrehajtandó plusz rajzolási parancsok definálása (OnRender() override) Eddigi cuccaink is ezt használták belül. Rectangle, Ellipse: ők is Visualok. Image+DrawingImage: az Image is (mint minden Uielement) – viszont itt a benne kirajzolt dolgok már alacsonyabb szinten (mint Drawingok) definiálódnak Ez most egy még alacsonyabb szint. A megjelenő UIElementben a kirajzolt dolgok már csak mint grafikai parancsok lesznek megadva (ez a 2. variációra vonatkozik).

5 DrawingContext A DrawingContext segítségével „tölthetünk fel” egy Visualt kirajzolandó tartalommal Nem azonnali rajzolás (retained mode) A Visualon belül Drawingok formájában vannak tárolva a rajzok (DrawingGroupban) A rajzolás időpontját a rendszer dönti el Pl. a következő függvények értelmezettek rajta: DrawEllipse() DrawRectangle() DrawGeometry() DrawImage() … The DrawingContext allows you to populate a Visual with visual content. When you use a DrawingContext object's draw commands, you are actually storing a set of render data that will later be used by the graphics you are not drawing to the screen in real-time. DrawingGroup.Open and DrawingVisual.RenderOpen. Ezekkel lehet DrawingContextet nyerni. A Visual describes its content as one or more Drawing objects contained within a DrawingGroup

6 Visual használat 1. variáció példa
public 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; AddVisualChild(), AddLogicalChild() – vizuális/logikai fához adja, események és találattesztelés támogatása miatt

7 Visual használat 2. variáció
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); } UIElement-ben az OnRender() felülírásával a rajzoló rendszer által még végrehajtandó grafikai parancsokat adhatjuk ki Nem azonnali rajzolás (retained mode) Új rajzolás mindig kikényszeríthető az InvalidateVisual() függvénnyel

8 FrameworkElement szabályok
Üres (nem rajzolt) területre nem lehet MouseDown eseményt elkapni Megoldás: a legelső rajzolt objektum egy nagy háttér-téglalap legyen Billentyűzet esemény nem rendelhető hozzá Megoldás1: az ablakhoz viszont rendelhető, a tartalmazó ablak referenciáját elérjük a Window.GetWindow(this) segítségével Megoldás2: Focusable=true és fókuszálni kell a FrameworkElement-et, ekkor a billentyűeseményt is megkapja

9 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 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 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 Feladat – Flappy Birds Turbo

13 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 Feladat – Asteroids

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


Letölteni ppt "Ismétlés (Grafikai lehetőségek WPF-ben) Visual utódok"

Hasonló előadás


Google Hirdetések