Diskuze: Zhodnocení mé hry - Java Swing
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.


Tak předně gratulace k projektíku dotaženému do zdárného konce. Hra
funguje a to je to co se počítá Sám nejsem herní vývojář, takže těm věcem kolem renderování
a fps a game loopu tak úplně nerozumím, ale pár připomínek jako Java
programátor se zkušenostmi se Swingem bych měl.
Nemáš správně ten threading. Už na začátku děláš chybu v tomhle:
JFrame jf = new JFrame("Hra");
jf.setDefaultCloseOperation(3);
jf.setVisible(true);
Takhle ti to gui neběží na tom 'správném' vlákně. Je to častá a
velmi záludná chyba, která se nemusí projevit při stovce spuštění, ale
pak se o to výrazněji projeví při tom stoprvním Takže správně je vždy:
SwingUtilites.invokeLater(() -> {
JFrame jf = new JFrame("Hra");
jf.setDefaultCloseOperation(3);
jf.setVisible(true);
}
Dále tam potom vytváříš nějaká vlákna pomocí Thread(), to taky není
dobré ve Swing aplikaci, použil bych místo toho spíš SwingWorker. Teď ti
to funguje ok, ale kdybys třeba chtěl v budoucnu to herní okno obohatit o
nějaké JLabely, které by ukazovaly třeba aktuální skore, nebo tak něco,
tak bys velice rychle narazil, při pokusu o jejich update... Ano práce s
vlákny ve Swingu je prostě hrozná
Zapracuj na pojmenování proměnných a tříd. Třída pojmenovaná
NewClass
, to raději přejdu bez dalšího komentáře Také jména proměnných jako
c
nebo jp
pl
- neboj se toho a nazvi je
pořádně klidně nějakým dlouhatánským názvem, ale tak aby na první
pohled bylo jasné co to je. Zdrojový kód daleko víc čteš než píšeš a s
tím psaním ti pomůže ide. Zato s pochopením vlastního zdrojáku po pár
měsících ti pomůžou jenom správné názvy proměnných.
BufferedWriter bw = new BufferedWriter(new FileWriter("stat.txt", true));
String s = JOptionPane.showInputDialog("Zadej své jméno: ");
String text = "";
for (char a : s.toCharArray()) {
write = true;
if ((' ') == a) {
text += "_";
} else {
text += a;
}
}
bw.write(text);
bw.write(";");
bw.write(cas);
bw.newLine();
bw.flush();
bw.close();
zastaralý a zbytečně ukecaný způsob jak získat od uživatele jméno, nahradit případné mezery podtržítkem a zapsat do souboru. Zkus to takhle moderněji:
Path path = Path.of("stat.txt");
String jmeno = JOptionPane.showInputDialog("Zadej své jméno: ").replace(' ', '_');
String line = jmeno + ";" + cas;
Files.writeString(path, line + System.lineSeparator(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
To umístění souboru stat.txt taky není šťastné. Teď ho máš tam, kde je aplikace a chápu že to tak teďka stačí. Ale představ si, že tu hru budeš chtít nějak distribuovat, použiješ nějaký nástroj na vytvoření klasického instalátoru, který ti tu hru nainstaluje na Windows někam do Program Files. V tu ránu ti ten zápis do souboru nebude fungovat, protože normální uživatel, který si tu hru spustí tam nemá práva zápisu.
To je momentálně z mé strany prozatím asi tak všechno. Vzato kolem a kolem dobrá práce!
qw3rtz:29.12.2021 17:48
Moc děkuji za zhodnocení
Jen bych měl dotaz k tomu lambda výrazu, k čemu vlastně slouží 😄
("SwingUtilites.invokeLater(() ..."), zkusil jsem se podívat do dokumentace,
ale nevím jestli jsem to úplně pochopil. Vytvoří vlákno pro ten JFrame, a
slouží k lepší práci s JComponentama, kvůli případné aktualizaci toho
GUI ? Nebo jaký je mezi tímto a klasickým vláknem rozdíl?😀
Děkuji
Atrament:29.12.2021 18:04
Jde o to že, Swing není tzv. thread safe, takže pokud máš v aplikaci více vláken a pokusíš se z některého z nich přistoupit k některé Swingové komponentě, může ale nemusí to skončit nějakou výjimkou. Všechno nastavování čehokoliv ve Swingu musí být správně prováděno na tzv. EDT vlákně, jedině tehdy je to bezpečné. K tomu slouží ta metoda invokeLater() - provede setVisible() na EDT vlákně.
Jak říkám dá se nad tím mávnout rukou, protože obzvláště v
jednoduchých příkladech to funguje i tak, ale je to cesta do pekel, obvykle
se to jako chyba projeví v tom nejméně vhodném okamžiku.
Více o tom https://docs.oracle.com/…y/index.html
S tím, co píše Atrament nejde víc, než souhlasit. Jen ještě něco
doplním. Kromě toho šíleného pojmenování (Na kterém jde vidět vývoj
začátečníka - nejdřív sis s tím dal práci, dokonce i balíček jsi
vytvořil:), ale pak už jsi se snažil, aby to nějak fungovalo a to, co jsi
našel na netu, tak jsi hodil do nějaké třídy a už to šlapalo Dost mi to někoho připomíná
(mluvím o sobě:D) ).
Tak je tam úsměvná ta "čeglish". Držíš se správné konvence -
pojmenovávat anglicky, ale třeba jeden boolean máš pojmenovaný
"kolize".
- Určitě bych chtěl ocenit ty komentáře. Snaha tu je, i když komentář by ti měl něco napovědět (třeba jak metodu používat, varovat před špatným použitím či říct, jaké vstupy očekáváš, pokud to není patrné z kódu). Komentář typu:
/**
* @return the colorPlayer
*/
public Color getColorPlayer() {
return colorPlayer;
}
Je na prd. Co vlastně vidíš? Mám tu metodu, u které vidím, že mi
vrací barvu a jmenuje se getColorPlayer. No a ty mi napíšeš v komentáři,
že vrací colorPlayer.
To má pro mě nulovou hodnotu takový komentář. Ale dal bych ti zeleného
bludišťáka za snahu. Aspoň jde už co napravovat -> takže na to se
můžeš také zaměřit, jak psát dobré komentáře;)
- Další věc (ale tu nemůžeš asi ještě vědět), je ta třída Entity. Až budeš pokročilejší, tak zjistíš, že entita je v programátorském světě už oficiálně brána jako třída databáze. V podstatě když řekneš entita, tak každý zkušený programátor si okamžitě vybaví, že to bude třída obsahující pouze proměnné, které budou mít stejný název, jako hlavička tabulky v databázi, že tam budou pouze přístupové metody (nebo Lombok) a uvidí tam pouze anotace, které mi dokáží prozradit strukturu tabulky v databázi.
Takže to ber jako info pro tebe - Entita není dobrý název z tohoto hlediska.
- Jinak určitě oceňuji použití abstraktní třídy a hlavně, že ji i využíváš. To není u začátečníků obvyklé a není to špatné.
- Dochází k logické chybě u té aplikace. Když si aplikaci spustíš a nic si nezahraješ a zvolíš možnost "Statistiky", tak ti sice vyskočí správná hláška, ale pak program pokračuje dál, jako kdyby se nic nestalo a navíc zmizí možnost spuštění hry.
To je hodně kritický nedostatek a měl bys jej opravit. Respektive nezmizí, ale ten seznam tuto možnost překryje. Tabulátorem se dá na ni překliknout, ale málo koho to napadne.
- Další věc, co bys mohl vylepšit, tak veškerou konfiguraci a texty vytáhnout z kódu. Nepsat to tam natvrdo, ale vytvářet si třeba .properties soubory (ještě lepší v dnešní době .yaml soubory), které ti zajistí konfiguraci. Jeden si bude pamatovat názvy (tím bys měl i jednoduchou přípravu, kdybys chtěl třeba zavádět více jazyků do hry) no a druhý konfigurák na barvy, rozměry, atd.
Potom nějaký osobní setting, který by se mohl měnit a který by si ukládal aktuální nastavení uživatele.
- Dost šikovné je, když se ti aplikace spustí uprostřed obrazovky.
Toho můžeš docílit dvěma způsoby. Buďto přes Toolkit a Dimension balíčky:
private final Toolkit tool = Toolkit.getDefaultToolkit();
private final Dimension src = tool.getScreenSize();
...
//v metodě či konstruktoru
JFrame frame = new JFrame();
frame.setSize(800, 800); //i tyto údaje bys pak tahal z osobního configu
frame.setLocation(src.width / 2 - frame.getWidth() / 2, src.height / 2 - frame.getHeight() / 2);
...
No a nebo úplně jednoduše:
JFrame frame = new JFrame();
frame.setSize(800, 800); //i tyto údaje bys pak tahal z osobního configu
frame.setLocationRelativeTo(null); // <- pokud tuhle metodu zavoláš na null, tak to zarovná v rámci plochy na střed
- Myslím, že jsi špatně pochopil dědičnost. Konkrétně tvoje třída Menu, která dědí z JPanelu, tak jej nijak nerozšiřuje jak by měla. Třeba se tu objevuje metoda visibleNastav (opět šílený čeglish, ze kterého bych tedy ani omylem nepoznal, že "nastav" je název proměnné pro tlačítko -.-)
Trošku to souvisí s tou logikou celé aplikace.
Ke každé aplikaci (ať už hře, webu či čemukoliv) bys měl přistupovat s
tím, že by se v aplikaci měl vždy objevit nějaký "manager". Třída,
která bude vše řídit, spracovávat, uchovávat.
V podstatě i ve webových technologiích, tak to je hlavní smysl Javy. Java je
rize mozek všeho a pak už jen provolává ty zbytky.
Musíš mít roztřízené v projektu: Logiku, Komponenty, práci se soubory,
distribuci - (tu dělíš na frontend,případně desktop nebo mobil). Pak máš
další vytřídění pro databázi atd. atd. atd.
Ty v podstatě tu dědičnost používáš stylem: Hele já si teď vezmu
třídu člověk, jemu dám baťoh, k tomu přidělám dva plechy, k tomu
přišrubuji dvě tyče a mám robota.
Ano, funguje to, ale smysl dědičnosti je rozšiřovat stávající funkcionalitu. To, že to takto jde neznamená, že je to správně. Až příliš jsi to konkretizoval a teď si představ, že ze tvé nové třídy (Menu) by měl někdo dědit.
Konkrétně tvoje metoda setSettings. Má pouze tři parametry, které se ti zrovna teď hodí. Ale co když bych chtěl třídu menu použít jinde a budu pracovat třeba se soubory a potřeboval bych nastavit umístění souboru? To mi tvoje metoda setSettings bude na prd a nikdy ji nevyužiju.
- No a poslední věc, co jsem si zkoušel, tak nemáš to moc objektové. Ano, máš sice dost tříd, ale zkusil jsem si jen tak z hecu vytvořit třeba jinou třídu Framu a jen tak z legrace si zkusil vytvořit novou třídu hráče. Ano, podařilo se mi to vyrendrovat, ale byl jsem přinucen v podstatě naprogramovat novou třídu "NewClass", protože to máš až moc závislé jeden na druhém.
Možná trošku špatně chápeš smysl OOP.
Mám na to hezký příklad. Když si vezmeš dva objekty - židli a zem, tak ty
musíš programovat nezávisle každý z objektů.
Země by neměla propustit ŽÁDNÝ objekt (ani židli, ani letadlo ani barák).
Prostě je tu nějaký povrch a tím nemá nikdo co projít. Ano, pak máš
třeba třídu krtek a ta se ti do povrchu zavrtá a tudíž jim projde ale to je už další rozvoj
třídy Země
Podstata je, že třída Země bude programována samostatně a pokud třída
židle bude chybět, nic se nestane.
To samé třída Židle. Ta má samozřejmě svoji grafickou podobu, ale ať ji
položíš na cokoliv, tak ona se nepropadne a bude hledat pevný povrh.
Takže musí platit obojí pravidlo. Třída Země nepropustí žádný objekt
(ani židli) a třída Židle neprojde žádným povrchem (ani Zemí).
Oba dva objekty jsou nezávislé na sobě.
Tvá třída Player je až moc svázaná se třídou NewClass. A to je
špatně.
Samozřejmě logika, jak bude třída NewClass se třídou Player pracovat, tak
ta už musí být hodně konkrétní, ale tady se bavíme o blbém
zobrazení.
Ty nejsi schopen třídu Player jednoduše zobrazit. Přitom třída Player (i
když docela složitě) reprezentuje objekt panelu, kterým nějak
posouváš.
Prostě ten logický koncept je docela zmatečný a měl bys nad tím
postupovat trošku víc racionálněji.
V podstatě když bych to převedl do skutečného světa, tak ty, kdybys
takovouto hru měl vytvářet ve skutečnosti, tak ty místo toho, abys
vytvořil nový objekt, který bude bude představovat čtvereček, se kterým
bude uživatel pohybovat, tak ty vytvoříš ovládač, který bude uživatel
ovládat a tento ovládač bude posunovat nějakou deskou, na kterou se obvykle
dávají jiné věci.
Když bych to řekl jednoduše - zkus se na celou aplikaci dívat z pohledu
nějakého řízení.
Zkus si to předělat na tuto logiku:
Mám třídu, která mě bude dělat managera a všechno řídit. Bude se starat
o to, že se nějak spustí hra (ale nebude vytvářet spouštění!! Ona to jen
provolá, když bude potřeba). Bude vyhodnocovat výsledky (ale opět nebude
nic vypočítávat, jen v pravý čas zavolá, kdy bude potřeba něco
vyhodnotit). To samé zobrazení atd.
Prostě typický manager
Umí hovno, ale je velmi důležitý, protože všechno dokáže zařídit tak,
aby to fungovalo.
No a potom k tomu přiděláš potřebné třídy. Třidu, která POUZE
vykreslí hráče a nic víc. Tato třída se bude zabývat pouze tím, co se
vztahuje k samotnému hráči (barvu, pozici, posun, případně bude vracet
informace o tom všem. A to je vše).
To samotné nějaký timer. Ten si bude uchovávat čas a nic víc (teoreticky
na to bys ani nepotřeboval třídu, ale dobrou soukromou metodu v managerovi -
že by měl něco jako vlastní stopky).
To samé hlavní okno. Manager ho dokáže vytvořit, manager ho nastaví a on
bude s oknem pracovat, až když se něco stane. A manager ho vyhodnotí.
Okno sice bude mít nějaká tlačítka, ale co budou tlačítka vykonávat, tak
pokud půjde o nějakou logiku, tak to vyhodnotí manager, pokud půjde o
nějakou grafiku, tak to si okno zpracuje samo.
Manager také bude řešit, jestli hra skončila, v jakém jede vlákně, atd.
atd. atd.
Tohle je způsob, kterým bys měl uvažovat - dělit program do logických oddílů a pokud možno takových, aby bylo jasné, co který oddíl bude řešit. Tento bude řešit logiku hry, tento grafiku, tento práci se soubory, atd.
Schválně - jak by ti to dlouho trvalo, když bys třeba teď chtěl přidat
druhého hráče?, který by třeba hrál stylem - náhodné pohyby (takovou
primitivní umělou inteligenci). Kam bys takového hráče přidal?
Nebo třeba další věc - kdybys chtěl rozšířit Menu možnosti. Co vše bys
musel dodržet a jak dlouho by ti v kódu trvalo, než najdeš, co vše je se
vším spjato?
No a samozřejmě v projektu chybí unit testy:) + spousta věcí by se
syntakticky dala zapsat lépe. Na to ti doporučím plugin Sonarlint (v
podstatě když se ti podaří správně nastavit, tak ti to bude kontrolovat
kód a bude ti říkat, co syntakticky napsat jinak).
Kupříkladu tě sonarlint bude upozorňovat na to, že máš v konstruktoru 7
parametrů a kód se stává nečitelným. Nebo naopak moc zanořených ifů a
cyklů v sobě. Nebo nepoužité metody, atd. Je to užitečná věc, která tě
naučí psát čisté kódy. Někdy je úprava pomocí sonaru lehká, někdy to
vyžaduje uvažovat nad změnou celé logiky.
Každopádně dobrá práce. Projevils snahu, máš výsledek a tvůj topic jen dokazuje, že se chceš zlepšovat;) Tento přístup si zachovej, vzdělávej se dál a dál a budeme mít o jednoho velmi šikovného programátora navíc, což je bezva!!
qw3rtz:5.1.2022 21:16
Děkuji Vám moc za odpověď. 🙂
Asi o víkendu zkusím zapracovat na tich chybách a přeprogramuju to, až bych
to měl, tak bych to sem zkusil ještě dát ?
Jen bych měl ještě dotaz 😀
,,Konkrétně tvoje třída Menu, která dědí z JPanelu, tak jej nijak
nerozšiřuje jak by měla." - takže místo dědičnosti bych si měl v té
třídě udělat instanci JPanelu a pracovat s ní ? Tím rozšířením se
myslí třeba Overide nějaké metody ?
Lubor Pešek:5.1.2022 22:26
Jo, rozšířit třídu znamená zdědit a přidat nové metody, ale podstata
předka by měla zůstat. Override znamená přepsání metody, takže bys jen
změnil stávající funkcionalitu.
Ono celkově to dědění je velmi nebezpečná věc. Implementace je velice
jednoduchá, ale je potřeba vždy zvážit, jestli je potřeba dědit (čili
rozšířit) z dané třídy. To je právě na programátorovi, aby to posoudil.
Pokud to jen trošku půjde, tak je dobré se dědičnosti vyhnout. Už jen z
toho principu, že dědit v Javě můžeš pouze jednou a tak bys to měl
šetřit opravdu do takových případů, kdy to bude nevyhnutelné.
Konkrétně v tomto případě, co jsi udělal ty, tak jsi vůbec
nepotřeboval žádné vlastnosti toho JPanelu. V podstatě jsi to využil pouze
jako komponentu, na kterou jsi navrkal další tlačítka.
Takže jsi mohl přímo použít prázdnou JComponent třídu a na ní si to
všechno naházet. No a nebo není vůbec potřeba vytvářet na to speciální
třídu, ale pokud jde o 4 tlačítka, tak jsi to mohl v rámci jedné metody
přihodit přímo v hlavní třídě.
No a kdyby jsi chtěl speciální třídu na to, tak právě kdybys měl nějakého managera, který by to zpracovával, tak bys mohl vytvořit obyčejnou třídu a přes toho managera by sis vytáhl componentu (třeba nějaký hlavní JPanel), na který bys to nasáčkoval. No a tím pádem bys vůbec nepotřeboval žádného potomka swing component, ale v metodě dané třídy by sis hezky vytvořil tlačítka a pak bys je jednoduše přidal na JPanel, který dostaneš v rámci nějaké metody (ať už statické či singletona) z managera.
Těch způsobů je samozřejmě moc a neexistuje žádný mustr. Ty musíš vždy uvažovat tak, abys pokud možno programoval co nejobecněji a taková jednoduchá kontrola, jestli programuješ objektově, tak je v podstatě v tom, že si to, co naprogramuješ, vyhodíš z projektu. No a teď se ptáš sám sebe - funguje to samostatně nebo je to hodně provázané s projektem? Pokud je to provázané, je to chyba, protože případná editace bude v budoucnu hodně složitá.
To samé i naopak. Pokud mám nějaký panel, na který vkládám komponenty,
tak se sám sebe ptej - můžu tam přidat jakoukoliv komponentu a nebo to
musím specifikovat?
Krásným případem tohoto jsou třeba piškvorky. Když si uděláš nějakou
herní plochu, tak se pak zeptej sám sebe: Tak, teď tam mám křížek a
kolečko. Jak by bylo obtížné tam implementovat, abych tam přidával
nějaké jiné tvary?
A další věc - když bych tam chtěl přidávat nové tvary, tak jak by bylo
problematické, aby se správně vykreslovaly? A šlo by, aby tvary byly
libovolné, nebo musí být přesně specifické? (kupříkladu dost častá
chyba, kdy samotný tvar ať už křížek či kolečko je vypočítáváno na
základě kliknutí na plochu). Atd. atd. atd.
PS: Toto je dost častý problém, který programátor řeší. Jak zobecnit a zpřehlednit kód. Jak udělat strukturu celého programu, jak vytvořit logické celky a dávat to do správných balíků.
Třeba konkrétně u tebe - dej si tu práci a sám si řekni, kolik času by
ti zabralo, abys čtverečky přeměnil na kolečka. Potom aby to byl třeba
složitější tvar (třeba dvě kolečka v sobě, nebo kolečko s hvězdičkou
uprostřed).
Určitě toho, čeho bys chtěl docílit, tak by mělo vypadat tak, že podobu
samotného objektu, kterým budeš pohybovat, tak aby se programovalo naprosto
nezávisle na ostatním kódu. V podstatě aby samotný hráč byla komponenta
(klidně prázdný nebo neviditelný patvar), který bude vždy fungovat
stejně. No a to, jak si to vykreslíš, nesmí hrát roli.
To samé další věc - jak by ti dlouho trvalo, aby hráč měl nějakou
podobu a "Enemy" úplně jinou?
Jak dlouho by trvalo, kdybys chtěl do hry přidat další elementy
(kupříkladu, aby menu bylo hezky celou dobu nahoře v okně, jak to u
aplikací bývá? Kdybys tam chtěl třeba přidat nějakou překážku. Odraz
kostky je pevně svázán jenom s okrajem plochy? Nebo se odrazí od čehokoliv?
(třeba nepřítel od nepřítele) atd.
Je to všechno možné rozšíření, ale na takovýchto věcech nejlépe poznáš a nejlépe se budeš učit, jak programovat.
Kdysi dávno tu byla diskuze ohledně nějaké nové Javy. Nevím, kolikátka
to byla, jestli 8 nebo 9. Šlo o to, že se borec ptal na nějaké info ohledně
přechodu na novou verzi Javy. Tak jeden "profesionál" mu odvětil, že
nechápe, proč z toho dělá takovou vědu, když novější Java zvládá bez
problémů vždy i nový kód. Na to dostal dotyčný krásnou reakci:
"Je vidět, že jsi nikdy nic nevyvíjel a nepracoval s frameworkem. Není nic
příjemného přecházet na novou verzi u frameworků, které třeba jinak
využívají různé technologie atd."
A popravdě o tom je celý i vývoj. Nejlepší, co můžeš udělat je, že
začneš projektík. Velice jednoduchý - prostě se spustí, něco udělá a
ukončí se. No a pak si budeš dávat vlastní tasky, jak to budeš měnit,
vylepšovat, přidělávat a předělávat. Třeba i blbá změna barviček.
Změna textů všude. Změna fontů atd.
Tohle si někdy zkus. Prvně to dělej ručně. A třeba už jen blbá změna
fontů tě donutí k tomu, že než abys všechno měnil furt ručně a
prohledával, kde všude máš ještě měnit textíky, tak si sám řekneš -
budu to ukládat v nějaké společné kolekci, v nějakém souboru, prostě
někde společně. No a najednou máš novou featuru - funkci, kterou dáš i
uživateli - změna fontu v celé aplikaci.
To samé třeba lokalizace do jiných jazyků. Najednou ti zmizí všechny texty
aplikace z kódu, ale budeš to mít hezky v nějakém souboru. A potom budeš
rád, že změna lokalizace na jiný jazyk pro tebe bude znamenat pouze změna
jednoho souboru za druhý.
Atd. atd. atd. Jestli máš čas, chuť a zápal, tak jdi tímto směrem. Začni si mini projektík a vylepšuj ho. Sám dojdeš postupně na to, co bude pro tebe lepší a budeš hledat chytřejší řešení. O tom celé programování je. No a pak začneš používat modernější technologie (opět příklad - začneš s properties soubory a pak přejdeš na XML, pak na JSON a pak na yaml. A nebo některý z nich přeskočíš, ale vyzkoušej si to, to ti radím, ať se seznámíš s výhody i nevýhody).
Krásný příklad takového vývoje je třeba obyčejná kalkulačka. Začni
konzolově - že jen vypíšeš součty. Pak to přesuneš do metod. Pak
uděláš projekt, ve kterém výpočty a logika budou v jenom balíku a
zobrazování v dalších balících (a jakékoliv zobrazování bude používat
právě tuto již naprogramovanou logiku).
Kdybys to začal přímo ve swingu, tak asi první, co by tě napadlo, tak že
každé tlačítko pro výpočet bude mít pevně spjatou logiku s daným
výpočtem (že tlačítko + bude sečítat atd.)
No když ti řeknu - převeď to na FX nebo na web aplikaci, tak můžeš
začít prakticky od začátku.
Joooo, když budeš mít početní logiku separátně a nějaká třida ti vždy
vrátí výstup podle vstupu, tak to můžeš pak používat v konzoli, ve
swingu, v FX, v mobilní aplikaci, webové aplikaci nebo to vracet jako nějakou
servisu.
A zase jsme u toho případu s tím "managerem" Opět je dobré mít nějaký
centrální mozek, přes který to všechno proudí a který si hraje s logikou
a pak už ty jednotlivé dílčí nástroje (výpočty, komponenty, různé
algoritmy, business logiku, JPA, práci s modely a všechno možné a
nemožné), tak rvi do samostatných oddílů.
Zdravím,
konečně jsem se opět dostal k tomu projektíku a předělal jsem ho. 😀
Víc jsem to rozdělil, zkusil jsem si napsat i JUnit4 testík na herní soubory
(zatím tam je teda jen jeden), napsal jsem komentáře a ještě mě napadlo
pár dalších věcí, tak to tam ještě potom zkusím dodělat. 🙂
Odkaz (už je tam moc tříd ): Projekt - odkaz na úschovnu
Snad je to už lepší
A ještě bych měl takový vedlejší dotaz, jestli nemá náhodou někdo
zkušenost s touto třídou:
VektorováGrafika1
nebo s touto:
VektorováGrafika2
zkoušel/zkouším udělat aplikaci která by bitmapu převedla na vektorovou
grafiku, našel jsem si tyto třídy, ale ta vektorizace u tich obrázků není
nic moc (mění to barvy a dokresluje si to čáry, občas to rozostří celý
obrázek) 😀
Děkuji za rady.
qw3rtz:4.2.2022 21:59
Ještě mě teď napadlo, jak je to s bezpečností (u této aplikace je to
asi zbytečné řešit, ale třeba u jiných), používal jsem nakonec
.properties soubory (na xml jsem si zatím netroufl ), který se dají snadno
přepsat, to se pak ukládají do složek, který může přepisovat jen
správce nebo jdou nějak zakázat úpravy?
Děkuji
Zobrazeno 9 zpráv z 9.