quinta-feira, 13 de junho de 2013

[Tutorial] [Java] Jogo Invasores do Espaço - Parte 1

Hello people! Agora vamos ver um jogo diferente de Tetris, e Snake, TCHAAARÃN! O jogo é Invasores do Espaço, relativamente simples, entretanto com recurso de vilões ( MUAHAHAHA ) e vilões inteligentes. Esse tutorial vai dar a base para entender o funcionamento do comportamento entre classes diferentes, e permitir o desenvolvimento completo do jogo Pacman em Java, e continuação do desenvolvimento do Jogo em Plataforma (C#). Bom, basicamente para esse projeto teremos as seguintes classes:

InvasoresDoEspaco (principal, JFrame) - Exibe o jogo na tela
Grade (JPanel) - Controla todos processos do jogo

Comuns - Contém todas variáveis globais do jogo
Alienígenas - Controla os vilões do jogo
Jogador - Controla a nave principal do jogo
Tiro - Controla os tiros da nave pelo espaço do jogo
Desenho - Manipula o desenho de cada objeto do jogo

Para esse tutorial desenvolveremos as classes, na respectiva ordem, Comuns, Desenho, Alienígenas, Jogador e Tiro. Para o próximo tutorial desenvolveremos a Grade do jogo, juntamente com a classe principal.

CLASSE COMUNS

A classe Comuns, contém todas variáveis fixas do jogo. Vamos analisar o código abaixo ( lembrem-se de se atentar a todos comentários que faço durante o código ).

package INVASORESDOESPACO;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: COMUNS
 * OBJETIVO: DEFINE AS VARIÁVEIS GLOBAIS DO JOGO
 *
 */

public interface Comuns
{

    // TAMANHO DA TELA
    public static final int LARGURA = 358;
    public static final int ALTURA = 350;

    // TAMANHO DA BASE DO JOGO
    public static final int BASE = 290;

    // ALTURA DA BOMBA
    public static final int BOMBA_HEIGHT = 5;

    // TAMANHO DO ALIENIGINA
    public static final int ALIEN_HEIGHT = 12;
    public static final int ALIEN_WIDTH = 12;

    // DEFINIÇÕES DA BORDA
    public static final int BORDA_DIREITA = 30;
    public static final int BORDA_ESQUERDA = 5;

    // VELOCIDADE DE DESLOCAMENTO GRAVITACIONAL
    public static final int VAI_ABAIXO = 15;

    // QUANTIDADE DE ALIENS
    public static final int NUMERO_DE_ALIENS = 24;

    // CHANCES DISPONÍVEIS
    public static final int CHANCES = 5;

    // DEFINIÇÃO DO DELAY
    public static final int DELAY = 17;

    // TAMANHO DO JOGADOR
    public static final int JOGADOR_WIDTH = 15;
    public static final int JOGADOR_HEIGHT = 10;
    
}

CLASSE DESENHO

A classe Desenho é responsável por manipular a imagem (Sprite), controlar a visibilidade e o plano cartesiano em (x,y) do objeto. O código é bem simples, conta somente com variáveis e os métodos get/set necessários para obter/setar esses valores. Vamos analisar o código abaixo.

package INVASORESDOESPACO;

// Importação necessária para a classe
import java.awt.Image;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: DESENHO
 * OBJETIVO: RESPONSÁVEL POR MONTAR DESENHOS DO JOGO
 *
 */

public class Desenho
{

    // DEFINIÇÃO DA VISÍBILIDADE DO OBJETO NA TELA
    private boolean visivel;
    // CRIAÇÃO DE UMA NOVA IMAGEM
    private Image imagem;

    // VALORES (x,y) DO PLANO CARTESIANO
    protected int x;
    protected int y;

    // DEFINIÇÃO DO STATUS DO OBJETO
    protected boolean morrendo;

    // DEFINIÇÃO DA DIREÇÃO DO OBJETO NA TELA
    protected int dx;

    // MÉTODO CONSTRUTOR DA CLASSE
    public Desenho ()
    {
        // DEFINE COMO VISÍVEL
        visivel = true;
    }

    // TORNA O DESENHO INVISÍVEL
    public void morrer ()
    { visivel = false; }

    // OBTEM SE O OBJETO ESTÁ VISÍVEL OU NÃO
    public boolean isVisivel ()
    { return visivel; }

    // SETA A VISIBILIDADE DO OBJETO
    public void setVisivel (boolean visivel)
    { this.visivel = visivel; }

    // OBTEM A IMAGEM DO OBJETO
    public Image getImagem ()
    { return imagem; }

    // SETA A IMAGEM DO OBJETO
    public void setImagem (Image imagem)
    { this.imagem = imagem; }

    // OBTEM OS VALORES DO PLANO (x,y)
    public int getX ()
    { return x; }
    public int getY ()
    { return y; }

    // SETA OS VALORES DO PLANO (x,y)
    public void setX (int x)
    { this.x = x; }
    public void setY (int y)
    { this.y = y; }

    // OBTEM SE O DESENHO ESTÁ OU NÃO MORRENDO
    public boolean isMorrendo ()
    { return morrendo; }

    // SETA SE O DESENHO ESTÁ OU NÃO MORRENDO
    public void setMorrendo (boolean morrendo)
    { this.morrendo = morrendo; }

}

Muito bem!! Essa classe Desenho será um auxiliar para todos gráficos do jogo, e como podemos ver, ela é relativamente simples.

CLASSE ALIENÍGENAS

A classe Alienígenas é responsável por controlar o alienígena (vilão do jogo), estendendo a classe Desenho. Também é uma classe definitivamente simples, abaixo o código comentado com maiores informações.

package INVASORESDOESPACO;

// Importação necessária para a classe
import javax.swing.ImageIcon;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: ALIENIGINAS
 * OBJETIVO: CONTROLA OS VILÕES DO JOGO
 *
 */

// EXTENDE A CLASSE AOS ATRIBUTOS E MÉTODOS DA CLASSE DESENHO
public class Alieniginas extends Desenho
{

    // DEFINE UMA BOMBA DA SUB-CLASSE BOMBA
    private Bomba bomba;
    // CRIA A STRING COM A URL DA IMAGEM DO ALIEN
    private final String alvo = "alien.png";

    // MÉTODO CONSTRUTOR DA CLASSE
    public Alieniginas (int x, int y)
    {
        // DEFINE O PLANO (x,y)
        this.x = x;
        this.y = y;

        // DEFINE UMA NOVA BOMBA A PARTIR DO PLANO (x,y) DO ALIEN
        bomba = new Bomba(x, y);

        // CRIA UM NOVO ICONE DE IMAGEM
        ImageIcon alien = new ImageIcon(alvo);
        // SETA A IMAGEM NA EXTENSÃO DA CLASSE DESENHO
        setImagem(alien.getImage());
    }

    // PARA O ALIEN SE MOVIMENTAR NO EIXO (x,y)
    public void atuarX (int direcao)
    { this.x += direcao; }
    public void atuarY (int direcao)
    { this.y += direcao; }

    // OBTÉM A BOMBA DESSE ALIEN
    public Bomba getBomba ()
    { return bomba; }

    // CRIA UMA SUB-CLASSE DE BOMBA COM EXTENSÃO EM DESENHO
    public class Bomba extends Desenho
    {
        // DEFINE A URL DA IMAGEM DA BOMBA
        private final String bomba = "bomba.png";
        // DEFINE SE A BOMBA ESTÁ DESTRUÍDA OU NÃO
        private boolean destruido;

        // MÉTODO CONSTRUTOR DA CLASSE
        public Bomba (int x, int y)
        {
            // DEFINE O PLANO (x,y)
            this.x = x;
            this.y = y;

            // CRIA UM NOVO ICONE DE IMAGEM
            ImageIcon bomba_ = new ImageIcon(bomba);
            // SETA A IMAGEM NA EXTENSÃO DA CLASSE DESENHO
            setImagem(bomba_.getImage());
        }

        // VERIFICA SE ESTÁ DESTRUIDO OU NÃO
        public boolean isDestruido ()
        { return destruido; }

        // SETA SE ESTÁ DESTRUIDO OU NÃO
        public void setDestruido (boolean destruido)
        { this.destruido = destruido; }
    }

}

Como observado a classe cria uma imagem do alien no plano (x,y) e deixa setado uma bomba para ele, possui métodos para para mover o alien no plano, e para verificar a destruição ou não da bomba.

CLASSE JOGADOR

A classe Jogador é responsável por criar o jogador na tela, permitir sua manipulação, estendendo a classe Desenho e ainda implementando as variáveis globais da classe Comuns. É uma classe definitivamente simples, implementando somente a possibilidade de interação com o teclado, vamos analisar agora para maiores detalhes.

package INVASORESDOESPACO;

// Importações necessárias para a classe
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: JOGADOR
 * OBJETIVO: CONSTRÓI O JOGADOR
 *
 */

// ESTENDE A CLASSE AOS ATRIBUTOS E MÉTODOS DA CLASSE DESENHO
// E POSSUI A IMPLEMENTAÇÃO DA CLASSE COMUNS
public class Jogador extends Desenho implements Comuns
{

    // DEFINE AS COORDENADAS (x,y) DE INICIO
    private final int INICIAL_X = 270;
    private final int INICIAL_Y = 280;

    // CRIA A STRING COM A URL DA IMAGEM DO JOGADOR
    private final String jogador = "jogador.png";

    // DEFINE A LARGURA
    private int width;

    public Jogador ()
    {
        // CRIA UM NOVO ICONE DE IMAGEM
        ImageIcon jogador_ = new ImageIcon(jogador);
        // OBTEM A LARGURA DESSE ICONE
        width = jogador_.getImage().getWidth(null);

        // SETA A IMAGEM NA EXTENSÃO DA CLASSE DESENHO
        setImagem(jogador_.getImage());

        // SETA O PLANO (x,y) NA EXTENSÃO DA CLASSE DESENHO
        setX(INICIAL_X);
        setY(INICIAL_Y);
    }

    // DESLOCA A NAVE DO JOGADOR NA TELA
    public void atuar ()
    {
        // INCREMENTA NO X A DIREÇÃO RECEBIDA
        x += dx;

        // SE O X FOR MENOR QUE DOIS MANTEM ELE COMO 2
        if (x <= 2)
        { x = 2; }

        // SE O X FOR MAIOR QUE O LIMITE DA TELA, MANTEM ELE NO LIMITE DA TELA
        if (x >= LARGURA - 2*width)
        { x = LARGURA - 2*width; }
    }

    // CAPTURA O EVENTO CLICADO NO TECLADO
    public void keyPressed (KeyEvent e)
    {
        // RECEBE O CÓDIGO DA TECLA DIGITADO
        int key = e.getKeyCode();

        // SE A TECLA FOR PARA ESQUERDA DECREMENTA A DIREÇÃO
        if (key == KeyEvent.VK_LEFT)
        { dx = -2; }

        // SE A TECLA FOR PRA DIREITA INCREMENTA A DIREÇÃO
        if (key == KeyEvent.VK_RIGHT)
        { dx = 2; }
    }

    // CAPTURA O FIM DO CLIQUE NO TECLADO
    // QUANDO O USUÁRIO PARA DE CLICAR
    public void keyReleased (KeyEvent e)
    {
        // RECEBE O CÓDIGO DA TECLA DIGITADO
        int key = e.getKeyCode();

        // SE A TECLA FOR PARA ESQUERDA NÃO DESLOCA
        if (key == KeyEvent.VK_LEFT)
        { dx = 0; }

        // SE A TECLA FOR PARA DIREITA NÃO DESLOCA
        if (key == KeyEvent.VK_RIGHT)
        { dx = 0; }
    }
}

Facinho demaissssssssssssss, criando a imagem do desenho, atuando sobre uma direção na tela e alterando tal direção com as teclas. Ahhhhhhhhhh quem dera se todos jogos fossem fáceis assim. Enfim, let´s go para próxima classe.

CLASSE TIRO

A classe Tiro é responsável por controlar o tiro dado pelo jogador, estendendo a classe Desenho também. Mais simples ainda que as outras classe, veja o código.


package INVASORESDOESPACO;

// Importação necessária para a classe
import javax.swing.ImageIcon;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: TIRO
 * OBJETIVO: REPRESENTA O TIRO DA NAVE
 *
 */

// EXTENDE A CLASSE AOS ATRIBUTOS E MÉTODOS DA CLASSE DESENHO
public class Tiro extends Desenho
{

    // CRIA A STRING COM A URL DA IMAGEM DO TIRO
    private String tiro = "tiro.png";

    // DEFINE O TAMANHO, E O ESPAÇAMENTO
    private final int H_SPACE = 6;
    private final int V_SPACE = 1;

    // MÉTODO CONSTRUTOR VAZIO DA CLASSE, INSTÂNCIA UM TIRO SEM DEFINIR
    // SUA POSIÇÃO NO AMBIENTE
    public Tiro () {}

    // MÉTODO CONSTRUTOR QUE RECEBE A POSIÇÃO DO TIRO
    public Tiro (int x, int y)
    {
        // CRIA UM NOVO ICONE DE IMAGEM
        ImageIcon tiro_ = new ImageIcon(tiro);
        // SETA A IMAGEM NA EXTENSÃO DA CLASSE DESENHO
        setImagem(tiro_.getImage());

        // DEFINE O PLANO (x,y) COM BASE NO TAMANHO E ESPAÇAMENTO DO TIRO
        setX(x + H_SPACE);
        setY(y - V_SPACE);
    }

}

UHUUUUU, acabou! Relativamente simples, não!? Na próxima parte do tutorial, vamos desenvolver a classe grade para manipular todo o jogo com seus objetos! Até lá pessoal.


Um comentário:

  1. Amigo, o meu não esta aparecendo o jogo. somente a tela,uma listra verde, o nome "vidas" e "pontuação". poderia me ajudar?

    ResponderExcluir