Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno OOP - objekty zasahujúce mimo?

Mal by som praktickú otázku ohľadne OOP. Prerábam jednu hru, čo som kedysi napísal v Turbo Pascale do C#. Jedná sa o klasiku, húsenica, známa v zjednodušenej forme na starých Nokiách a v zložitejšej forme ako Wurmi. Samozrejme, moja prerábka bola najlepšia. ;-) Ale k veci:

Červík Wurmi by mal vystupovať ako samostatný objekt, čo sa implementácie pohybu týka. Obsahuje teda:
- informáciu o umiestnení tela pre každý článok
- začiatok a koniec tela
- smer

Do toho chcem implementovať metódy na posuv červíka. Lenže, ak má byť tento objekt samostatný, tak z neho nemôžem odkazovať na kreslenie hracej plochy. Musel by som teda v obsluhe červíka implementovať posuv interne až potom po použití v programe urobiť krok červíka a následne ručne volať metódu kreslenia. Nebolo by teda lepšie implementovať kreslenie červíka do jeho objektu priamo a na kresliace metódy vytvoriť delegátov, ktorí budú volaní v objekte červíka a bude v nich adresa rutín pre kreslenie požičaná z hlavnej obslužnej rutiny? Tým pádom bude objekt samostatný a prehľadný.

Chcem sa teda spýtať, aké riešenie sa v takýchto prípadoch používa najčastejšie? Je aj nejaká výhodnejšia tretia možnosť? (V zmysle, čo je najvhodnejšie urobiť.)

Ono je plno seriálov o OOP, len všade sa používajú jednoduché príklady, kde takéto veci nie je nutné riešiť.

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
Hlavně necpi to vykreslování do červíka, ten by vůbec o nějakém vykreslovaní neměl nic vědět... Čím…
MaSo 25.06.2009 22:13
MaSo
Kľudne môže byť vykresľovanie aj v červíkovi. Koľko pohľadov na červíka potrebuješ? Mne by stačil je…
los 25.06.2009 23:21
los
Vykresľovanie bude v objekte, ktorý sa predá červíkovi v konštruktorovi, čiže, ak bude plátno väčšie…
msx. 25.06.2009 23:39
msx.
Předáš mu objekt, který umožňuje vykreslení. Ale ten objekt zase nic neví o červovi. Takže ten objek…
Jan Fiala 26.06.2009 00:18
Jan Fiala
Áno, všetko súhlasím. Ale ide o to, že s plátnom bude previazané pole, kde budú uložené hodnoty, čo… nový
msx. 26.06.2009 08:09
msx.
Tiez suhlasim s tym, ze cervik nema nic spolocne s vykreslovanim... ten sa ma starat sam o seba... m… nový
Intex 26.06.2009 08:01
Intex
Neviem, nakoľko máš naštudované OOP, ale mám pocit, že si úplne preskočil analýzu a návrh a ideš imp…
los 25.06.2009 23:47
los
Kreslenie bude v v objekte hracia plocha. Ak budem chcieť zmeniť kreslenie na iné, tak zmením tento… nový
msx. 26.06.2009 08:15
msx.
Takže mám to takto: Objektu záhrada odovzdám objekt PictureBox, kam má kresliť. V tomto objekte sú… poslední
msx. 27.06.2009 23:44
msx.

Hlavně necpi to vykreslování do červíka, ten by vůbec o nějakém vykreslovaní neměl nic vědět... Čím obecněji napíšeš třídu/y červíka, tím více reusenutelná ta třída bude, pohledů pak na ni může být třeba milion různých.

Viz návrhový vzor MVC.

Vykresľovanie bude v objekte, ktorý sa predá červíkovi v konštruktorovi, čiže, ak bude plátno väčšie alebo objekty iné, tak červíka to vôbec nemusí zaujímať, lebo bude volať metódy kreslenia v predanom objekte. V objekte bude plátno a pole, v ktorom bude uložené, čo sa na plátne nachádza. Červík bude úplne samostatný objekt, ktorý bude len využívať iné objekty. Tak ako napríklad formulár vo Windows Forms aplikáciách obsahuje iné objekty, tak aj červík bude obsahovať objekt na kreslenie. Prípadné kreslenie v aplikácii nebude nutné, lebo červík si nakreslí všetko potrebné. Ak náhodou bude treba niečo predsa len kresliť (skôr už nejaké efekty a tak, tak si ich cez ten objekt, ktorý sa odovzdal červíkovi vykreslí aplikácia sama, pretože odkaz na objekt bude vlastniť aj ona.

Doplnené: V skratke teda: Miesto plátna sa dá červíkovi objekt, ktorý obsahuje aj plátno, ale okrem neho ďalšie pre červíka podstatné informácie.

Předáš mu objekt, který umožňuje vykreslení. Ale ten objekt zase nic neví o červovi. Takže ten objekt na kreslení sám o sobě nic nevykreslí, pouze obsahuje nějaké obecné metody, které červ na kreslení použije a bude vlastně červ vykreslovat.
Aby mohla aplikace vykreslit červa, musela by o něm něco vědět a v tomto případě by se ti to hodně komplikovalo...

Plátno jako takové je objekt, který už potřebné metody obsahuje. Takže předáním plátna červovi mu současně předávám i systémové nastroje na vykreslení. Červ nebude sám o sobě nic kreslit (nebudeš programovat kreslení úseček), ale použije pro kreslení metody plátna.
Možná v tomto bodě jsme si nerozuměli.

Áno, všetko súhlasím. Ale ide o to, že s plátnom bude previazané pole, kde budú uložené hodnoty, čo sa na plátne nachádza. Toto bude v tom objekte a preto sa červovi neodovzdá plátno, ale celý objekt. V tom objekte budú rovno aj metódy na prepočet. V prípade druhé červa v hre sa druhému odovzdá ten istý objekt a keďže bude objekt v pamäti ten istý, tak druhému červovi sa na objekte všetko bude meniť tak ako bude treba. Ide o to, že ak to bude len plátno, tak červík nebude vedieť čo je na ňom. Ja totiž chcem, aby si hodnoty na plátne pamätal kresliaci objekt. Odovzdaním objektu inému červovi sa takto poskytnú informácie o obsahu plátna aj inému červovi. Ak si bude obsah plátna pamätať červ, tak druhý červ nebude mať ako zistiť čo je na plátne. Preto chcem obsah plátna prenechať objektu kresliaca plocha. Proste zapuzdriť čisto kresliacu plochu.

Tiez suhlasim s tym, ze cervik nema nic spolocne s vykreslovanim... ten sa ma starat sam o seba... ma sa prepocitat, mal by vediet, ktorym smerom ide, ale aby sa mal aj vykreslit mi nepride ako rozumne riesenie... Cervik ako taky by nemusel nic vediet o svojom okoli, aj napriek tomu, ze bude stale iba jeden pohlad...

Neviem, nakoľko máš naštudované OOP, ale mám pocit, že si úplne preskočil analýzu a návrh a ideš implementovať metódy, ktoré ani nevieš umiestniť. Stále sa sústredíš len na červíka a nad ostatnými objektami sa príliš nezamýšľaš.

Najprv by si si mal identifikovať všetky objekty, ktoré v tvojej hre vystupujú, t.j. hracia plocha, červík, prekážka, kapusta a čo ja viem čo ešte. Pre každý tento objekt by si mal potom identifikovať jeho vlastnosti, ako napr. pozícia, a aj metódy, ktoré sa s jednotlivými objektami budú vykonávať.

Čo ti z toho vyjde závisí od toho, čo chceš dosiahnuť. Ak chceš mať napríklad možnosť "jednoducho" vymeniť hraciu plochu, napr. namiesto 2D plochy v okne formulára za nejakú, ktorá sa bude zobrazovať 3D, tak vykresľovanie bude zrejme zabezpečovať hracia plocha. Ak takéto ambície nemáš, tak si vykresľovanie môže robiť každý predmet hracej plochy vo vlastnej réžii.

Tiež si premysli, ako bude vyzerať tvoja herná slučka (game loop) - kedy budeš posúvať červíkov, kedy budeš zisťovať kolízie, kedy budeš získavať vstup z klávesnice, kedy budeš vykresľovať...

K analýze a návrhu tiež patrí aj voľba technológie, ktorú chceš použiť. Bude to GDI, Direct3D, OpenGL, použiješ XNA, alebo niečo iné?

Kreslenie bude v v objekte hracia plocha. Ak budem chcieť zmeniť kreslenie na iné, tak zmením tento objekt a červovi odovzdám iný. Podstatné je, aby vykresľovacia metóda mala rovnaké parametre. Môžem to urobiť dokonca tak, že urobím abstraktnú triedu kresliacej plochy a z nej urobím rôznych potomkov. Podľa toho, akého potomka priradím h hlavnej triede, tak sa bude vykresľovať. A bude to úplne obyčajná grafika cez DrawImage a niekoľkých BMP súborov, ktoré chcem neskôr vložiť do resource, aby neboli mimo EXE súboru.

Takže mám to takto:

Objektu záhrada odovzdám objekt PictureBox, kam má kresliť. V tomto objekte sú implementované všetky metódy na kreslenie a tiež na vytváranie objektov v záhrade. Čiže v programe nepotrebujem vygenerovať súradnice kapusty pri vytváraní záhrady, ale záhrada vygeneruje sama a odovzdá súradnice.

Objektu Wurmi odovzdám objekt záhrada. Kompletný pohyb červíka je implementovaný v ňom. Ak zje kapustu, tam objekt záhrada vygeneruje novú. Ak chce nakresliť články tela, objekt záhrada ich vie vykresliť, keďže kreslenie je v nej. Vytváranie a zanikanie článkov tela je ale implementované v tomto objekte.

Aplikácia vytvorí plátno na PictureBox. Vytvorí objekt záhrada a odovzdá mu už pripravený PictureBox. Aplikácia naaranžuje záhradu, ale príkazy na kreslenie odovzdáva objektu záhrada. Potom vytvorí objekt Wurmi a odovzdá mu objekt záhrada, aby Wurmi vedel, kam patrí. Cez Timer je riadený pohyb červa. Podľa stlačenej klávesy aplikácia odovzdáva objektu Wurmi informáciu o pokuse zmeniť smer. Ak je to možné, objekt Wurmi si ho zmení. Aplikácia si následne od objektu Wurmi vypýta, aký objekt je pred hlavou červa a prikáže mu urobiť krok. Zobrazia sa informácie o dĺžke a času do konca hry. Potom sa otestuje, či pred hlavou červa nebola otrava alebo či neskončil čas. Ak áno, hra končí, inak sa to celé opakuje dokola.

Ak budem chcieť v budúcnosti pridať červa, nebude nič jednoduchšie. Vytvorím len ďalší objekt Wurmi a odovzdám mu rovnaký objekt záhrada a dvaja červi budú v jednej záhrade.

Ďakujem zúčastneným za pomoc.

Zpět do poradny Odpovědět na původní otázku Nahoru