Grafická podoba programu – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Grafická podoba programu – Java – Fórum – Programujte.comGrafická podoba programu – Java – Fórum – Programujte.com

 

joe0
Newbie
16. 10. 2008   #1
-
0
-

Ahoj,

potřeboval bych vědět, jakým způsobem se v Javě vykresluje - vysvětlim. Dejme tomu, že bych chtěl udělat hru Dámu a teď bych chtěl vykreslit šachovnici a figurky na ní pomocí obrázků, ale nevím jak správně postupovat, jaké prvky/objekty pro to použít.

Třeba když by se něco podobného dělalo v .NETu, na formulář se může umístit prvek Image, ten pak případně rozkopírovat a posouvat jejich pozici. Jenže v Javě to je jiný a tam to takhle jednoduše nejde nebo jo?

A také jak byste co nejjednodušeji vykreslili šachovnici? Celým obrázkem/nějakým cyklem a použitím čar v Javě..?

Kdyby mě někdo navedl jakým způsobem nebo věděl o nějakém jednoduchém ukázkovém příkladu, ocenil bych to...

Díky

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
16. 10. 2008   #2
-
0
-

Ahoj,
na tohle je potřeba použít aktivní renderování, tzn. žádný Swing/SWT. Ono by to samozřejmě teoreticky šlo, jelikož je to jen jednoduchá grafika, takže by nějak šla nacpat do UI komponent, ale bylo by to prasácké a naprosto neefektivní, takže na to vůbec nemysli:-)
Podívej se na Java 2D, na 2D grafiku naprosto dostačující věc, a pracuje se s ní krásně.
Tutorial máš například přímo na Sunu http://java.sun.com/docs/books/tutorial/2d/index.html (je nich tam víc, tak hledej).

Nahlásit jako SPAM
IP: 85.13.98.–
joe0
Newbie
16. 10. 2008   #3
-
0
-

To Mihulik :
Dobře, díky. Podívám se na to. Pokud se ale nepletu, pak budu muset po každé změné třeba té figurky znovu vykreslit šachovnici, když by to bylo tak jak jsem napsal v úvodu? Není to zbytečný? Zase použiju pro příklad ten .NET (mám ho daleko radši než Javu) - tam bych jen změnil pozici obrázku a o vykreslování bych se nijak nestaral... (ještě jsem na to ale nekoukal)

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
16. 10. 2008   #4
-
0
-

joe napsal:
To Mihulik :
Dobře, díky. Podívám se na to. Pokud se ale nepletu, pak budu muset po každé změné třeba té figurky znovu vykreslit šachovnici, když by to bylo tak jak jsem napsal v úvodu? Není to zbytečný? Zase použiju pro příklad ten .NET (mám ho daleko radši než Javu) - tam bych jen změnil pozici obrázku a o vykreslování bych se nijak nestaral... (ještě jsem na to ale nekoukal)


V aktivním renderováním ano. To co popisuješ ty je pasivní renderování. Netvrdím, že by na tento jednoduchý případ nestačilo, ale jakmile budeš chtít opravdu s tou grafikou pracovat, tak ti nic jiného než aktivní renderování nezbyde.
A o neefektivitu se neboj. Pokud se alespoň malinko naučíš principy aktivního renderování, tak tvoje aktivní renderování bude podstatně výkonější než nějaké pasivní renderování pomocí Swingu:-)

Edit: Nejde o to, jestli jestli programuješ v .Net nebo v Javě nebo v XYZ. Tohle jsou obecné postupy. Aktivní renderování jde stejně hezky dělat v Javě jako v .Net:)

Nahlásit jako SPAM
IP: 85.13.98.–
joe0
Newbie
17. 10. 2008   #5
-
0
-

To Mihulik :
Mohl bys mi prosím tě ještě vysvětlit, jak "tam" mám vykreslit ten obrázek? Pročítal jsem si jak se obrázek načte a vykreslí, všechno je mi jasné, jenom mám vždycky problém to pak "propojit" s tim formulářem, který jsem vytvořil v gui builderu v Netbeanech. Nemám s tím moc zkušenosti... Situace se má takhle, jednoduše jsem si vytvořil nový projekt, s hlavní třídou Main a pak třída představující formulář JFrame, na který jsem v gui builderu dal JPanel. A teď jak to udělat, když bych chtěl na ten JPanel vykreslit obrázek, který načtu v tý hlavní třídě Main? To jsou věci, který jsem na Javě a podobných jazycích nepochopil...

        BufferedImage img = null;

try {
img = ImageIO.read(new File("C:/strawberry.jpg"));
} catch (IOException e) {
}

Form f = new Form(img);
f.jPanel1.drawImage(img, 0, 0, null);
f.show();

Potřeboval bych vědět jak se "to" děl. Kdyby to fungovalo jako je označený ten tučný řádek, snad bych s tím žádné problémy neměl...
Díky za pomoc.

EDIT:

Teď jsem si všimnul, že jsem tam nechal předávání toho obrázku v konstruktoru, tak jsem to někde viděl a tak by to i šlo, jen by mě zajímal správný postup, co třeba v případě, že těch obrázků bych chtěl vykreslit víc... to by se zase dalo řešit tak, že předám pole obrázků, ae kdybych předával několik různých typů, tak dávat všechno do konstruktoru mi nepřijde moc vhodný...

A taky jestli to chápu dobře, ten obrázek můžu vykreslit jen když tam mám Graphics, takže musím vždycky přepsat metodu paint?

S těma jazykama, napsal jsem třeba .NET, ale myslel jsem pod tím třeba Delphi, VB, ty starší verze ještě, kde se třeba jednoduché hry dělali tak, že se obrázky nastrkaly do prvků na formulář, ty se skryly a pak se jen zobrazovaly a měnily jejich pozice, takže to bylo daleko jednodušší :-) aspoň pro mě.

EDIT: už jsem na to asi přišel.

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
18. 10. 2008   #6
-
0
-

Jediná možnost jak aktivně renderovat je pomocí grafického kontextu (Graphics a Graphics2D). Koukám ale že jsi na to již přišel, takže dobrý:-)

Určitě se nenech odradit a snaž se-je to lehké:-)

Nahlásit jako SPAM
IP: 89.24.5.–
joe0
Newbie
18. 10. 2008   #7
-
0
-

To Mihulik :
Přišel jsem na to, asi si pořád neuvědomuju, že všechno jsou objekty, ještě jsem si asi nezvyknul :-)

Teď už to mám všechno vyřešené, ale zaseknul jsem se na jedný věci. Mam vykreslenou mřížku a teď po stisku obyčejného tlačítka chci změnit pozici figurky. Pozice se mi změní (uloží do parametrů figurky), ale otázkou je, jak to překreslit. Potřeboval bych zavolat metodu paint(Grephics g), ale kde vzít ten grafický kontext... tu metodu potřebuju zavolat z jiný třídy.

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
18. 10. 2008   #8
-
0
-

Hele je to jednoduché:

udělej si nějakou animační smyšku. Obvykle je ve tvaru (je to vlastně i taková konvence):

public void draw(Graphics g){
...
}

a zde probíhá vykreslování.

A kde vzít kontext? Jednoduše.
Dejme tomu,že tedy kreslíš do nějakého JPanel...

máš herní cyklus, který furt běží. Něco ve stylu:

public void gameLoop(){
while(running){
gameUpdate();//zde se provede aktualizace stavů hry
gameRender();//zde se vykreslí hra na obrazovku...zde právě voláš metodu draw(Graphics)
checkInputs();//zde kontroluješ uživatelské vstupy
...
Thread.sleep(10);/*
* Tohle je zde poměrně důležité, aby jsi dal možnost pracovat i jiným vláknům.
* Lepší by bylo počítat onen "spící" interval
* dynamicky, v závislosti na stavu hry, ale to teď vůbec neřeš.
*/
}
}

zkrátka něco v takovém stylu.

No a v metodě gameRender() probíhá něco takového:

public void gameRender(){
Graphics g=myJPanel.getGraphics();
draw(g);
g.dispose();
}





Doufám, že jsem to napsal alespoň malinko srozumitelně a trochu ti poradil:-)

Nahlásit jako SPAM
IP: 85.13.98.–
joe0
Newbie
18. 10. 2008   #9
-
0
-

Díky za vytrvalost :-)

Později se na ten postup jak jsi napsal určitě podívám podrobněji a zkusím si to, ale to svoje vykreslování jsem už vyřešil, resp. zkusil jsem si vytvořit nový projekt a tam nastínit tu samou situaci a najednou tam to bezproblémů šlo, tak jsem to porovnával v čem to je jiné, že mi to v tom kde jsem to chtěl rozběhat nešlo a doteď nechápu jak je možný, že jak jsem to měl, tak to nefunguje. Popíšu to sem, kdyby mě to třeba někdy v budoucnu zajímalo :-)

Mám jednu třídu, která představuje formulář a v ní mám i ten prvek, který chci po nějaké změně překreslovat. V té samé třídě třeba po kliknutí na tlačítko volám metodu jiné třídy, která má v sobě parametr toho prvku, co chci překreslit. Tak v té metodě co volám v té druhé třídě jsem měl prvek.repaint(); a to nezpůsobovalo překreslení toho prvku. Pokud jsem to ale udělal v té samé třídě, kde ten prvek je, tak to najednou šlo... nechápu.

Jinak k tomu tvýmu příkladu, určitě poradil ;-) a chápu to, ale co na tom nechápu je ta smyčka, která neustále vykresluje a možná to dělá někdy i mnohokrát zbytečně. Nebylo by lepší překreslovat jen v případě nějaké změny, když k nějaké dojde..?

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
18. 10. 2008   #10
-
0
-


Tak v té metodě co volám v té druhé třídě jsem měl prvek.repaint(); a to nezpůsobovalo překreslení toho prvku.


Pozor! Metoda repaint() se používá při pasivním renderováním, nikoliv při aktivním! Podívej se ještě pořádně na rozdíl mezi aktivním a pasivním renderováním (najdeš to v nějakém tutorialu na SUNu):-)


a možná to dělá někdy i mnohokrát zbytečně. Nebylo by lepší překreslovat jen v případě nějaké změny, když k nějaké dojde..?


Samozřejmě, že už záleží na tvé konkrétní implementaci, jak moc bude optimalizována a efektivní. Tohle byl jen nejjednoduší AHA-příklad:-)

Nahlásit jako SPAM
IP: 89.24.5.–
joe0
Newbie
27. 10. 2008   #11
-
0
-

Kam mi zmizel můj příspěvek? Je fuč, tak to zkusim napsat nějak podobně znova..

Předpokládám, že pasivní renderování je přesně to, co potřebuju. Nemusím totiž překreslovat (zbytečně), když se nic neděje, tak proto volám metodu repaint();

Teď jsem se ale dostal k dalšímu problému. Mám tlačítko, které po kliknutí zavolá metodu proved(); která změní nějaké proměnné a zavolá právě metodu repaint(); (u "prvku", který mi zařizuje vykreslení - dědí po JComponent). Tim se posune figurka. Problém ale nastává, když chci udělat další tlačítko, které po kliknutí zavolá metodu cyklus(); která může vypadat nějak takhle:

void cyklus() {
for(int i = 0; i < N; i++) proved();
}

To způsobí, že se několikrát provede proved(). Teď bych předpokládal, že figurka se mi bude pohybovat, ale nepohybuje - proč? Nemyslím si, že metoda proved() trvá tak krátkou dobu, aby to posouvání figurky nebylo vidět. Čeká totiž na odpověď ze serveru. Zkoušel jsem přidat

Thread.sleep(5000);

ale ani to nepomohlo. Můžeš mi s tím ještě poradit prosim tě? Díky ;-)

Nahlásit jako SPAM
IP: 82.100.5.–
joe0
Newbie
27. 10. 2008   #12
-
0
-

Ještě malý pokus k tomu textu nad, když napíšu tohle:

proved();
Thread.sleep(2000);
proved();

Vykreslí se to až po tom druhém zavolání metody, nevím proč.

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
27. 10. 2008   #13
-
0
-

Rozhodl jsi se pro pasivní renderování. No je to tvá volba, v tomto případě to možná stačí, ale znovu říkám-pasivní renderování není určené pro takovéto účely.
A teď k tvému problému. Nastuduj si lépe, jak funguje metoda repaint(). Metoda repaint() neprovádí okamžité překreslení komponenty. Pouze signalizuje vláknu AWT, že až bude mít čas, měl by tuto komponentu překreslit...

Nahlásit jako SPAM
IP: 85.13.98.–
joe0
Newbie
28. 10. 2008   #14
-
0
-

No, ale já zase předpokládám, že aktivní renderování není zrovna moc vhodné používat pro okenní aplikaci nebo snad jo? Na těch SUNovskejch stránkách jsem si to tak lehce pročítal a taky ne všemu rozumim jak bych měl, ale když budu mít nějakou MDI aplikaci - nějaký editor například a teď na nějakém místě mám JPanel, kde chci plynule posouvat třeba nějaký trojúhelník ze strany na stranu, použiju aktivní renderování? Asi mi nic jinýho nezbyde, ale nenašel jsem žádný příklad na to.

Akorát jsem si všimnul, že doporučují vypnout překreslování na celém formuláři a to já zase nechci, protože tam mám i další prvky, které chci aby se mi normálně překreslovaly...

Nakonec jsem to vyřešil tak, že místo repaint() jednoho JPanelu updatuju celý okno... Sice to není zrovna nejlepší, ale na to co to potřebuju je to snad úplně jedno, protože ta metoda update() se provede daleko méněkrát, než když třeba zvětším nebo zmenším hlavní okno programu... Každopádně dík za pomoc. Já teď nemám zrovna moc času učit se nějaký aktivní renderování když ho k ničemu nepotřebuju a Javu už třeba vidím naposledy...

Nahlásit jako SPAM
IP: 82.100.5.–
Mihulik0
Návštěvník
28. 10. 2008   #15
-
0
-

Každopádně dík za pomoc. Já teď nemám zrovna moc času učit se nějaký aktivní renderování když ho k ničemu nepotřebuju a Javu už třeba vidím naposledy...


nejde o to, jestli je to Java, C#, C++, nebo XYZ- tohle jsou obecné techniky, ale nemá cenu to řešit-už jsi se rozhodl, takže nezbývá než popřát hodně štěstí:-)

Nahlásit jako SPAM
IP: 85.13.98.–
joe0
Newbie
28. 10. 2008   #16
-
0
-

Mihulik, víš, já to možná chápu trošku špatně :-) Ona třeba takhle jednoduchá animace by se dělala ve VB/VB.NET tak, že by se na formulář jednoduše umístil svůj vlastní prvek (UserControl, který se dá vytvářet) a pak Timer, ve kterém jen nastavím interval a pak už to jen samo s prvkem hýbe. To, že na to ve finále používá někde nějaký grafický kontext mi je vcelku ukradený :-) Takže když to porovnám, asi to je stejné, protože

UserControl = třída / objekt, který dedí po JComponent, má grafický kontext a tam se vykresluje.
Timer = jednoduchá smyčka s nějakou prodlevou.

(Asi to tak je, že?)

Takže rozdíl jak jednoduše to "naprogramovat" ve VB/VB.NET je daleko jednodušší a zabere daleko méně času, než nějaké patlání se v tom v Jave... a výsledek? Aplikace vytvořená ve VB(.NET) bude pro uživatele daleko rychlejší, tipnul bych si, že spotřebuje méně paměti když je tak jednoduchý program spuštěný a nepotřebuje žádné JDK - samozřejmě na úkor toho, že to nebude multiplatformní, ale to mě tak moc zajímat nebude, protože tu je Windows, byl a vždycky tu bude... ;-)

Nahlásit jako SPAM
IP: 82.100.5.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 2 hosté

Podobná vlákna

Grafická knihovna — založil Prasklej Talíř

Graficka kniznica — založil Erik

Grafická funkce — založil kropovez

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý