Kreslíme dům

Cvičení

GDI grafika

SSŠVT


Kreslíme dům

Projekt

Založte projekt ve VS na WinForms aplikaci v .NET Framework (C#).


Jak to má celé fungovat

Projekt bude mít pouze jeden formulář, na kterém bude nějaký panel, a na něm nakreslíme celé umělecké dílo - dům se zahradou (s plotem) :-)

Na kreslení použijeme grafickou knihovnu GDI (GDI+), přičemž žádná část nebude "z obrázku" (bitmapa). Vše hezky vektorově, tj. pomocí metod DrawLine, DrawRectangle, DrawEllipse, případně FillRectangle a FillEllipse.

Abychom si připomněli práci s objekty, bude každá část domu reprezentována nějakou třídou, která bude držet jisté grafické vlastnosti té části (rozměry, barvu apod.), bude mít v sobě zapouzdřené "podčásti", ze kterých se skládá, a hlavně: Bude umět se vykreslit. Vykreslí se tak, že napřed vykreslí sama sebe (je-li co pro danou část vykreslovat) a pak zavolá vykreslení svých "podčástí".


Technický popis struktury tříd (dědičnost a asociace)

Celý obrázek bude zapouzdřen do komponenty (části), která reprezentuje celý dům včetně zahrady. Říkejme jí statek nebo nemovitost (anglicky Property).

Nemovitost se skládá ze dvou částí - domu (House) a zahrady, či spíše plotu (Fence).

Dům má opět dvě části: přízemní obytnou část (GroundFloor) a střechu (Roof>). V přízemí jsou dveře (Door) a dvě čtvercová okna (SquareWindow). Střecha má kulaté okno (RoundWindow).

Plot na zahradě se skládá ze svislých kůlů (Pole) a vodorovných latí (Batten).

Kdo by si chtěl věci dobrovolně zesložitit, může dát ještě plot do zahrady (Garden), a teprve tu dát do celé nemovitosti. A na zahradě může být třeba strom (Tree) nebo květiny (Flower). Na střeše může být komín (Chimney), okna mohou mít okenní tabulky (WindowPane). Nechávám na vaší fantazii a času, který do uměleckého díla hodláte investovat.

Nyní ještě schematicky, jak vypadá struktura "zanoření" povinných tříd, které se umějí kreslit jako části domu:

A úplně nakonec: Jelikož čtvercové a kulaté okno mají leccos společného (oboje je "okno"), uděláme ještě jednu třídu (Window) jako jejich společného předka. Takže kromě mnoha asociací typu celek-část si vyzkoušíme i dědičnost.

Příklad zdrojového kódu pro přízemí domu:

public class GroundFloor
{

    public Door Door { get; set; }
    public Point DoorPosition { get; set; }

    public SquareWindow LeftWindow { get; set; }
    public Point LeftWindowPosition { get; set; }

    public SquareWindow RightWindow { get; set; }
    public Point RightWindowPosition { get; set; }

    public int Width { get; set; }
    public int Height { get; set; }
    public Color Color { get; set; }


    public GroundFloor(int width, int height)
    {
        this.Width = width;
        this.Height = height;

        this.Color = Color.Black;

        this.Door = new Door { Height = this.Height / 2, Width = this.Width / 5, Color = Color.Pink };
        this.DoorPosition = new Point(this.Width / 2 - this.Door.Width / 2, this.Height - this.Door.Height);

        this.LeftWindow = new SquareWindow { Size = this.Width / 6, Color = Color.Blue };
        this.LeftWindowPosition = new Point(this.Width / 12, this.Height / 3);

        this.RightWindow = new SquareWindow { Size = this.Width / 6, Color = Color.Blue };
        this.RightWindowPosition = new Point(11 * this.Width / 12 - this.RightWindow.Size, this.Height / 3);
    }


    public void Draw(Graphics g, int left, int top)
    {
        Pen pen = new Pen(this.Color, 2);

        g.DrawRectangle(pen, left, top, this.Width, this.Height);

        pen.Dispose();


        this.Door.Draw(g, left + this.DoorPosition.X, top + this.DoorPosition.Y);
        this.LeftWindow.Draw(g, left + this.LeftWindowPosition.X, top + this.LeftWindowPosition.Y);
        this.RightWindow.Draw(g, left + this.RightWindowPosition.X, top + this.RightWindowPosition.Y);
    }

}
        

Vizuální aspekt

Výsledek by měl vypadat nějak takto (barvičky si vyberte dle libosti a vkusu):

Dům - jednoduchá verze

Pokud chce mít někdo "méně schematický" obrázek, pak třeba:

Dům - vylepšená verze

A pro ty, kdo to mají rádi opravdu "fancy":

Dům - fancy