JAVA – Jogo da Velha em Janela PARTE 1 de 2.

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

JAVA – Jogo da Velha em Janela PARTE 1 de 2.

Mensagem por Da Galáxia em Sab 29 Dez 2012, 12:16

IDE – NetBeans 7.1.1

O que vamos fazer:
Criaremos uma janela onde na parte 2 do tutorial jogaremos o jogo da velha contra o computador.
O computador fara jogadas aleatórias (não usaremos IA, pois uma IA desta, bem programada (sem usar logica FUZZI) envolve estrutura de dados como “Arvore” em jogadas MinMax e isto é um tema que por si só precisaria de um tutorial), se a jogada do computador “cair” em uma casa ocupada haverá novo “sorteio” para sua jogada.
O que vamos aprender:
Construir uma janela com componentes via código, aprenderemos alguns dos principais métodos desses componentes. Além do quê, aprenderemos a criar um programa simples, porem funcional em Java, onde muito dos conceitos usados será extremamente úteis (e necessários) em outros projetos.
Nosso jogo possuirá duas classes. Uma que vai controlar a parte visual e a outra vai controlar a parte lógica:
Controla a parte visual: classe “JogoDaVelhaVisual”
Controla a parte lógica: classe “JogoDaVelhaLogica” (esta veremos depois)
Abaixo explico como se cria um projeto no NetBeans 7.1.1, todavia pode haver algumas alterações em relação a outras versões. Mas o contexto é o mesmo, inclusive para a IDE Eclipse.
Vamos começar:

Crie um projeto:
Va em Arquivo depois Novo Projeto
Na tela que se abre:
Escolha a pasta Java à esquerda, e à direita escolha Aplicativo Java, click em próximo.
Agora no campo nome do projeto digite TutoJogoVelhaJanela. Ainda nesta tela abaixo, verifique se as caixinhas estão marcadas (v):
Criar Classe Principal e também Definir como Projeto Principal.
Vc tb verá na caixa de texto assim: tutojogovelhajanela.TutoJogoVelhaJanela,
Antes do ponto é o nome do pacote em que as classes ficarão, após o ponto é o próprio nome da classe (repare que tanto o nome do pacote quanto da classe possuem o mesmo nome do projeto, a classe começa com maiúsculo), é que aproveitou o nome do projeto. Mudaremos para: JogoDaVelha.JogoDaVelhaVisual
Agora click em finalizar.
Nosso pacote JogoDaVelha foi criado e dentro dele nossa classe JogoDaVelhaVisual.
Isto é fácil de observar no código, e tb à esquerda, na janela, onde se encontra o projeto.
Vejam bem:
Foi criado um ícone de uma xicara com o nome “TutoJogoVelhaJanela” esse é o nosso projeto, dentro dele tem o pacote de código fonte e dentro desse o nosso pacote “JogoDaVelha” dentro dele esta a nossa classe “JogoDaVelhaVisual”.
O código criado:

Código:
package JogoDaVelha;

/**
 *
 * @author Alex
 */
public class JogoDaVelhaVisual {

    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        // TODO code application logic here
    }
}



Explicando:
O nosso pacote:
package JogoDaVelha;
A nossa classe:
public class JogoDaVelhaVisual
O método principal (main)
public static void main(String[] args)
De alguma forma e existem muitas, é no método main(...) que o interpretador saberá onde inicia o programa. Para o interpretador não importa onde termina nosso programa, mas ele deve saber aonde começa. Como eu disse, existem varias formas e como verão, vou fazer a mais simples, que é instanciar a nossa classe principal dentro do método main(...). Esta classe que criamos é a classe principal (lembram que marcamos como tal ao criarmos o projeto?).

IMPORTANTE: Java como C/C++ são case-sensitive, ou seja, fazem distinção de maiúscula e minúscula, ex: a variável int valor é diferente de int Valor ou vAlor.
Continuando...
Para visualizarmos melhor o código gerado, vamos apagar os comentários, e criar os nossos. O código fica assim:

Código:
package JogoDaVelha;

// Classe.
public class JogoDaVelhaVisual {

    // Metódo principal.
    public static void main(String[] args) {
     
    }

}// Fim classe.



Bem, o que vamos fazer é uma janela e dentro desta, componentes como botões e caixa de texto.
Serão 10 botões. 1 para re-iniciarmos o jogo após termino de uma partida os outros 9 botoes serão as 9 casas que simularão o tabuleiro da velha, ao clicar em um dos botões/casa do tabuleiro será marcado um X (xis) na vez do jogador, e na vez do computador será marcado um O (oh, ou bolinha se preferir). A caixa de texto nos emitira informações como: “Vez do Computador” ou “O Jogador Venceu”. Também vamos criar um componente onde serão adicionados os botões e a caixa de texto.
Vamos lá então:
É-nos oferecido uma classe chamada JFrame (J de java e Frame é quadro) que possui varias chamadas de métodos para com facilidade criarmos nossa janela. Novamente me sinto na obrigação de dizer, existem varias maneiras de se fazer o que estamos prestes a fazer, todavia, escolhi o que no meu ponto de vista é a mais pratica quiçá correta de se fazer.
Vamos estender a classe JFrame a nossa classe, ou seja, herdaremos a classe JFrame, com isto, podemos usar todos os métodos da classe JFrame sem precisar instanciar um objeto para ela, como faremos com os outros componentes. Vejam:


Código:
package JogoDaVelha;


// Classe.
public class JogoDaVelhaVisual extends JFrame {

    // Metódo principal.
    public static void main(String[] args) {
     
    }


}// Fim classe.


JFrame ficou sublinhado em vermelho, pois não fizemos o importe do pacote aonde se encontra esta classe. Vamos resolver:
Selecione a classe JFrame (como se seleciona uma palavra no Word) agora pressione as teclas ALT e ENTER. Apareceu uma janela com provavelmente 3 soluções click em “Adicionar Importe para Javax.swing.JFrame”, veja que abaixo do “package JogoDaVelha;” aparece a linha “import javax.swing.JFrame;” e o “problema” foi resolvido. Explicando:
Importe é a sintaxe de java para trazer uma biblioteca, como “Uses” em Delphi e “include” em C e C++. Javax é a biblioteca (tem outra importante quando trabalha-se com componentes, que é a Java. Javax é mais recente, veio para corrigir algumas deficiências de alguns componentes da Java). Swing é o pacote onde tem varias classes, uma delas é esta JFrame.

Ok, agora vamos criar um construtor para a nossa classe. O Construtor de uma classe é usado para iniciar variáveis e chamar métodos, mas ele faz isto apenas em tempo de compilação, ou seja, não é acionado run time, apenas uma vez, ao entrarmos no programa e/ou jogo. Nosso construtor será um construtor default, ou seja, ele não terá parâmetros (argumentos). Muitas vezes construtores como esse nosso nem precisa ser construídos, pois a IDE cria um construtor default “invisível” aos olhos do programador, mas como queremos usar o método main(...) apenas para instanciar nossa classe, vamos construí-lo, e também para efeito de aprendizagem. Outra coisa sobre os construtores é que eles sempre possuem o nome de sua classe e nunca possuem retorno, nem mesmo nulo. Isto os difere dos métodos.
Vejam nosso código com o construtor.


Código:
package JogoDaVelha;

import javax.swing.JFrame;


// Classe.
public class JogoDaVelhaVisual extends JFrame {

    // Metódo principal.
    public static void main(String[] args) {
     
    }

    // Construtor.
    public JogoDaVelhaVisual() {
       
       
       
    }// Fim construtor.



}// Fim classe.


Beleza, agora vamos usar as chamadas dos métodos do JFrame, para criarmos a janela. Esses métodos serão criados dentro do construtor.
Vamos fazer o primeiro para fim didático, pois quero falar sobre o operador “this” depois passo todos de uma vez.
Digite (dentro do construtor) this. (ao digitar o ponto abrira uma tela lotado de métodos) todos esses métodos são do JFrame . O operador “this” acessa os atributos de sua classe, e como herdamos a classe JFrame foi o que ele fez. Vamos fazer um teste. Acima do construtor criem a linha public int minhaVariavel; (int = variável do tipo inteiro) se agora vc usar this. a variável aparece juntamente com os métodos do JFrame, pois ela pertence a nossa classe “JogoDaVelhaVisual”.
Mas neste tutorial não vamos ter que usar este operador, apenas usem-no (se quiserem) para facilitar a encontrar os métodos.

Apaguem a variável.

Segue todos os métodos necessários para a construção da nossa janela (estão comentados no código)
Coloque dentro do construtor.

Código:

        /*Propriedades do objeto janela (classe JFrame que foi extendido (herança) a nossa classe)*/
        this.setSize(300, 400);
        // Posiciona a janela no centro do PC.
        this.setLocationRelativeTo(this);
        // Não se pode alterar o tamanho da janela esticando-a com o mouse.
        this.setResizable(false);
        // Titulo na janela.
        this.setTitle("Jogo da Velha");
        // Visualizar a janela.
        this.setVisible(true);
        // IMPORTANTE: Se não usar, mesmo fechando a janela, o aplicativo continua na memória.
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);


Nesses casos se retirarem o “this” não faz diferença.

BOM SABER: Os métodos que iniciam em set (que significa algo como por, colocar) indicam que os métodos são, digamos “ativos”, este método this.setSize(300, 400); diz que a janela tem este tamanho, esses métodos sempre tem um ou mais parâmetros (argumentos) e nunca, jamais possuem retorno, são sempre void. Se eu não me enganar, nas duas partes do tutorial usaremos apenas métodos set.
Já métodos get (algo como adquirir, receber) sempre possuem retorno e nunca possuem parâmetros. Os métodos is são como os gets, todavia seu retorno é apenas boleano.
Senti na obrigação de levantar estes conceitos mesmo que vão ser irrelevantes para nosso tutorial, pois, acreditem em mim, isto é de suma importância, no futuro vocês verão, e quando chegar vão ter uma noção mesmo que mínima que seja sobre esses conceitos.
Continuando...
Se vc mandar rodar o código( seta verde no topo da IDE) ou << Executar << Executar Projeto Principal. Nada acontece. Percebe que faltou algo? É que não passamos nada no método main(...), vamos instanciar nossa classe dentro do main(...), veja:
new JogoDaVelhaVisual();

Nosso código completo ate agora, esta assim:

Código:
package JogoDaVelha;

import javax.swing.JFrame;


// Classe.
public class JogoDaVelhaVisual extends JFrame {
   
    // Metódo principal.
    public static void main(String[] args) {
     
        new JogoDaVelhaVisual();
    }
 
    // Construtor.
    public JogoDaVelhaVisual() {
   
        /*Propriedades do objeto janela (classe JFrame que foi extendido (herança) a nossa classe)*/
        this.setSize(300, 400);
        // Posiciona a janela no centro do PC.
        this.setLocationRelativeTo(this);
        // Não se pode alterar o tamanho da janela esticando-a com o mouse.
        this.setResizable(false);
        // Titulo na janela.
        this.setTitle("Jogo da Velha");
        // Visualizar a janela.
        this.setVisible(true);
        // IMPORTANTE: Se não usar, mesmo fechando a janela, o aplicativo continua na memória.
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
       
       
    }// Fim construtor.

}// Fim classe.


Mande rodar e vera que funcionou (Uma tela com fundo cinza claro).

OBS: Se vc passar o mouse em new JogoDaVelhaVisual(); recebera uma informação que é: nova instancia ignorada. É que a IDE quer que seja instanciado um objeto e foi apenas a classe. Então poderá mudar para: JogoDaVelhaVisual meuObj = new JogoDaVelhaVisual();
Mas se passar o mouse em meuObj recebera a informação: nova instancia não é usada. Nenhuma destas duas situações tem importância (pelo menos nunca teve pra mim, e já fiz muita coisa), é que o IDE é muito informativo, o que é muito bom. Mas se essas situações os incomodarem podem fazer assim:
Dentro do construtor apague a linha de código this.setVisible(true);
E dentro do método main(...) troque a linha de código que esta lá por:
new JogoDaVelhaVisual().setVisible(true);
Pronto, a IDE se conformou.
Mostrei isto, para perceberem como há varias maneiras (tem outras) de se fazer, isto lhes facilitaram quando ler outros artigos.

Agora vamos criar os componentes.
Acima do construtor coloque:
Código:
// Variaveis de instancias (Já instanciadas "new").
    private JPanel      objFundo      = new JPanel();
    public  JButton[][] objTabuleiro  = new JButton[3][3]; // Matriz.
    public  JButton    objIniciar    = new JButton("RE-INICIAR");
    public  JTextField  objMsg        = new JTextField();

Vai aparecer uma tela, dê OK e veja que foi como com o JFrame.

Ta certo, ninguem ainda falou de public nem private, vamos lá então:
Uma variável ou método publico, significa que pode vir a serem acessados em outra classe que não somente a sua, quando privado apenas pode ser acessado dentro da própria classe. Na segunda parte do tutorial isto vai ficar claro.
Explicando:
private JPanel objFundo = new JPanel();
JPanel é a classe e objFundo é o nome do nosso objeto que ao ter sido instanciado (new) vai acessar seus métodos, é privado pois sei que não vou relaciona-lo em nada na futura classe (Tuto parte 2). Ele vai nos servir de contêiner para nossos componentes, nossos outros componentes serão alinhados em sua superfície. No código completo cada linha inédita será comentada com uma explicação, e ficara mais claro.
A explicação acima com exceção da parte de conter os objetos servem para:
public JButton objIniciar = new JButton("RE-INICIAR");
public JTextField objMsg = new JTextField();
Todavia de alguma forma sei que vou relaciona-los na futura classe, por isso são públicos.

public JButton[][] objTabuleiro = new JButton[3][3]; // Matriz.
Essa linha acima é mais complexa. Serão criados 9 botões de uma só vez, será uma matriz 3x3, como 3x3 é o tabuleiro do jogo da velha.
Abaixo do fechar } do construtor vamos criar um método privado chamado iniciarComponentes. É um método simples, sem parâmetros nem retorno, e depois de implementado será chamado no construtor. Vejam:
Código:
private void iniciarComponentes() {
       
       
       
       
}// Fim metodo.

E dentro deste método vamos aos poucos implementar códigos, todas as linhas inéditas são comentadas, por isso vou fazer apenas algumas ressalvas.
Código:
 /*Propriedades do objeto fundo*/
        // Adicionar no JFrame (extensão da classe).
        this.add(objFundo);  // Se quiserem podem retirar o this.             
        objFundo.setBackground(Color.black);// Cor de fundo usando uma macro pra cor.

As janelas que aparecerem deem OK, são os pedidos dos importes.

Vejam como é simples: Adicionamos ao JFrame o objFundo, ao objFundo chamamos o método que lhe da a cor. E segue este contexto até o fim.
Continuando...

Código:
    /*Propriedades do objeto botão iniciar*/
        //Dimensões
        objIniciar.setSize(250, 60);   
        Dimension db = objIniciar.getSize();
        objIniciar.setPreferredSize(db);
        objIniciar.setBackground(Color.red);
        objIniciar.setFont(new Font("arial", 1, 30));
        // Ao passar o ponteiro do mouse em cima do botão, escreve uma informação.
        http://objIniciar.setToolTipText("Re-iniciar Partida");
        objFundo.add(objIniciar); 

      /*Propriedades do objeto botão matriz*/
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                // Instanciar a matriz.
                objTabuleiro[i][j] = new JButton();   
                // Dimensões desejadas (x e y).
                objTabuleiro[i][j].setSize(80, 80);   
                // Setar dimensão.
                Dimension dm = objTabuleiro[i][j].getSize();
                // Usar dimensão.
                objTabuleiro[i][j].setPreferredSize(dm);
                // Cor usando macro.
                objTabuleiro[i][j].setBackground(Color.white);
                // Adicionar no objFundo.
                objFundo.add(objTabuleiro[i][j]);   
               
            }
           
        }




OBS: objTabuleiro[i][j] = new JButton();
Este componente possui uma nova instancia (new), pois no inicio do programa instanciamos uma matriz para os componentes e aqui criamos estes componentes.

Continuando...

Código:
    /*Propriedades do objeto objMsg*/
        // Cor trabalhando RGB diretamente no parâmetro do metódo.
        objMsg.setBackground(new Color(0, 100, 0));
        // Cor dos caractere.
        objMsg.setForeground(Color.white);
        objMsg.setFont(new Font("arial", 1, 22));
        // Iniciar com mensagem.
        objMsg.setText("Vez do Player");
        // Anular entrada do teclado no text field.
        objMsg.setEditable(false);
        /*Dimensões*/
        objMsg.setSize(250, 40);
        Dimension dtf = objMsg.getSize();
        objMsg.setPreferredSize(dtf);
        // Adicionar no objHUD.
        objFundo.add(objMsg);



Beleza, se mandarmos rodar (seta verde no topo da IDE) apenas a janela aparece, pois tudo dos componentes esta no método, e temos que “ligar” ou fazer “escutar” este método ao nosso programa, para isto neste caso basta chama-lo dentro do construtor. Assim:
Abaixo da linha: this.setDefaultCloseOperation(EXIT_ON_CLOSE); coloque:
// Chamar metódo.
iniciarComponentes();

EM TEMPO: Se quiserem podem substituir as linhas:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
por:
import javax.swing.*;

Mas não acho legal, pois apenas de olharmos para os importes sabemos os componentes que estamos usando, quando formos, outro dia mexer no código.

LEMBRE-SE apenas a parte visual programamos nós (como diria mestre Yoda) a parte lógica fica para a 2° e ultima parte do tutorial. Qualquer coisa é só postar.

NÂO ME CONTIVE, EM TEMPO 2:

Vou dar um exemplo de uma boa utilidade do operador this. E mostrar métodos get e set (não precisam ter esses nomes é apenas convenção).

public class BlaBlaBla {
private int valor;

public int getBla() {
return valor;
}

public void setBla(int valor){
this.valor = valor;
}

}
Reparem que eu tenho uma variável valor e um método com parâmetro valor, o valor após this refere-se a variável da classe, dentro de um método o this acessa uma variável fora do mesmo, ainda que tenham o mesmo nome e o compilador sabe perfeitamente o que esta acontecendo. Em um caso destes a variável passa a ter o valor que o parâmetro do método tiver. E como o método get retorna a variável, ligamos tudo, não precisamos referir nada a variável, por isso ela é privada. Temos 2 métodos, o que passa o valor (set) e o que recebe o valor(get). Esta forma de programar é excelente quando programamos juntamente com banco de dados.

SEGUE NOSSO CODIGO COMPLETO:

Código:
package JogoDaVelha;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

// Classe.
public class JogoDaVelhaVisual extends JFrame {
   
    // Metódo principal.
    public static void main(String[] args) {
     
        new JogoDaVelhaVisual().setVisible(true);
    }

    // Variaveis de instancias (Já instanciadas "new").
    private JPanel      objFundo      = new JPanel();
    public  JButton[][] objTabuleiro  = new JButton[3][3]; // Matriz.
    public  JButton    objIniciar    = new JButton("RE-INICIAR");
    public  JTextField  objMsg        = new JTextField();
   
    // Construtor.
    public JogoDaVelhaVisual() {
   
        /*Propriedades do objeto janela (classe JFrame que foi extendido (herança) a nossa classe)*/
        this.setSize(300, 400);
        // Posiciona a janela no centro do PC.
        this.setLocationRelativeTo(this);
        // Não se pode alterar o tamanho da janela esticando-a com o mouse.
        this.setResizable(false);
        // Titulo na janela.
        this.setTitle("Jogo da Velha");
        // Visualizar a janela.
        this.setVisible(true);
        // IMPORTANTE: Se não usar, mesmo fechando a janela, o aplicativo continua na memória.
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
       
        // Chamar metódo.
        this.iniciarComponentes();// Se preferir tirem o this.
         
    }// Fim construtor.
   
    private void iniciarComponentes() {
       
        /*Propriedades do objeto fundo*/
        // Adicionar no JFrame (extensão da classe).
        this.add(objFundo);               
        objFundo.setBackground(Color.black);// Cor de fundo usando uma macro.
       
        /*Propriedades do objeto botão iniciar*/
        //Dimensões
        objIniciar.setSize(250, 60);   
        Dimension db = objIniciar.getSize();
        objIniciar.setPreferredSize(db);
        objIniciar.setBackground(Color.red);
        objIniciar.setFont(new Font("arial", 1, 30));
        // Ao passar o ponteiro do mouse em cima do botão, escreve uma informação.
        http://objIniciar.setToolTipText("Re-iniciar Partida");
        objFundo.add(objIniciar);
       
        /*Propriedades do objeto botão matriz*/
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                // Instanciar a matriz.
                objTabuleiro[i][j] = new JButton();   
                // Dimensões desejadas (x e y).
                objTabuleiro[i][j].setSize(80, 80);   
                // Setar dimensão.
                Dimension dm = objTabuleiro[i][j].getSize();
                // Usar dimensão.
                objTabuleiro[i][j].setPreferredSize(dm);
                // Cor usando macro.
                objTabuleiro[i][j].setBackground(Color.white);
                // Adicionar no objFundo.
                objFundo.add(objTabuleiro[i][j]);   
               
            }
           
        }
       
        /*Propriedades do objeto objMsg*/
        // Cor trabalhando RGB diretamente no parâmetro do metódo.
        objMsg.setBackground(new Color(0, 100, 0));
        // Cor dos caractere.
        objMsg.setForeground(Color.white);
        objMsg.setFont(new Font("arial", 1, 22));
        // Iniciar com mensagem.
        objMsg.setText("Vez do Player");
        // Anular entrada do teclado no text field.
        objMsg.setEditable(false);
        /*Dimensões*/
        objMsg.setSize(250, 40);
        Dimension dtf = objMsg.getSize();
        objMsg.setPreferredSize(dtf);
        // Adicionar no objHUD.
        objFundo.add(objMsg);

    }// Fim metodo.

   
}// Fim classe.




Da Galáxia

Número de Mensagens : 348
Data de inscrição : 14/01/2010
Reputação : 1
Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Prêmios
   : 0
   : 0
   : 0

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum