Hei, ei taas googlettelu auta, tai sitten en osaa käyttää oikeita hakusanoja. Miten minun kannattaa toimia jos haluan luoda olion jolla on esimerkiksi muuttujat kokox, kokoy, x, y ja haluan piirtää tämän esim fillrect(kokox, kokoy, x, y);. Ongelma tulee eteen kun koitan saada aikaan ohjelmaa joka tunnistaa törmääkö kaksi laatikkoa toisiinsa.
Lisäys:
Tässä vielä olion koodi. Eli miten tätä tulisi kutsua luokasta joka toteuttaa "pelikentän"?
import java.awt.Color; import java.awt.Graphics; import java.awt.Toolkit; import javax.swing.JPanel; public class Laatikko extends JPanel{ int width = 10; int height = 10; int x = 100; int y = 50; public Laatikko() { setBounds(x, y, width, height); } public void paint(Graphics g) { super.paint(g); g.setColor(Color.white); g.fillRect(100, 150, 10, 10); Toolkit.getDefaultToolkit().sync(); g.dispose(); } }
miksi Laatikko luokka, kun on olemassa valmis Rectangle-luokka? Se kun palauttaa myös Point(oikean yläreunan sijainti) ja Size(korkeus ja leveys) luokat valmiiksi. Ja jos se ei suoraan kelpaa niin periytät siitä oman luokkasi.
Se mitä tulee törmäyksen tunnistamiseen, on sitten puhtaasti matematiikkaa, ja sen toteuttamiseen löytyy runsaasti ohjeita googlettamalla. Hakusanoina käyttäisin esim. java törmäyksen tunnistus, tai jos englanti taipuu: java collision detection.
Laatikko luokka että saan palautettua tietyn laatikon sijainnin. Tähän olisi varmasti helpompikin keino mutta Graphics luokka on minulle vielä aika tuore asia.
En Javasta juuri mitään ymmärrä, mutta tuo menee jo surkuhupaisasti pieleen:
Koska Laatikko-luokka perii JPanelin, niin jokainen luotu Laatikko-olio luo aina uuden JPanelin. (Kaiken lisäksi ne JPanelit luultavasti tulevat edellisten JPanelien päälle, joten näkyvissä on aina vain yksi JPanel+Laatikko.)
Varmaankin haluat yhden JPanelin ja siihen lisätään sitten laatikoita.
Google löysi heti tuollaisen esimerkin:
http://www3.ntu.edu.sg/home/ehchua/programming/
En tiedä onko tuo koodi hyvää Javaa, toivottavasti palstan Java-osaajat kertovat.
Joo olet todennäköisesti oikeassa ja koitin kyllä esim periyttää JLabelia mutta eipä sekään auttanut. Enkä tosta linkistäkään oikeen vastausta saanut ongelmaani. Eli siis haluan että voin luoda nimetyn objectin jotta voin esimerkiksi palauttaa sen sijainnin getBounds() metodilla.
Kuten JaskaP yrittää yllä sanoa, tee yksi JPanel, laita siihen lista Rectangle-olioista ja piirrä kaikki laatikot silmukassa kyseisen pääpaneelin piirtorutiinissa. Kahden laatikon törmäyksen saat helposti selville intersects-metodilla.
Swingissä ei pitäisi käyttää paint-metodia vaan paintComponent-metodia. Kannattaa lukea Sunin sivuilta artikkeli Painting in Swing.
Okei tein tämän nyt näin:
Board.java
package net.viped.piirtoa; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JOptionPane; import javax.swing.JPanel; public class Board extends JPanel implements ActionListener{ Laatikko laa = new Laatikko(); Laatikko laa2 = new Laatikko(); Saie saie = new Saie(); boolean right = false; int x = 10; public Board() { addKeyListener(new ListenKeys()); laa2.setBounds(100, 10, 10, 10); laa.setBounds(10, 10, 10, 10); saie.start(); setFocusable(true); } public void paint(Graphics g) { //Graphics2D g2d = (Graphics2D)g; super.paint(g); g.fillRect(laa.x, laa.y, laa.width, laa.height); g.fillRect(laa2.x, laa2.y, laa2.width, laa2.height); g.dispose(); } public class ListenKeys extends KeyAdapter { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_RIGHT) { right = true; } } } public class Saie extends Thread { public void run() { System.out.println("run"); while (true) { try { if (right) { laa.x++; laa.setBounds(laa.x, laa.y, laa.width, laa.height); } sleep(20); repaint(); //System.out.println(rlaa.getBounds()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (laa.intersects(laa2)) { System.out.println("kosketus"); } } } } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub repaint(); } }
Laatikko.java
package net.viped.piirtoa; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Toolkit; import javax.swing.JLabel; import javax.swing.JPanel; public class Laatikko extends Rectangle{ public Laatikko() { } //Omia metodeja yms }
Onko tähän helpompaa ja järkevämpää tapaa?
Edit: Ja vielä yksi luokka josta tuo kaikki laukaistaa
Launch.java
package net.viped.piirtoa; import javax.swing.JFrame; public class Launch extends JFrame{ public Launch() { add(new Board()); setSize(300, 300); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new Launch(); } }
Mikä siinä on niin vaikea taas tajuta? Heitä koko Laatikko-luokka roskiin, et tarvitse sitä mihinkään. Laita Rectangle-oliot listaan (esim. ArrayList), niin ei tarvitse luetella niitä erikseen ja voit hyödyntää silmukoita määrän kasvaessa.
Kyse on esimerkistä. Entä jos haluan Laatikolle sellaisia metodeja jota Rectanglelta ei löydy. Jos Laatikko olisi esimerkiksi Enemy ja sillä pitäisi olla myös muuttujat kuten int power tai int health tjsp. Hieman kärsivällisyyttä pyydän, tässä koitetaan vasta opetella ohjelmoimista.
Kun haluat lisää metodeja ja muuttujia, niin silloin perit Rectangle-luokan.
Olio-ohjelmoinnin perusteet pitää olla hallussa jos Javalla koodaa.
Nykyisen koodisi järjettömyys on siinä, että jokaista loogista oliota (laatikkoa) vastaa kaksi oliota (yksi Laatikko ja yksi Rectangle), joilla on vieläpä molemmilla samat muuttujat (sijainti). Koko keskustelun ajan sinulle on yritetty sanoa, että lähde liikkeelle luokasta Rectangle, joka sisältää valmiiksi kaipaamasi sijaintitiedot. Jos haluat lisätä ominaisuuksia, periytä oma Laatikko-luokkasi Rectangle-luokasta.
Muokkasin nyt tuon koodin, onko nyt parempi? Kiitos ohjeista.
No edelleenkin ne laatikot kannattaisi laittaa listaksi, jos niitä on tarkoitus tulla enemmän kuin kaksi.
Täytyykin sitten tutustua tuohon ArrayListiin. Entäs mikä olisi järkevä toteutus jos haluan tehdä seinät, esim. labyrintti, joihin tuo laatikko ei saa osua. Monta Rectanglea vai jotain muuta?
Ehkä monta Rectanglea on järkevä toteutus tai sitten ei. Johtuu mitä yrität tehdä ja kun me muut emme sitä tiedä niin...
Johan kerroin esimerkin labyrintti johon pelaajan liikuteltava rectangle ei saa osua. Onko seinät järkevä toteuttaa Rectanglella vai jollain muulla. Jos labyrintti on yhtään isompi niin rectangleja tulee aika kasa, tästä johtuen kysymys.
Mietitäänpä ensin, mitä oikeastaan kysyt ja miksi. Oletko pohtinut ongelmaa perusteellisesti itse? Mihin tulokseen tulit? Mitä muita ratkaisuja keksit (vaikka ihan kynällä ja paperilla mietittynä, ei tarvitse osata ohjelmoida)? Mitä hyviä ja huonoja puolia eri ratkaisuissa mielestäsi on?
Kyllä, jos seinät koostuvat suorakulmaisista laatikoista, ne on käytännöllistä kuvata ohjelmassakin suorakulmaisina laatikoina. Jos kuitenkin tarvitset enimmäkseen pyöreitä seiniä, laatikot eivät ehkä ole paras ratkaisu.
Olen koittanut pohtia ja todennäköisesti tässä tapauksessa järkevintä olisi piirtää pohja ja käyttää getrgb metodia. Mutta jos oletetaan että haluan tehdä tämän pelkästään koodia kirjoittamalla niin entäs sitten? Kysymyksen pointti oli pohjimmiltaan siinä kannattaako käsin kirjoittaa montaa rectanglea vai onko helpompi tapa generoida nuo seinät.
Jos haluat esimerkiksi lukea labyrintin kartan tiedostosta (myöhemmässä vaiheessa), niin kovakoodatut rectanglet asettaa aika kovat rajoitteet kartallesi ;). Itse käyttäisin listaa :)
Edit:
Labyrintin kartta voisi olla kaikessa yksinkertaisuudessaan esimerkiksi sarja pilkuilla eroitettuja lukuja (tämä siksi että voi helposti käsin editoida suoraan tiedostosta ja kaikki on suht ymmärrettävässä muodossa). 4 ensimmäistä pilkulla erotettua lukua pitävät sisällään esimerkiksi lähtöpisteen ja seuraavat 4 maalin, loput 4 luvun sarjat olisivat sitten seiniä.
sarjan kaksi ensimmäistä numeroa pitäisivät sisällään neliön vasemman yläkulman sijainnin (x,y) ja seuraavat kaksi leveyden ja korkeuden (width,height). Ja lähdöstä ja maalistahan ei tarvitse välttämättä muodostaa oma Rectanglea, vaan lähtö on se piste tai oikeammin alue mistä lähdetään liikenteeseen, ja kun saavutaan maali alueelle, on kenttä suoritettu.
Aihe on jo aika vanha, joten et voi enää vastata siihen.