Tetris - problem z GUI

0

Witam uprzejmie proszę o pomoc w kwestii GUI gry tetris. Do tej pory programowałem jedynie pod konsole (nawet nienajgorzej) ale teraz mam zrobić grę przy użyciu SWING'a. Problem polega na tym iż nie mam bladego pojęcia jakich klas użyć do wykonania części związanej z "tablicą" gry tzn. tym kawałkiem gdzie układa się klocki (i wyświetlaniem następnego klocka). Na razie w kwestii GUI i nie mam prawie nic (jedna JFrame z dwoma JPanel jeden na samą grę drugi na nast. klocek, punkty, itd.) Proszę więc o pomoc nie tyle od strony kodowej (choć jeśli ktoś ma czas to miło będzie jeśli wrzuci parę linijek kodu dla zobrazowania) a samego skruconego algorytmu i obiektów których powinienem użyć przy robieniu animacji (wielkie słowo - chodzi o po ruszanie się klocka)

Z góry dziękuje

0

Oczywiście niezależnie od tego, jakie GUI napiszesz, model powinien być oddzielony od GUI.

Co do rysowania klocków, to masz dwie możliwości:

  1. Każde pole to JLabel z ustawionym tłem lub ikoną w zależności od tego, czy jest zajęte, czy też nie.
    Te labele powinny być rozłożone na siatce prostokątnej, więc użyj JPanel + GridLayout
    http://java.sun.com/javase/6/docs/api/java/awt/GridLayout.html
    http://java.sun.com/docs/books/tutorial/uiswing/layout/grid.html

  2. Użycie JPanel ze zmienioną metodą paint(Graphics g)
    Poszczególne prostokąty możesz malować za pomocą metody drawRect(x, y, width, height).
    Pamiętaj tylko o wywołaniu metody repaint() na panelu, gdy zmienisz coś w modelu.

0

Myślałem o Gridzie i nawet zrobiłem coś o czy piszesz ale używałem JButton ("niepodłączonych" do niczego) no i napotkałem 2 problemy

  1. plansza ma mieć szer 10 wys 20 - po uruchomieniu wyświetlało mi jakieś 60-80 przycisków dopiero po kliknieciu na ramkę pojawiały się wszystkie

  2. Zrobie to na Label'u tak jak mówisz ale przypuszczam że niezniknie problem "zarządzania" tymi elementami (pod konsolą robiłem tablice i niebyło problemu ale jak mam tutaj napisać algorytm ruchu klocków - przecieŻ grid to nie tablica wiec jak sie odwołać do konkretnej etykiety ?)

0

Aby poruszyć klocki, nie musisz zmieniać pozycji labelów, wystarczy że zmienisz im kolor.
Problemem jest to, że klocek składa się z kilku kwadracików. Najprościej więc po każdym ruchu ustawiać na nowo kolor wszystkich kwadratów.

Jeżeli chodzi o dostawanie się do labeli, to możesz albo użyć metody getComponent, albo mieć dodatkową tablicę.

JLabel[][] labele = new JLabel[wys][szer];

for(int i=0;i<wys;i++)
  for(int j=0;j<szer;j++){
     JLabel label = new Label();
     panel.add(label);
     labele[i][j] = label;
}
0

Pięknie dziękuje [soczek]

dopiero zaczynam zabawe z GUI i niewiedziałem że można zrobić tablice JLabel [wstyd]

0

Kiedyś napisałem Tetrisa na J2ME. Utworzyłem macierz booleanów. True oznaczało że jest klocek, false że go nie ma. Co x milisekund klocek spadał o jeden wiersz niżej. Zmieniały się wtedy wartości z macierzy, a następnie rysowane były kwadraciki odpowiedniego koloru na Canvasie.

0

Agorytm i pomysł jak to zrobić to ja mam nie jest dla mnie problemem napisanie Tet pod konsole tylko z GUI sobie nie radze po prostu niewiem jak wsadzić taką macierz do np. JPanel
(otrzymuje błąd
cannot find symbol symbol : method add(javax.swing.JLabel[][],java.lang.String)
location: class java.awt.Container
cp.add(PLANSZA,BorderLayout.EAST);

gdzie

JLabel[][] PLANSZA = new JLabel[20][10];
cp - kontener )

0

__Krzysiek85 ci napisał, wsadzasz labele po jednym
Jakoś tak:

JLabel[][] PLANSZA = new JLabel[20][10];
JPanel panel=new JPanel();
panel.setLayouy(new GridLayout(20,10));
for(int i=0;i<20;i++)
  for(int j=0;j<10;j++){
     JLabel label = new Label();
     panel.add(label);
     PLANSZA[i][j] = label;
cp.add(panel,BorderLayout.EAST);
0

Wiem ale to mi się niekompiluje w ostatniej linii mam ten bład który wcześniej przedstawiłem - próbowałem to trochę przerobić ale dalej to samo po prostu niepotrafie dodać tablicy JLabel[][] do JFrame/JPanel

0

Wiem ale to mi się niekompiluje w ostatniej linii mam ten bład który wcześniej przedstawiłem - próbowałem to trochę przerobić ale dalej to samo po prostu niepotrafie dodać tablicy JLabel[][] do JFrame/JPanel

0

Teraz sie skompilowało ale okienko które się pojawia jest puste

0

A co bys chciał zobaczyć? Dodajesz przecież puste labele.

     JLabel label = new Label();
     if((i+j)%2==0)
         label.setBackground(Color.RED);
     else
         label.setBackground(Color.GREEN);
     panel.add(label);
0

Własnie te tabele chciałbym zobaczyć a tu nic :(

    public static void main(String[] args) {

		JFrame OKNO_GLOWNE = new JFrame("Tetris ");
		JLabel[][] PLANSZA = new JLabel[20][10];
		JPanel panel=new JPanel();
		
		
		OKNO_GLOWNE.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		OKNO_GLOWNE.setSize(600, 900);	
		OKNO_GLOWNE.setVisible(true); 
		
		Container cp = OKNO_GLOWNE.getContentPane();
		
		panel.setLayout(new GridLayout(20,10));
		for(int i=0;i<20;i++)
		  for(int j=0;j<10;j++){
			 JLabel label = new JLabel();
			if((i+j)%2==0)
				label.setBackground(Color.RED);
			else
				label.setBackground(Color.GREEN);
			panel.add(label);
			PLANSZA[i][j] = label;
			cp.add(panel,BorderLayout.EAST); // próbowałem też dla OKNO_GLOWNE
		}
          }

Cały czas mam puste szere okno i nic więcej

0

jak dam tak (co wydaje mi się sensowne bo przecież chce wyświetlić tablice)

cp.add(PLANSZA,BorderLayout.EAST);

to znów błąd cannot find symbol symbol : method add(javax.swing.JLabel[][],java.lang.String)

0

Ile razy trzeba Ci napisać, że dodawać labele należy pojedyńczo? Dopasuj do swoich potzreb poniższy kod.

import javax.swing.*;
import java.awt.*;

public class Test extends JFrame
{
    public static void main(String[] args) 
    {
        new Test();
    }
    //------------------------
    public Test()
    {
        super("Tetris");
        JLabel[][] PLANSZA = new JLabel[20][10];
        JPanel panel=new JPanel();


        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(600,600);
        setLocationRelativeTo(null);
        setVisible(true);


        panel.setLayout(new GridLayout(20,10));
        for(int i=0;i<20;i++)
            for(int j=0;j<10;j++)
            {
               JLabel label = new JLabel("      ");
               label.setOpaque(true);
               if((i+j)%2==0)
                   label.setBackground(Color.RED);
               else
                   label.setBackground(Color.GREEN);
               panel.add(label);
               PLANSZA[i][j] = label;
            }
        add(panel,BorderLayout.CENTER); // próbowałem też dla OKNO_GLOWNE
    }
}
0

Jestem naprawdze wdzięczny za pomoc i cierpliwość ale wiedz że pierwszy raz robie cokolwiek w GUI (troche czytałem ale niebardzo kumam co i jak) a co do Twojego kodu to mam z nim ten sam proble co z moim po uruchomieniu jest tylko szare okno, może to wina kompilatora (N++ najnowsze JDK)</image>

0

Co to jest N++?. Ja mam JDK 1.6.13.
Spróbuj uruchomic program z ręki (bez pośrednictwa IDE, jeśli z jakiegos korzystasz). Uruchom konsolę, przejdź do katalogu z plikiem Test.class i wpisz java Test.

0

Linię z "setVisible(true);" przenieś na sam koniec.

0

Tak teraz jest cudnie wielkie dzięki chyba już sobie poradzę [browar]

0
bogdans napisał(a)

Co to jest N++?

Notepad++ to nie jest IDE tylko rozbudowany notatnik podkreśla składnie, umożliwa kompilacje i uruchomienie jednym klawiszem i takie tam pierdoły

a problem rozwiązało to co napisał __Krzysiek85

0

Odpuść sobie n++, jakbyś używał jakiegoś porządnego IDE to byś nie miał tylu problemów.

0

Dziękuje Wam za pomoc bardzo mi pomogliście tetrisik już na ukończeniu został tylko jeden problem i jeden szczegół więc jeszcze raz (chyba ostatni) prosze o pomoc

Problem. Niepotrafie odpalić timer'a :-[ więc kolocki niechcą "same" spadać - klawiaturką wszystko jest super przesuwają się obracają itd. Niestety niechcę spadać same timer się kompiluje ale nic nierobi

((pseudo)kod pisany z głowy bo wtej chwili niemam go w programie - zgodniość z tym co próbowałem zrobić oceniam na min 95%)

graj {
Timer timer = new Timer(1000, this)
timer start;
if (czy_moge == true) ruch()
else nowy_klocek();
timer stop;

}

mniej więcej coś takiego mi się wymyśliło oczywiście bez błędów uniemożliwiających kompilacje

Szczegół. Zliczone punkty i inne tego typu informacje wyświetlam zapomocą JTextField i wszystko fajnie tylko że tam można sobie dopisać jakiś tekst (nie jest odczytywany wiec to nieproblem) ale chciałbym zablokować opcje bazgrania w tym elemencie. Powiniem go wymienić na jakiś inny obiekt czy tylko coś dopisać aby dało się go wypełniać tylko danymi wysłanymi przez program a nie wczytanymi z klawiatury ?

Z góry dziękuje

0

szczegół: tf.setEditable(false);

0

Wielkie dzięki :-)

a masz może jakiś pomysł na samo spadające klocki - niekoniecznie z użyciem timera (ja po prostu tak sobie wymyśliłem ale może jest jakieś lepsze albo nie lepsze ale działające rozwiązanie) ?

0

Nie znam całego kodu, ale dziwi mnie drugi argument w konstruktorze timera. Jak się nie obawiasz o prawa autorskie, to wyślij cały kod tu: [email protected].

0

O prawa autorskie sie nieobawiam bo napawde pisałem sam ale kod jest tak rozkopany że:

  1. normalnie sie wstydze [wstyd]
  2. jestem wdzięczny za pomoc ale niechce Ci zmarnować zbyt dużo czasu (a odnalezienie w nim czego kolwiek zajmie "chwilkę") :|

Pomęcze się wiec sam jeszcze trochę a jak naprawdę polegne to poproszę o pomoc a tym czasem może tak ujmę pytanie: "Czy gdybyś Ty robił takiego zwykłego tetrisa na zwykła jave (żadne J2ME) to czego byś użył do "automatyzacji" spadania klocków - właśnie clasy timer czy czegoś inngo ?"

ps. a drugi parametr zanlazłem w przykładach użycia timer'a i tylko tak mi się kompiluje

0

Chodziło mi o Twoje prawa autorskie. Też bym chyba użył timera.
Nie chodziło o to że jest drugi parametr, tylko o jego wartość.
Typowo tworzenie timerów wygląda tak:

        timer=new javax.swing.Timer(1000,new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
            	 // tutaj to co timer ma wykonać
            }
        });
0

O moje prawa autorskie tym bardziej się nie obawiam - w sieci napwno są dostępne znacznie lepsze kody ;]

Co do tworzenia timer'a to czytałem o tym rozwiązaniu ale jakoś niechciałem mieszać z AL już jeden mam w tej klasie więc szukałem innego rozwiązania bo jak wiesz dopiero zaczynam zabawę z GUI i trochę się jeszcze "boje" listener'ów - niby mi to działa ale nie jest to moja ulubiona klasa ;] Ale skoro to najlepsze rozwiązanie to popróbuje ;]

Jeszcze raz dzięki

1 użytkowników online, w tym zalogowanych: 0, gości: 1