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

Předmět Autor Datum
Predpokladejme, ze na plose mohou byt i jine objekty nez cerv. Udelal bych zakladni objekt, ktery by…
Jan Fiala 24.06.2009 21:39
Jan Fiala
Všetko súhlasím, s poslednou vetou nie a to práve chcem vyriešiť k ideálu. Ide o to, že pri pohybe…
msx. 24.06.2009 21:55
msx.
Cervik moze kreslit aj len to co potrebuje aj tak ako to chces, ale len do niecoho co dostane ako pa…
MM.. 25.06.2009 01:47
MM..
Právě díky tomu, že červ bude samostatný objekt, jsi schopný jeho vykreslení dotáhnout k ideálu, vyk…
Jan Fiala 25.06.2009 15:43
Jan Fiala
Na MM budem reagovať neskôr, lebo mi napísal toho dosť veľa, tak si to prečítam poriadne, ale k tomu…
msx. 25.06.2009 21:06
msx.
Myslím, že to s tým delegátom je najrozumnejšie riešenie, uvediem príklad na rovnakom princípe: V D…
msx. 24.06.2009 22:19
msx.
Ides na to uplne blbo. Da sa sice urobit vsetko, ale to co popisujes je asi najhorsie co moze byt a…
MM.. 25.06.2009 01:53
MM..
Inac to tvoje tlacitko nevola ziadneho delegata, OnMouseClick je zavolany (funkciou okna) vtedy ked…
MM.. 25.06.2009 02:00
MM..
Z toho opisu vôbec nerozumiem, medzi akými alternatívami sa vlastne rozhoduješ. Jednoducho v metóde…
los 24.06.2009 23:28
los
Tak JaFimu som napísal ako si to predstavujem, tak myslím, že už lepšie porozumieš, druhá alternatív…
msx. 25.06.2009 21:19
msx.
Prekresluje objekt HRACIEPOLE a nie objekt cervik. Objekt cervik ma len metody na zmenu jeho stavu (…
MM.. 25.06.2009 00:57
MM..
Veď práve aj preto sa pýtam, aby som to urobil čo najrozumnejšie, nechcem to robiť hŕ.
msx. 25.06.2009 21:11
msx.
Ale skus najprv rozmyslat (= v hlave skusat rozne "usporiadania" objektov), smerniky na nejake metod…
MM.. 25.06.2009 21:15
MM..
V C# sú delegáty. Doňho vložíš adresu metódy a zavolaním delegáta sa vyvolajú doradu všetky metódy,…
msx. 25.06.2009 21:22
msx.
Jezisikriste oni fakt dali do C# smernik :-) To ale fakt je to posledne co by som v slusnom OOP prog…
MM.. 25.06.2009 21:24
MM..
Aj delegáty majú zmysel, hoci netvrdím, že sa to hodí práve sem. Má to napríklad význam, ak máš jedn…
msx. 25.06.2009 21:34
msx.
Ano ale vytvara to chaos a bordel a jediny zmysel OOP je presne opacny (znizovat chaos a bordel).
MM.. 25.06.2009 21:54
MM..
Ked nechces mat kreslenie v cervikovi, tak ako uz pisal JaFi - mozes mat napr. base-class s metodami…
MM.. 25.06.2009 21:21
MM..
Tak už viem. Vhodnejším riešením by bolo toto: Vytvoriť triedu, ktorá bude zobrazovať na obrazovke…
msx. 25.06.2009 21:43
msx.
To doplnene nerob. Mal by si rozmyslaj aj nad tym ze v buducnosti budes napr. chciet vytvorit 10 obj…
MM.. 25.06.2009 21:58
MM..
Nižšie som napísal, ako by to bolo lepšie spraviť. Dať červíkovi objekt hracia plocha. Pri pridávaní…
msx. 25.06.2009 22:50
msx.
Ano to je trochu problem, ale tie kroky musis podla mna takto: najprv odstranit koniec (ak sa ma ods…
MM.. 25.06.2009 22:55
MM..
V tom problém nevidím, skôr je problém v tom, že keby som dal dvoch červíkov, bol by problém s kkolí…
msx. 25.06.2009 23:34
msx.
Proč vše vymýšlíš naopak? Proč prostě červovi plátno nepředáš? Ať už jako property nebo v konstrukto…
Jan Fiala 25.06.2009 22:18
Jan Fiala
Aby mohlo byť v budúcnosti viac červíkov, nemôžem v konštruktore odovzdať plátno, ale objekt hracia…
msx. 25.06.2009 22:42
msx.
No, to sa sice da (dat objektu aj objekt ktory ho vytvoril), ale narazis na "slucku" pri definovani…
MM.. 25.06.2009 22:53
MM..
Tak, objekt hracia plocha bude fukcionalita kreslenia, červík si cez tento objekt bude kresliť čo tr…
msx. 25.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…
MaSo 25.06.2009 22:13
MaSo
Zrovna pro tento typ aplikace bych MVC nepoužil. Když chceš zatlouct hřebík, vezmeš kladivo. Můžeš t…
Jan Fiala 25.06.2009 23:20
Jan Fiala
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…
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…
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…
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.

Predpokladejme, ze na plose mohou byt i jine objekty nez cerv.
Udelal bych zakladni objekt, ktery by mel metodu pro vykresleni - te bych predal platno, na ktere se kresli.
Cerva bych odvodil od tohoto objektu.
Pak by stacilo projit seznam vsech objektu a zavolat jejich metodu pro vykresleni

Všetko súhlasím, s poslednou vetou nie a to práve chcem vyriešiť k ideálu.

Ide o to, že pri pohybe červa stačí, aby sa mu stratil článok z konca a zobrazil článok na začiatku a pred to hlava. Červík je interne uložený ako FIFO. Čiže ukladajú sa údaje o polohe článku tela a ak niečo zožerie, tak sa z konca nevyberie. Ak narazí do seba, začne sa vyberať až kým hlava nemá voľný priechod. Preto ten delegát, aby červík mohol kresliť sám len to čo práve potrebuje. Rozmýšľam teda zle?

Doplnené: Prekresľovanie všetkého zožerie veľa strojového času, nejde o to, že by to počítač nestihol, ale je to neefektívne vzhľadom na to, ako málo sa bude na plátno kresliť.

Cervik moze kreslit aj len to co potrebuje aj tak ako to chces, ale len do niecoho co dostane ako parameter (bitmapa, pole, apod) od niekoho ineho.

Pod Win sa prekresluje okno (alebo vysek okna) na zaklade vstupu od uzivatela (napr. po obnoveni okna z minimalizacie apod) nezavisle od toho ci sa v programe pohol nejaky cervik. Program kresli na obrazovku LEN vtedy ked na to dostane od Windows "prikaz" (message WM_PAINT). Inac si moze kreslit len do nejakych internych veci v pamati a volat invalidate okna alebo vyseku okna (co vyvola WM_PAINT). Takze musis mat v pamati programu nejaku bitmapu alebo pole na zaklade ktoreho sa da vykreslit vsetko naraz, alebo zavolat metodu "vykresli vsetko" vsetkych objektov ktore nieco vykresluju (to by bolo ale asi najhorsie riesenie). Cervik moze menit nieco, a to nieco dostane od niekoho ineho ako parameter.

Právě díky tomu, že červ bude samostatný objekt, jsi schopný jeho vykreslení dotáhnout k ideálu, vykreslit pouze změny - pohne se a ty vykreslíš nově hlavu a prázné místo po posledním článku.
Červ jako objekt přece ví, na jakých souřadnicích se nachází, kde má souřadnice jednotlivých článků atd.

samozřejmě to můžeš udělat tak, že vykreslení uděláš mimo a červ si bude držet pouze souřadnice, ale pak už to není zapouzdření objektu, protože při změně červa musíš přepisovat nějakou externí metodu na vykreslování.

Na MM budem reagovať neskôr, lebo mi napísal toho dosť veľa, tak si to prečítam poriadne, ale k tomuto len toľkoto:

Kresliaca metóda by mala byť univerzálna a podá sa aj červíkovi, takže nehrozí jej zmena, ak mením červíka, predstavujem si to nejako takto:

vynenovaný typ - hlava, telo, kapusta, jed, ohrada

formulár
  obrázok

  metóda kreslenia do obrázku(x, y, vymenovaný typ)

  objekt červík
    súradnice tela
    dĺžka
    smer
    adresa metódy na kreslenie do obrázku

    metóda na zistenie kde je hlava
    metóda na zistenie dĺžky
    metóda na zistenie konca hry

    metóda na vytvorenie (konštruktor) (suradnice hlavy, adresa metódy na kreslenie)
      
    metóda na krok červíka
      urob krok
      zavolaj kreslenie do obrázku a nakresli krok (x, y, vymenovaný typ)
    koniec
  koniec

  metódy na chod hry

koniec

Takže by to bolo niečo ako nejaké rozhranie (nezamieňať so slovom interface, to má iný význam), cez ktoré by vedel červík vykresliť zmeny.

V metóde na krok červíka by sa skúmali všetky možnosti (narazenie do ohrady, zjedenie kapusty, zjedenie jedu, prechod prázdnym políčkom, zožratie vlastného tela) a podľa toho by sa kreslilo len to čo by bolo treba. Ono by sa to dalo aj úplne zapuzdriť a povedzme, že pri volaní kroku by obsluha dostala pole, kde by boli vyznačené všetky zmeny, ktoré by obsluha len vykreslila, ale toto sa mi zdá trochu pohodlnejšie. Preto ten príklad s volaním OnClick v Delphi, lebo toto by bolo niečo podobné.

Myslím, že to s tým delegátom je najrozumnejšie riešenie, uvediem príklad na rovnakom princípe:

V Delphi je formulár, na ňom tlačítko. Po kliknutí na tlačítko sa má vyvolať nejaká činnosť, lenže tlačítko má len v sebe nadefinované metódy a nevie čo vykonať, tak zavolá delegáta OnMouseClick. Presne toto chcem vlastne urobiť ja. Červík sa bude chcieť prekresliť, pretože dôjde k nejakej udalosti a zavolá delagáta, ktorý vyvolá metódu zvonka a prekreslí určitú časť. Teraz už viem, že na tom idem dobre. Alebo sa predsa len mýlim?

Inac to tvoje tlacitko nevola ziadneho delegata, OnMouseClick je zavolany (funkciou okna) vtedy ked Windows posle fcii okna prislusny message, a Win nema s OOP nic spolocne.
Ked niekto (Delphi apod) ma nahodou aj OOP objekt "tlacitko", tak potom OnMouseClick je metoda toho objektu tlacitko, a nie metoda ziadneho ineho objektu, ani ziaden delegat ani poslanec ani prezident :-)

Z toho opisu vôbec nerozumiem, medzi akými alternatívami sa vlastne rozhoduješ. Jednoducho v metóde pre vykreslenie hracej plochy vykreslíš každého červíka, ktorý sa na tej ploche nachádza. Či už bude kresliaca metóda patriť hracej ploche alebo červíkovi je v tomto prípade prakticky jedno. Neviem si predstaviť, kde tam chceš ešte dostať delegáta a na čo by to bolo dobré.

K náročnosti prekresľovania všetkého - je zbytočné trápiť sa nad rýchlosťou vykreslenia zopár čiar na súčasných počítačoch. Samozrejme len v prípade, že to nevykresľuješ pomocou metódy typu SetPixel. :-D

Tak JaFimu som napísal ako si to predstavujem, tak myslím, že už lepšie porozumieš, druhá alternatíva bola, že bude čisto zapúzdrený a pri kreslení budem zas kontrolovať všetky možnosti a celé to, čo červík vo svojej logike spraví budem prekresľovať s ďalšou logikou odznova.

Prekresluje objekt HRACIEPOLE a nie objekt cervik. Objekt cervik ma len metody na zmenu jeho stavu (pohyb apod). (ked chces mat ten objekt cervik striktne univerzalny).
Alebo mozes urobit metodu cervika ktora dostane ako parameter hracie pole a urobi si s nim co chce (otestuje dalsi krok, zmeni stav policok hracieho pola, resp. "umiestni sa" do hracieho pola apod). Fyzicky vykresluje aj tak WM_PAINT v aplikacii CELE POLE NARAZ na zaklade nejakeho pola cisel, a nie nejaky objekt cervik.
Snaz sa aby to bolo co najprehladnejsie a najlogickejsie, co je casto vtedy ked objekty popisuju akokeby realne objekty, v realite ziaden cervik nic nekresli (nechceli mu predat farbicky v drogerii :)
P.S> premyslenie/vymyslenie co najlepsieho objektoveho modelu je pri vyvoji asi to nahlavnejsie a kludne moze zabrat aj nejaky cas straveny premyslanim a vymyslanim roznych moznosti ake objekty a metody zadefinovat (co prave asi aj robis co je dobre) este predtym ako sa vobec zacne nieco programovat. Nechaj si dostatok casu a skus rozmyslat nad viacerymi moznostami objektov a ich metod. Na to co si pisal v otazke zabudni. Objektov/tried budes mat viac, nielen cervika.

Ale skus najprv rozmyslat (= v hlave skusat rozne "usporiadania" objektov), smerniky na nejake metody fakt nie su OOP riesenie. Neviem kde chces nabrat napr. v jave alebo C# (co su ciste OOP veci) smerniky.
Objekt ma byt vpodstate uzavreta vec, pracujuca s DATAMI ktore dostane zvonku (DATA sa nerovna metoda)

Jezisikriste oni fakt dali do C# smernik :-) To ale fakt je to posledne co by som v slusnom OOP programe robil, az po tom ako by som otrieskal nieco o hlavu tomu kto vymyslal objektovy model :-)
Si zatial moc zaujaty ne-OOP myslenim, uvolni trochu myslenie a uplne vsetko v hlave preorganizuj... Bude to logickejsie a krajsie.

Aj delegáty majú zmysel, hoci netvrdím, že sa to hodí práve sem. Má to napríklad význam, ak máš jednotkové operácie a do delegáta nahádžeš viac operácii a bude ti to vytvárať nejakú hotovú vec. Pre každú z týchto vecí bude jeden delegát a volaním delegátov urobíš čo potrebuješ.

Ked nechces mat kreslenie v cervikovi, tak ako uz pisal JaFi - mozes mat napr. base-class s metodami na kreslenie a od neho odvodit cervika. Potom ked bude niekto chciet pouzit toho isteho cervika s inymi metodami na kreslenie tak ho odvodi od ineho base-classu. Napriklad. Moznych slusnych rieseni je mnoho, zavisi od toho jak to chce mat clovek zapuzdrene, jak sa da dany problem rozdelit na mensie ciastkove problemy, jaky sa predpoklada vyvoj/modifikacie do buducna apod. Nejake smerniky na metodu ale medzi tymi slusnymi rieseniani nie su.

Tak už viem. Vhodnejším riešením by bolo toto:

Vytvoriť triedu, ktorá bude zobrazovať na obrazovke to čo treba, tam kde treba. Bude sa jej musieť dať jedine objekt plátna, na ktorý bude vykresľovať. Červík bude potomkom a teda vo vlastnej triede bude môcť kresliť ako chce, pretože zvonka dostane plátno. Ak budem potrebovať z programu niečo vykresliť, napríklad zablikanie červíka na konci hry a podobne, tak dám na to červíkovi len príkaz a aplikácia nijako do plátna nebude zasahovať. Takto bude červík samostatný, plátno bude mať vlastné, akurát, že odkaz na plátno dostane z aplikácie. Aplikácia bude mať na starosť len test, či hra beží alebo skončila a teda bude vyriešené aj prípadne zväčšenie plochy v novej verzii (v konštruktore bude ako parameter aj plocha, akú si má červík vytvoriť.

Doplnené:
Ešte lepšie bude, ak červík plátno vytvorí a odovzdá ho v nejakom verejnom člene aplikácii. Aplikácia ho už len správne dosadí do obrázku.

To doplnene nerob. Mal by si rozmyslaj aj nad tym ze v buducnosti budes napr. chciet vytvorit 10 objektov cervik a tak rozsirit hru na multiplayer apod, takze cervik by nemal vytvarat platno. Objekty sa snazit robit co najstriktnejsie oddelene zmyslom a funkcionalitou. Tym zvysis sancu ze vyuzijes vyhod OOP (menej chaosu a jednoduchsie rozsirenie do buducnosti).
P.S. preto som aj v uplne prvom navrhu vcera oddelil hraciu plochu a cervika, tak je jednoduchsie zabezpecit aby cerviky vedeli zistovat aj kolizie medzi sebou keby ich tam bolo viac apod - dostanu plochu ako pole a mozu si testovat co chcu). Ale je to na tebe jak si to vymyslis, moznosti je dost.

Mudrujem a sam robim vacsinou ne-OOP v asm :-) Ale to je ina vec, obcas pouzijem OOP ked sa to hodi a viem ze tym vyuzijem vyhod OOP.

P.S. a dufam ze je jasne ze moze existovat napr. objekt triedy hra (v nej by malo byt platno), ktory napr. v konstruktore alebo v metode OdstartujHru(kolkohracov) vytvori objekt(y) triedy cervik a ulozi ich ako napr. private data v triede hra. Tym su cerviky v hre a hra moze volat metody svojich cervikov a predavat im platno. Paralelne moze bezat ina hra (iny objekt hra), ktora ma ine platno, vytvori inych (svojich) cervikov a bude im predavat ako parameter ine platno. Apod. Ked das platno do cervika tak sa toto logicke usporiadanie meni na chaos a pridanie multiplayera alebo multihry sa z jednoducheho new hra zmeni na nocnu moru.

Nižšie som napísal, ako by to bolo lepšie spraviť. Dať červíkovi objekt hracia plocha. Pri pridávaní prípadného multiplayera by sa ale pohyb musel vyhodnotiť v dvoch krokoch:
1. otestovať prekážky
2. pohnúť všetkých červov

Pretože, ak by sa testovalo a hneď na to pohol červík, potom ďalší testoval, pohol a tak ďalej, mohol by nastať dve situácie, ktoré by sa riešili odlišne:
1. červík 1 by vrazil do konca červíka 2, program by to vyhodnotil ako náraz, lebo červík 1 by sa pohol skôr.
1. červík 2 by vrazil do konca červíka 1, program by to vyhodnotil ako posun, lebo červík 1 by sa pohol skôr a uvoľnil by mu miesto.

V tom problém nevidím, skôr je problém v tom, že keby som dal dvoch červíkov, bol by problém s kkolíziami medzi červíkmi. Ale podľa toho, čo som napísal, že najprv testy, potom kroky, ktreba ošetriť aj prípad, že dvaja červíci by sa hlavami hrnuli v rovnaký čas na rovnaké miesto. Pre vyhodnocovanie kolízií by v jednom prípade (test 1. červíka, krok 1. červíka, test 2. červíka, krok 2. červíka) znamenalo, že nabúral 2. červík a v druhom prípade (test 1. červíka, test 2. červíka, krok 1. červíka, krok 2. červíka), že nenarazí ani jeden. Takže najlepšie bude vyhodnotiť čo je pred každým červíkom podľa toho sa zariadiť, urobiť kroky všetkých červíkov a nakoniec skontrolovať vzájomné kolízie. Aby to takto mohlo fungovať, červík musí mať verejné metódy:
- testuj čo je pred tebou
- urob krok
- testuj kolíziu s iným červíkom
V prípade monoplayera sa posledná nevyužije, ale pre prípad budúceho doplnenia do hry je vhodné ju implementovať. V pôvodnej verzii pre DOS by bolo pridanie druhého červíka bez kompletného prepísania kódu nemožné. Vďaka OOP to tu bude potom hračka. Vďaka za nápad s viacerými červíkmi ani som o tom neuvažoval. Keď to bude hra hotová, dám vedieť.

No dúfam, že takto to už bude vyzerať dobre.

Proč vše vymýšlíš naopak?
Proč prostě červovi plátno nepředáš? Ať už jako property nebo v konstruktoru nebo jako parametr metody na vykreslení...

V té první části jsi se v podstatě dobral k tomu, co jsem psal na začátku.
a pokud to chceš mít opravdu jako OOP, měl bys začít vytvořením základního objektu (jedno pole), které bude mít všechny společné metody.
Od něj odvodíš vykreslení zdí, překážek, červa(ů), laskomin pro červy...

Aby mohlo byť v budúcnosti viac červíkov, nemôžem v konštruktore odovzdať plátno, ale objekt hracia plocha, ktorý bude obsahovať plátno a pole, kde bude uložené, čo sa na plátne nachádza. Ide o to, že ak urobím jednu zmenu v plátne, aby o tom vedeli aj prípadní ďalší červíci. Ak odovzdám len plátno, tak to bude len nakreslené a z nakresleného nezistím čo tam je, len pomocou "GetPixel".

Doplnené: Potom bude červík úplne samostatný objekt, pretože na kreslenie bude volať metódy objektu hracia plocha, ktorý dostane v konštruktore.

No, to sa sice da (dat objektu aj objekt ktory ho vytvoril), ale narazis na "slucku" pri definovani tried: trieda A obsahuje objekt triedy B, a trieda B obsahuje objekt triedy A, ktoru triedu zadefinujes ako prvu? ;-)
P.S: tusim ze na to je nieco specialne v OOP ale zhlavy neviem, az taky majster v OOP niesom. Je lepsie asi davat im z plochy len platno a pole ako parametre apod, nie cely objekt.

P.S.2. aha ty chces odovzdat len objekt hracia plocha ale nie objekt hra, to je samozrejme OK. Uz blbnem :)

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.

Zrovna pro tento typ aplikace bych MVC nepoužil. Když chceš zatlouct hřebík, vezmeš kladivo. Můžeš to také udělat tak, že si najmeš 3 lidi - jeden bude držet hřebík, druhý do něho tlouct kladivem a třetí kontrolovat správnou hloubku. Výsledkem bude také zatlučený hřebík...

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