Aplety - Kółko i krzyżyk


Aplety - Kółko i krzyżyk

No to napiszemy sobie grę, która może uatrakcyjnić naszą stronę internetową. Zanim zaczniemy powinieneś/powinnaś zapoznać się z podstawami pisania apletów. Grą tą będzie kółko i krzyżyk, więc zastanówmy się jakich obiektów potrzebujemy.
1. Na pewno musi być jakiś element, który będzie pokazywał jaki jest stan gry(czyja kolej, kto wygrał). Wykorzystamy do tego metodę paint(), która narysuje nam informację o tym.
2. Teraz plansza do gry podzielona na 9 pól. Zrobimy ją z 9 przycisków button.
3. Jeszcze przyda się opcja rozpoczęcia gry od nowa, czyli jeszcze jeden przycisk.
Takie założenia przyjąłem ja gdy postanowiłem napisać tą gierkę, więc myślę że na początek to wystarczy. Na samym początku należy importować dwie klasy, które są bardzo często używane w apletach, mianowicie:


import java.awt.*;      // ta pozwala na umieszczanie przycisków itd.
import java.awt.event.*;  // ta pozwala na obsługę zdarzeń
 

u mnie plik z grą to kik.class więc piszę:
public class kik extends Applet implements ActionListener { // kik dziedziczy bezpośrednio z //klasy Applet i implementujemy klasę nasłuchującą zdarzenia(ActionListener)
 

Jest to niezbędne aby nasz program mógł reagować na zdarzenia(aby po kliknięciu pojawiło się na przycisku O lub X itd.). Teraz utworzymy zmienną, która będzie przechowywać stan gry:
String user = "O"; // grę będzie zaczynało kółko
 

Następnie należy zadeklarować obiekty - przyciski:
Button b1 = new Button(),
    b2 = new Button(),
    b3 = new Button(),
    b4 = new Button(),
    b5 = new Button(),
    b6 = new Button(),
    b7 = new Button(),
    b8 = new Button(),
    b9 = new Button(),
    we = new Button("Nowa Gra");

chyba można się domyślić, które przyciski do czego służyć nam będą. Teraz z przycisków zrobimy planszę( wrzucimy je do kontenera):
GridLayout - rozmieszczenie siatkowe, polega na rozmieszczeniu komponentów w prostokątnej siatce o podanej liczbie kolumn i wierszy; wszystkie klatki tej siatki mają identyczne rozmiary,

Panel gridLayoutPanel()
{
  Panel panel = new Panel();
  panel.setLayout(new GridLayout(3,3));>  // trzy kolumny i trzy wiersze(razem 9 pól)
  panel.add(b1); panel.add(b2); panel.add(b3);        //dodajemy przyciski
  panel.add(b4); panel.add(b5); panel.add(b6);
  panel.add(b7); panel.add(b8); panel.add(b9);
  return panel;
}

Teraz wywołamy metodę paint(), która będzie nam pokazywać jaki jest stan gry:

public void paint(Graphics g) //przykrywamy metodę paint()
 {
  g.drawString(user, 140, 70);        // wyświetla wartość Stringa user
  g.drawString("Stan gry/kolej:", 40, 70); //wyświetla napis do wartości user
} // aby gracz się nie pogubił ;)
 

Przyszła pora na inicjalizację apletu:
public void init() {
        Panel panel = gridLayoutPanel();
        setLayout(new BorderLayout());
        add("South",panel);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        b4.addActionListener(this);
        b5.addActionListener(this);
        b6.addActionListener(this);
        b7.addActionListener(this);
        b8.addActionListener(this);
        b9.addActionListener(this);
    add("North",we);
    we.addActionListener(this);
    }

Na początku wrzucamy do apletu naszą planszę (panel), następnie każdy przycisk ustawiamy aby nasłuchiwał zdarzeń( aby mógł na nie reagować). Na końcu wrzucamy przycisk Nowa Gra i ustawiamy dla niego także ActionListener. Mamy już ustawione wszystko jeśli chodzi o interfejs graficzny naszej gry. Teraz należy oprogramować wciskanie przycisków. Do roboty:
public void actionPerformed(ActionEvent e) {
przesłonięcie metody actionPerformed, w tej części obsługuje się zdarzenia.
if(e.getSource() instanceof Button)
{
        System.out.println(((Button)e.getSource()).getLabel());

Tutaj pobieramy tzw. etykietę przycisku.
getSource() - informuje jaki przycisk został wciśnięty
getLabel() - informuje jaki jest napis na przycisku
dodam jeszcze bo się nam przyda:
setLabel() - ustawia teks na przycisku
Teraz obsłużymy ustawianie krzyżyka lub kółka na przycisku w zależności od graczy i tego czy na przycisku nie ma już jakiegoś znaku.

if (((Button)e.getSource()).getLabel()=="" &&  user == "X") { //jeśli nie ma napisu na                                                   //       przycisku, a jest kolej krzyżyka to
((Button)e.getSource()).setLabel("X");       //umieść na przycisku X
user = "O";                                        // zmień gracza na O
 repaint(); }                // przemaluj( bez tego nazwa zmiennej by się zmieniła ale napis nie)

if (((Button)e.getSource()).getLabel()=="" &&  user == "O") {
((Button)e.getSource()).setLabel("O");
user = "X";
repaint(); }

No i teraz zostało nam jedynie sprawdzanie czy ktoś nie wygrał oraz obsłużenie przycisku NOWA GRA.
if (((Button)e.getSource()).getLabel()=="Nowa Gra") {        // jeśli wciśnięto nowa gra
  b1.setLabel(""); b2.setLabel(""); b3.setLabel(""); b4.setLabel("");
  b5.setLabel(""); b6.setLabel(""); b7.setLabel(""); b8.setLabel("");
  b9.setLabel("");
  user = "O"; repaint();
}      // wyczyść napisy na przyciskach oraz ustaw wartość user na początkową
 

I teraz najdłuższa część. Należy sprawdzić wszystkie możliwości w jakich ktoś może wygrać:
if (b1.getLabel() == "X" && b2.getLabel() == "X" && b3.getLabel() == "X") {
    user = "wygrał X"; repaint();
  }  else
    if (b4.getLabel() == "X" && b5.getLabel() == "X" && b6.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b7.getLabel() == "X" && b8.getLabel() == "X" && b9.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b1.getLabel() == "X" && b5.getLabel() == "X" && b9.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b3.getLabel() == "X" && b5.getLabel() == "X" && b7.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b1.getLabel() == "X" && b4.getLabel() == "X" && b7.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b2.getLabel() == "X" && b5.getLabel() == "X" && b8.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else
    if (b3.getLabel() == "X" && b6.getLabel() == "X" && b9.getLabel() == "X") {
    user = "wygrał X"; repaint();
    }  else

    if (b1.getLabel() == "O" && b2.getLabel() == "O" && b3.getLabel() == "O") {
user = "wygrało O"; repaint();
}  else
    if (b4.getLabel() == "O" && b5.getLabel() == "O" && b6.getLabel() == "O") {
    user = "wygrało O"; repaint();
    }  else
    if (b7.getLabel() == "O" && b8.getLabel() == "O" && b9.getLabel() == "O") {
    user = "wygrało O"; repaint();
    }  else
    if (b1.getLabel() == "O" && b5.getLabel() == "O" && b9.getLabel() == "O") {
    user = "wygrało O"; repaint();
    }  else
    if (b3.getLabel() == "O" && b5.getLabel() == "O" && b7.getLabel() == "O") {
    user = "wygrało O"; repaint();
    }  else
    if (b1.getLabel() == "O" && b4.getLabel() == "O" && b7.getLabel() == "O") {
    user = "wygrało O"; repaint();
    }
          else
    if (b2.getLabel() == "O" && b5.getLabel() == "O" && b8.getLabel() == "O") {
    user = "wygrało O"; repaint(); }
    else
    if (b3.getLabel() == "O" && b6.getLabel() == "O" && b9.getLabel() == "O") {
    user = "wygrało O"; repaint();
    } else if (b1.getLabel() != "" && b2.getLabel() != "" && b3.getLabel() != "" &&
      b4.getLabel() != "" && b5.getLabel() != "" && b6.getLabel() != "" &&
      b7.getLabel() != "" && b8.getLabel() != "" && b9.getLabel() != "")
    { user ="REMIS !!!"; }


Na końcu jeżeli żaden z warunków nie jest spełniony, a jednak wszystkie przyciski są "zapisane" to wyskakuje słówko REMIS!!! To wszystko jest może długim kodem ale za to bardzo prostym. Jeśli trzy przyciski o tym samy napisie leżą w jednej linii to wtedy wyskakuje odpowiedni napis:
 

if (b3.getLabel() == "O" && b6.getLabel() == "O" && b9.getLabel() == "O") {
    user = "wygrało O"; repaint();

użyto tu operatora && aby otrzymać informacje czy trzy przyciski tworzące jedną linię mają ten sam napis("O").        W przypadku jakiś wątpliwości proszę pisać do mnie.


Może na koncu podam cały kod tak na wszelki wypadek :).
( w dziale Kody źródłowe - Java)
Informacje
Ostatnia modyfikacja 12-01-2010 14:06 Ostatni autor Koziołek
Ilość wyświetleń 29628 Wersja 3
Komentarz
prezi84 dnia 19-12-2009 00:06
sprawdzanie wszystkich warunków przy korzystaniu z tablic wygląda tak:
        public boolean isWinner(String s) {
                if( (b[0].getLabel() == s && b[1].getLabel() == s && b[2].getLabel() == s) ||
                        (b[3].getLabel() == s && b[4].getLabel() == s && b[5].getLabel() == s) ||
                        (b[6].getLabel() == s && b[7].getLabel() == s && b[8].getLabel() == s) ||
                        (b[0].getLabel() == s && b[4].getLabel() == s && b[8].getLabel() == s) ||
                        (b[2].getLabel() == s && b[4].getLabel() == s && b[6].getLabel() == s) ||
                        (b[0].getLabel() == s && b[3].getLabel() == s && b[6].getLabel() == s) ||
                        (b[1].getLabel() == s && b[4].getLabel() == s && b[7].getLabel() == s) ||
                        (b[2].getLabel() == s && b[5].getLabel() == s && b[8].getLabel() == s) )
                        return true;
                return false;
        }
i wywołanie
                if(isWinner(krzyzyk)) { napis = "wygrał "+krzyzyk; repaint(); } else
                if(isWinner(kolko)) { napis = "wygrało "+kolko; repaint(); }  else
                for(int i=0; i<9; i++) {
                        if(b[i].getLabel() == "")
                                break;
                        if(i==8) napis ="REMIS !!!";
                }
Cały program przy korzystaniu z tablic i małej optymalizacji zajmuje niecałe 70 linii

@Programista312 - jakie łatwiejsze sposoby niby są niż sprawdzanie tych raptem 8 warunków? Toż nawet stworzenie pętli, sprawdzającej czy tokeny są ustawione w rzędach lub kolumnach zajmie więcej niż 8 linii kodu.
prezi84 dnia 18-12-2009 02:19
działa fajnie, doskonały pomysł z tymi przyciskami
jednak kod strasznie nadmiarowy - można to znacznie krócej napisać, np. używając tablic:
Button [] b = new Button[9];
i wszędzie stosować pętle:
      for(int i=0; i<9; i++)
              b[i] ...
sprawdzanie warunków też wtedy można znacznie uprościć
Programista312 dnia 01-01-2009 22:17
Wypisywać wszystkie kombinacje ,są łatwiejsze sposoby!
longman dnia 28-05-2006 14:48
działa, ale jak by wyglądał kod z jakimś gif'em jako plansza i rysowanymi "o" i "x"? Ile z tego pozostanie kodu?
longman dnia 28-05-2006 14:46
działa, ale jak by wyglądał kod z jakimś gif'em jako plansza i rysowanymi "o" i "x"? Ile z tego pozostanie kodu?
pawel123 dnia 11-05-2006 09:19
Dzięki za kik ;D a ma ktoś może grę w statki napisaną w Javie? Bo potrzebuje na zaliczenie. Byłbym wdzięczny za przesłanie na maila winch@op.pl z góry dzieki. Pozdr ;D
pawel123 dnia 11-05-2006 09:18
Dzięki za kik ;D a ma ktoś może grę w statki napisaną w Javie? Bo potrzebuje na zaliczenie. Byłbym wdzięczny za przesłanie na maila winch@op.pl z góry dzieki. Pozdr ;D
pawel123 dnia 11-05-2006 09:15
Dzięki za kik ;D a ma ktoś może grę w statki napisaną w Javie? Bo potrzebuje na zaliczenie. Byłbym wdzięczny za przesłanie na maila winch@op.pl z góry dzieki. Pozdr ;D
dawciobiel dnia 22-11-2004 06:19
juz ok, dodałem tam jeszcze
"import java.applet.*;"
i stworzyłem kik.html :
"<APPLET CODE="kik.class" WIDTH="250" HEIGHT="250"></APPLET>"
dawciobiel dnia 20-11-2004 21:14
a mi sie nie chce bydle skompilowac.
"Cannot find symbol. class Applet" (kompiluje pod NetBeans IDE 4.0 Beta 2), ale pod kompilatorem konsolowym tez sie nie chce i jest to samo :(

(dawciobiel@kozmianet.kom.pl)
jaro. dnia 10-05-2004 14:59
Dziekuje,

dla mnie się przydał!

Na jego podstawie zaliczylem applet dla uniwerku.
MrGhost dnia 25-10-2003 11:35
Bardzo dobry artykuł...
RiccoXXX dnia 11-06-2003 20:56
Czytelnosc mniej istotna, sam artykul calkiem dobry.
Marooned dnia 03-05-2003 11:11
Cały kod w znacznikach &lt; b > - bardzo nieczytelny.

Katalog
Copyright © 2000-2006 by Coyote Group 0.9.3-pre3
Czas generowania strony: 0.5788 sek. (zapytań SQL: 9)