domingo, 29 de dezembro de 2013

[Tutorial] [3DSMax] Minecraft Steve - Parte 1

Olá pessoal,

Um novo tutorial que desenvolvi, que talvez mude o formato do blog ( muito mais fácil explicar por vídeo do que escrever o tutorial hahahaha ). Espero que aproveitem.


terça-feira, 26 de novembro de 2013

[Tutorial] [Android] Primeiros Passos

Olá pessoal,

Pretendo começar aqui algum tutorial sobre aplicações em Android. Para um projeto Android vamos utilizar o software Eclipse. Não que não exista uma maneira de realizar aplicações Android no NetBeans, mas o Google oferece maior suporte e facilidade ao software Eclipse.

Inicialmente acesse http://developer.android.com/sdk/index.html e baixe o SDK, extrai-a o arquivo para a pasta desejada, ele virá com o eclipse e o SDK, ambos já configurados, para iniciar o software basta abrir o eclipse.exe na pasta Eclipse. E temos nosso Eclipse:



Agora podemos desenvolver uma aplicação Android, mas antes de mais nada ATENÇÃO a pior parte ( na minha opinião ) é testar aplicativos direto no SDK com o Eclipse. É lento e não tão prático e funcional.

Sugestão para resolver isso?
Simples, baixe a ISO do Android de sua preferência. Instale via VirtualBox. Talvez eu faça um tutorial desse procedimento caso vocês precisem! O importante é que feito isso e configuração sua aplicação será testada direto em um Android de Máquina Virtual, tornando muuuuuuuito mais rápido a etapa de testes. Nas próximas semanas vou ensinar a vocês uma primeira aplicação Android, já baseada em Modelo MVC!

sábado, 16 de novembro de 2013

[Tutorial] [Java] Aplicação com Banco de Dados embutido [Parte 1]

Olá pessoal,

Hoje vou apresentar um MEGA BIG GIGANTE tutorial, dividido em partes ( mas que graças a Deus já fiz todas partes, só preciso postar hahahaha ). Esse tutorial abordará sobre um desenvolvimento de aplicação com banco de dados embutido.
Está se perguntando pra que isso? Simples, uma aplicação para usuário comum, não precisa ter uma estrutura externa de banco de dados, como MySQL por exemplo, basta tem um banco de dados acoplado. Existem vários bancos que fazem isso, mas neste caso vamos usar o SQLite (ótimo para aplicações android também).

Vamos lá! Inicialmente baixe o jdbc do SQLite no link: https://bitbucket.org/xerial/sqlite-jdbc/downloads

Abre o NetBeans, crie um novo projeto com o nome Agenda e classe Principal em br.com.agenda.Principal ( YEAHHHHHHH vamos desenvolver uma pequena Agenda porque é mais prático para iniciantes, inclusive ). Posteriormente siga os passos abaixo:

1 Clique com o botão direito em Bibliotecas.



2 Clique em Criar.
3 Defina o nome SQLite.



4 Abre o arquivo *.jar do SQLite que salvou anteriormente e clique em okay.



PRONTO! A biblioteca está adicionada. Agora criem as classe conforme a estrutura abaixo:


Como observado acima, vamos trabalhar com o modelo MVC, se não tem conhecimento do funcionamento dê uma olhada em http://papeldiario.blogspot.com.br/2013/11/programacao-tutorial-modelo-mvc.html

CLASSE
Principal - Inicia a aplicação

CONTROLE
InicialControle - Controla o inicio da aplicação
TelaPrincipalControle - Controla a TelaPrincipal.

MODELO
ConnectionFactory - Gerencia o banco de dados e nossa conexão.
ContatoDAO - Gerencia a manipulação do Contato em nosso banco de dados.
Contato - Objeto que representa o Contato.

VISÃO
TelaPrincipal - Tela exibida para o usuário.

Nos próximos tutoriais vamos começar a desenvolver cada uma dessas classes. Ate lá :)

sexta-feira, 15 de novembro de 2013

[Programação] [Tutorial] Modelo MVC

Olá, pessoal!

Hoje estou aqui para falar de um modelo de design de aplicações o MVC. Me deparei recentemente com ele e muitos materiais presentes na web não vão direto ao ponto e não explicam diretamente. Vou tentar demostrar como esse modelo é simples e facilita muito o desenvolvimento de aplicações. Primeiro vamos entender sua teoria.

M - MODELO
Representa o objetos. Classe de dados, comunicações com banco e retorno de informações e parâmetros.

V - VISÃO
A tela propriamente dita, com recursos gráficos para exibição aos usuários.

C - CONTROLE
Funciona como uma ponte, entre o MODELO e a VISÃO.

ESQUEMA DE FLUXO
A VISÃO solicita ou executa uma ação. O CONTROLE recuperá essa informação processa e solicita respostas do MODELO. O MODELO processa o resultado e retorna para o CONTROLE que por sua vez retorna à VISÃO.

Confuso? Vamos entender na prática. Desenvolvi um pequeno app em Java que solicita o e-mail para o usuário, e insere em uma lista. Teremos quatro classes: Principal, Visão, Modelo, Objeto e Controle. Coloquei estes nomes para facilitação de compreensão.

Crie um novo projeto com o nome MVC no Netbeans (ou outro editor JAVA de sua preferência). Crie a classe principal como br.com.mvc.Principal. Posteriormente crie as seguintes classes nos seguintes pacotes:

Classe - Pacote
Modelo - br.com.mvc.modelo
Objeto - br.com.mvc.modelo
Visao - br.com.mvc.visao
Controle - br.com.mvc.controle

Esse procedimento facilitará o nosso desenvolvimento.

CLASSE OBJETO

Uma classe simples, que somente representa os atributos e seus métodos GET/SET. É o modelo de dados do OBJETO.

package br.com.mvc.modelo;

/**
 *
 * @author Caique Monteiro Araujo
 * Classe: Objeto - Representa o objeto do nosso projeto, neste caso
 *         o e-mail do usuário.
 */
public class Objeto 
{
    // Definição do atributo e-mail
    private String email;
    
    // Método para obter o e-mail
    public String getEmail ()
    {
        return email;
    }

    // Método para setar o e-mail
    public void setEmail (String email)
    {
        this.email = email;
    }
}

CLASSE MODELO

O objetivo desta classe é manipular o OBJETO com operações que podem ser realizadas para ele. Neste caso, ele permite adicionar um e-mail e obter a lista de e-mails.

package br.com.mvc.modelo;

import java.util.ArrayList;

/**
 *
 * @author Caique Monteiro Araujo
 * Classe: Modelo, representa as operações de processamentos que podemos
 *         utilizar neste caso para a classe Objeto.
 */
public class Modelo 
{
    // Definição da lista de objetos do modelo
    private ArrayList<Objeto> objetos = new ArrayList<Objeto>();
    
    // Método para adicionar um objeto a lista
    public void adicionar (Objeto novo)
    {
        objetos.add(novo);
    }
    
    // Método para obter a lista
    public ArrayList<Objeto> obterLista ()
    {
        return objetos;
    }

}

CLASSE CONTROLE

A classe CONTROLE manipula as interações entre a VISÃO e o MODELO. Ela opera em construir os procedimentos e tratamentos de dados para enviar informações e receber respostas do MODELO e posteriormente enviar respostas à VISÃO.

package br.com.mvc.controle;

import br.com.mvc.modelo.*;
import br.com.mvc.visao.Visao;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.ArrayList;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Caique Monteiro Araujo
 * Classe: Controle, realiza os processamentos, se comunica com o Modelo
 *         e responde à Visão
 */
public class Controle 
{
    // Definição do atributo da Visão
    private Visao gui = null;
    // Definição do atributo do Modelo
    Modelo m = new Modelo();
    
    // Método construtor para iniciar Visão e adicionar controle de botões
    public Controle ()
    {
        // Nova instância da Visão
        gui = new Visao();
        // Adicionando a classe de controle de botões
        gui.adicionarControle(new VisaoController());
    }
    
    // Processar os dados da lista recebida pelo Modelo
    public void exibirLista ()
    {
        // Recebendo a lista de dados do Modelo
        ArrayList<Objeto> tabela = m.obterLista();
        
        // Cria um modelo de tabela
        DefaultTableModel preencher = new DefaultTableModel();
        // Define as colunas da tabela
        preencher.setColumnIdentifiers(new String[] {"E-MAIL"});
            
        // Para cada objeto da linha de dados do Modelo adiciona uma nova linha
        // no modelo da tabela
        for (Objeto o : tabela)
        {
            preencher.addRow(new String[] {o.getEmail()});
        }
        
        // Manipula a tabela da Visão para exibir os resultados
        gui.tabela.setModel(preencher);
    }
    
    // Extra-classa para definir controles de botões
    class VisaoController implements ActionListener 
    {
        
        // Reescreve o método actionPerformed do ActionListener
        public void actionPerformed (ActionEvent e) 
        {
            // Recebe a fonte/origem de chamada do evento
            JButton fonte = (JButton) e.getSource();

            // Se a fonte for o botão da Visão para adionar e-mails
            if (fonte == gui.botao) 
            {
                // Valida o email para constar presença do @
                if (!gui.text.getText().contains("@"))
                {
                    // Exibe mensagem de e-mail inválido
                    JOptionPane.showMessageDialog(null, "E-mail inválido!");
                }
                else
                {
                    // Cria um novo objeto
                    Objeto email = new Objeto();

                    // Seta o e-mail do objeto
                    email.setEmail(gui.text.getText());
                    
                    // Envia o objeto manipulado para o Modelo
                    m.adicionar(email);

                    // Chama o método para exibir resposta na tela
                    exibirLista();

                    // Limpa a tela
                    gui.limparCampos();
                    
                    // Informa que o e-mail foi cadastrado
                    JOptionPane.showMessageDialog(null, "E-mail cadastrado!");
                }
            }

        }
   }

}

CLASSE VISÃO

Está classe será a exibida para o usuário, nela só serão montados os elementos gráficos e nada mais além disso.

package br.com.mvc.visao;

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionListener;

import javax.swing.table.DefaultTableModel;

/**
 *
 * @author Caique Monteiro Araujo
 * Classe: Visão, cria o ambiente a ser exibido pelo usuário
 */
public class Visao extends JFrame
{
    // Definição de objetos gráficos a serem utilizados
    public JPanel painel_form;
    public JButton botao;
    public JTextField text;
    public JLabel label;
    
    public JPanel painel_tabela;
    public JTable tabela;
    
    public JScrollPane tabela_view;
    
    // Método construtor inicializa a Visão
    public Visao ()
    {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(350, 300);
        
        this.setTitle("MVC Exemplo");
        
        Toolkit toolkit = Toolkit.getDefaultToolkit();  
        Dimension tamanho = toolkit.getScreenSize();  
        
        this.setLocation((tamanho.width/2) - 175, (tamanho.height/2) - 150);
        this.setResizable(false);
                
        montarLayout();
        
        this.setVisible(true);
    }
    
    // Método para inicializar e montar os objetos gráficos a serem utilizados
    public void montarLayout()
    {
        this.setLayout(new BorderLayout());
        
        painel_form = new JPanel();
        botao = new JButton("Adicionar");
        label = new JLabel("E-mail: ");
        text = new JTextField();
        
        painel_tabela = new JPanel();
        tabela = new JTable();
        tabela_view = new JScrollPane();
        
        text.setPreferredSize(new Dimension(150, 25));
        
        painel_form.setLayout(new FlowLayout());
        
        painel_form.add(label);
        painel_form.add(text);
        painel_form.add(botao);
        
        painel_tabela.setLayout(new FlowLayout());
        
        DefaultTableModel preencher = new DefaultTableModel();
        preencher.setColumnIdentifiers(new String[] {"E-MAIL"});
        tabela.setModel(preencher);
        
        tabela_view.setViewportView(tabela);
        tabela_view.setPreferredSize(new Dimension(330, 200));
        
        painel_tabela.add(tabela_view);
        
        this.add("North", painel_form);
        this.add("South", painel_tabela);
    }
    
    // Método para limpar campos
    public void limparCampos ()
    {
        text.setText("");
    }
    
    // Método para setar o Controle à Visão
    public void adicionarControle (ActionListener controle) 
    {
        this.botao.addActionListener(controle);
    }

}

CLASSE PRINCIPAL

A classe fará a chamada para o CONTROLE que manipulará a VISÃO a partir de sua construção.

package br.com.mvc;

import br.com.mvc.controle.Controle;

/**
 *
 * @author Caique Monteiro Araujo
 * Classe: Princial, inicia a aplicação a partir do CONTROLE principal
 */
public class Principal 
{

    public static void main(String[] args)
    {
        new Controle();
    }

}

CONCLUSÕES

Ao observar esses códigos, vocês observaram o quanto ficou mais fácil o desenvolvimento e até para uma possível futura manutenção? Resumindo: a VISÃO manipula somente os gráficos, o CONTROLE manipula as ações do usuário, o MODELO manipula os dados da aplicação. Esperam que tenham gostado, até a próxima pessoal!

sexta-feira, 8 de novembro de 2013

[Blog] Esclarecimentos

Bom dia pessoal,

Eu sei que estamos tendo muitas solicitações no blog, escrevo esse blog sozinho e estou lotado de projetos para fazer, vou ter um grande espaço para atender todas solicitações aqui nos meses de novembro, dezembro e janeiro. Peço que sejam pacientes! Sei o quanto todos estão ansiosos para a parte 4 do tutorial com XNA e agradeço muito por isso! Vou trabalhar para resolver todos tutoriais pendentes, e a expectativa é um lançamento por semana.

Agradeço pela compreensão e logo mais, um novo layout para o blog estará saindo!


quarta-feira, 3 de julho de 2013

[Tutorial] [Java] Aplicação em Thread - Jantar dos Filósofos

E ai pessoal?! To sumido né?! ( TRÁGICO hahahahaha mas é que estou desenvolvendo muitos tutoriais para hora de postar postar eles em um ordem sem intervalos mas enfim... ) Neste tutorial vamos aprender a trabalhar com Threads ( UHUUUUU não sabe o que é isso!? Eu explico ). Thread é um recurso de multi-processamento disponível para aplicações, ou seja, existem vários processos em execução, porém cada um tem a sua hora de atuar sobre o outro.

Um exemplo clássico para entender para que servem e como funcionam os Threads é o Jantar dos Filósofos! Bom inicialmente observe a imagem abaixo.


Acima, podemos notar a presença de cinco pratos com espaguete ( HMMMMMMMM ) cada um desses pratos é para um filósofo, ou seja, existem cinco filósofos no ambiente. Porém, contudo, entretanto, também só existe cinco talheres e para um filósofo comer sua comida ele precisa de dois talheres ( na figura são garfos mas no conceito inicial são palitinhos chineses, os hashis ). Ou seja, temos cinco pratos com cinco filósofos, que terão que compartilhar cinco talheres, então um filósofo só pode pegar um talher que esteja disponível, assim como deve liberar o talher quando não utilizável ou quando estiver somente com um. Em termos da programação, isso significa que teremos 5 objetos (filósofos) e 5 objetos compartilhados (os talheres). Nesse termo que entra o conceito de Thread pois para o compartilhamento múltiplos de objetos é necessária uma programação simultânea, ou seja, todos filósofos "vivos" e todos talheres manipuláveis.

Agora vou apresentar a vocês um diagrama de classes, UHUUUUUU, este diagrama funciona como uma espécie de mapa para desenvolver nossas classes, métodos e atributos, para satisfazer a problematização descrita acima.


Bom acima podemos ver que desenvolveremos as classes: Filosofo ( Representa os filósofos em si, e o que eles são capazes de fazer na mesa ), Semaforo ( Define uma propriedade para mostrar aos outro filósofos 0 se estiver livre para uso, 1 se estiver ocupado para uso ), Grade ( Que cria o ambiente e exibe na tela ) e JantarDosFilosofos ( Nosso método principal que implementa nossa Grade ). O nome do pacote é JANTARDOSFILOSOFOS. Vamos as classes, e apreciem os comentários.

CLASSE FILOSOFO

package JANTARDOSFILOSOFOS;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 03/07/2013
 * CLASSE: FILOSOFO
 * OBJETIVO: CRIA UM OBJETO REPRESENTATIVO PARA O FILÓSOFO QUE PODERÁ COMER,
 *           PENSAR E ESTAR COM FOME.
 *
 */

// Cria uma extensão para a classe Thread
public class Filosofo extends Thread
{

    // Cria um código privado para o filósofo
    private int ID;

    // Cria padrões de comportamento do filósofo
    final int PENSANDO = 0;
    final int FAMINTO  = 1;
    final int COMENDO  = 2;

    // Método construtor que recebe um nome para a classe e um código de
    // identificação do filósofo
    public Filosofo (String nome, int ID)
    {
        super(nome);
        this.ID = ID;
    }

    // Método para definir que o filósofo está com fome
    public void ComFome ()
    {
        // Seta o estado deste filósofo na classe Grade para FAMINTO
        Grade.estado[this.ID] = 1;
        // Exibe uma mensagem de controle na tela
        System.out.println("O Filósofo " + getName() + " está FAMINTO!");
    }

    // Método para definir que o filósofo está comendo
    public void Come ()
    {
        // Seta o estado deste filósofo na classe Grade para COMENDO
        Grade.estado[this.ID] = 2;
        // Exibe uma mensagem de controle na tela
        System.out.println("O Filósofo " + getName() + " está COMENDO!");

        // Será criado um controle para o filósofo permanecer comendo
        // durante certo período de tempo
        try
        {
            // Fica parado neste estado por 1000 milisegundos
            Thread.sleep(1000L);
        }
        catch (InterruptedException ex)
        {
            // Exibe uma mensagem de controle de erro
            System.out.println("ERROR>" + ex.getMessage());
        }
    }

    // Método para definir que o filósofo está pensando
    public void Pensa ()
    {
        // Seta o estado deste filósofo na classe Grade para PENSANDO
        Grade.estado[this.ID] = 0;
        // Exibe uma mensagem de controle na tela
        System.out.println("O Filósofo " + getName() + " está PENSANDO!");

        // Será criado um controle para o filósofo permanecer pensando
        // durante certo período de tempo
        try
        {
            // Fica parado neste estado por 1000 milisegundos
            Thread.sleep(1000L);
        }
        catch (InterruptedException ex)
        {
            // Exibe uma mensagem de controle de erro
            System.out.println("ERROR>" + ex.getMessage());
        }
    }

    // Método para o filósofo soltar um garfo que ele pegou
    public void LargarGarfo ()
    {
        // Decrementa o semáforo mutex principal da classe, isso permite
        // informar que o atual método está operando na mesa dos filósofos
        Grade.mutex.decrementar();

        // Coloca o filósofo para pensar determinado tempo
        Pensa();

        // Após o filósofo pensar, ele vai informar para os seus vizinhos
        // que podem tentar pegar os garfos que já estão disponíveis
        Grade.filosofo[VizinhoEsquerda()].TentarObterGarfos();
        Grade.filosofo[VizinhoDireita()].TentarObterGarfos();

        // Após operar, volta o semáforo mutex para o estado normal
        // indicando que já realizou todos procedimentos na mesa
        Grade.mutex.incrementar();
    }

    // Método para o filósofo pegar um garfo na mesa
    public void PegarGarfo ()
    {
        // Decrementa o semáforo mutex principal da classe, isso permite
        // informar que o atual método está operando na mesa dos filósofos
        Grade.mutex.decrementar();

        // Deixa o filósofo faminto por determinado tempo
        ComFome();

        // Após o filósofo o período de fome, ele vai verificar com seus
        // vizinhos se ele pode pegar os garfos
        TentarObterGarfos();

        // Após operar, volta o semáforo mutex para o estado normal
        // indicando que já realizou todos procedimentos na mesa
        Grade.mutex.incrementar();
        // Decrementa seu semáforo
        Grade.semaforos[this.ID].decrementar();
    }

    // Método para verificar se o filósofo pode pegar um garfo disposto na mesa
    public void TentarObterGarfos()
    {

        // Verifica se este filósofo está com fome, e se o vizinho da esquerda
        // e da direita não estão comendo
        if (Grade.estado[this.ID] == 1 &&
            Grade.estado[VizinhoEsquerda()] != 2 && 
            Grade.estado[VizinhoDireita()] != 2)
        {
            // Então este filósofo pode comer
            Come();
            // E incrementa o seu semáforo
            Grade.semaforos[this.ID].incrementar();
        }

    }

    // Método de execução da classe, onde o ambiente do filósofo será rodado
    @Override
    public void run ()
    {

        try
        {
            // Coloca o filósofo para pensar
            Pensa();

            // Então realiza uma vida infinita para o filósofo onde inicialmente
            // ele executa os procedimentos de pergar os garfos da mesa, posteriormente
            // ele descansa um pouco, e por fim, ele largar os garfos que ele pegou
            do
            {
                PegarGarfo();
                Thread.sleep(1000L);
                LargarGarfo();
            }
            while (true);
        }
        catch (InterruptedException ex)
        {
            // Exibe uma mensagem de controle de erro
            System.out.println("ERROR>" + ex.getMessage());
            // E da um retorno de cancelamento
            return;
        }

    }

    // Método para obter o filósofo vizinho da direita
    public int VizinhoDireita ()
    {
        // Rationa o valor em 5 posições, ou seja, se o ID deste filósofo acrescentado
        // de um for maior que quatro, passa a ser zero
        return (this.ID + 1) % 5;
    }

    // Método para obter o filósofo vizinho da esquerda
    public int VizinhoEsquerda ()
    {
        if (this.ID == 0)
        {
            // Retorna a ultima posição
            return 4;
        }
        else
        {
            // Rationa o valor em 5 posições, ou seja, se o ID deste filósofo decrescido
            // de um for menor que zero, passa a ser quatro
            return (this.ID - 1) % 5;
        }
    }

}

CLASSE SEMAFORO

package JANTARDOSFILOSOFOS;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 03/07/2013
 * CLASSE: SEMAFORO
 * OBJETIVO: CONTROLA O CONTADOR DA APLICAÇÃO
 *
 */

public class Semaforo
{

    // Criação de um contador protegido para esta classe
    protected int contador;

    // Método construtor da classe que não recebe nenhum valor
    public Semaforo ()
    {
        this.contador = 0;
    }

    // Método construtor da classe que recebe um valor para setar no
    // contador
    public Semaforo (int valor)
    {
        this.contador = valor;
    }

    // Método de sincronização da classe onde será decrescido o contador
    public synchronized void decrementar ()
    {

        // Enquanto o contador for igual a 0, ele aguarda e trata a exceção
        while (this.contador == 0)
        {
            try
            {
                // Espera uma nova solicitação
                wait();
            }
            catch (InterruptedException ex)
            {
                // Exibe uma mensagem de controle de erro
                System.out.println("ERROR>" + ex.getMessage());
            }
        }

        // Caso tenha saído do while acima, então decrementa o
        // contador da classe
        this.contador--;

    }

    // Método de sincronização da classe onde será incrementado o contador
    public synchronized void incrementar ()
    {
        // Incrementa o contador da classe
        this.contador++;
        // Notifica que a solicitação já foi executada
        notify();
    }

}

CLASSE GRADE

package JANTARDOSFILOSOFOS;

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

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA:
 * CLASSE:
 * OBJETIVO: 
 *
 */

public class Grade extends JPanel implements Runnable
{

    // Cria padrões de comportamento dos filósofos
    final int PENSANDO = 0;
    final int FAMINTO  = 1;
    final int COMENDO  = 2;

    // Mensagem para cada um dos estados
    String mensagem = "";

    // Thread principal da aplicação
    Thread animador;

    // Criação dos semáforos da aplicação

    // O semáforo mutex que recebe o valor incial 1 para o contador
    // e é o semáforo principal da nossa aplicação
    public static Semaforo mutex = new Semaforo(1);

    // O vetor semáforos são normais e existe um semáforo para cada filósofo
    // que será criado, esses semafóros não recebem valores de inicialização
    // portanto iniciando o contador em 0
    public static Semaforo semaforos[] = new Semaforo[5];

    // Define um vetor para o estado de cada um dos filósofos presentes
    // na aplicação
    public static int estado[] = new int[5];

    // Cria 5 filósofos em um vetor para a aplicação
    static Filosofo filosofo[] = new Filosofo[5];

    // Método construtor da Grade da aplicação
    public Grade ()
    {
        // Define o foco para este JPanel
        setFocusable(true);

        // Define um tamanho para a tela
        setSize(400, 400);
        
        // Seta a cor do fundo
        setBackground(Color.white);
        
        init();
    }

    // Método para inicializar tudo o que é preciso dentro da classe
    public void init ()
    {
        // Inicializa todos estados para zero
        for (int i = 0; i < estado.length; i++)
        {
            estado[i] = 0;
        }

        // Verifica se o Thread de animação é vazio
        if(animador == null)
        {
            // Então cria um novo Thread
            animador = new Thread(this);
            // Inicia sua execução
            animador.start();
        }

        // Define a prioridade principal para este atual Thread
        Thread.currentThread().setPriority(1);

        // Inicializa todos filósofos
        filosofo[0] = new Filosofo("Platao", 0);
        filosofo[1] = new Filosofo("Socrates", 1);
        filosofo[2] = new Filosofo("Aristoteles", 2);
        filosofo[3] = new Filosofo("Tales", 3);
        filosofo[4] = new Filosofo("Sofocles", 4);

        // Inicializa todos semáforos
        semaforos[0] = new Semaforo(0);
        semaforos[1] = new Semaforo(0);
        semaforos[2] = new Semaforo(0);
        semaforos[3] = new Semaforo(0);
        semaforos[4] = new Semaforo(0);

        // Inicia a execução de todos filósofos
        filosofo[0].start();
        filosofo[1].start();
        filosofo[2].start();
        filosofo[3].start();
        filosofo[4].start();
    }

    // Método para desenhar os objetos na tela da aplicação
    @Override
    public void paint(Graphics g)
    {
        super.paint(g);
        
        // Define a cor azul
        g.setColor(Color.blue);
        // Cria um circulo na posição (50,50) do plano cartesiano com tamanho
        // 300x300
        g.drawOval(50, 50, 300, 300);

        // Para cada um dos filósofos será feito um desenho
        for(int i = 0; i < 5; i++)
        {            
            // Define a cor para cara tipo de estado
            if(estado[i] == 0)
            {
                g.setColor(Color.gray);
                mensagem = "PENSANDO";
            }
            if(estado[i] == 1)
            {
                g.setColor(Color.yellow);
                mensagem = "FAMINTO";
            }
            if(estado[i] == 2)
            {
                g.setColor(Color.green);
                mensagem = "COMENDO";
            }
            
            // Desenha o filósofo, sua carinha e seu nome na tela
            // Define os planos (x,y) e posteriormente o tamanho do objeto a ser desenhado
            g.fillOval((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 15, 30, 30);
            g.setColor(Color.black);
            g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 5, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 5, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 5, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 5);
            g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 3, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)));
            g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)), (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 2, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)));
            g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 3, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8);
            g.drawLine((int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 3, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) + 8, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) - 8);
            g.drawString(filosofo[i].getName(), (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 25);
            g.drawString(mensagem, (int)(200D - 100D * Math.cos(1.2566370614359172D * (double)i)) - 15, (int)(200D - 100D * Math.sin(1.2566370614359172D * (double)i)) + 40);
        }

        // ATIVA A SINCRONIA
        Toolkit.getDefaultToolkit().sync();
        // PAUSA
        g.dispose();

    }

    // Método de execução da classe, onde o ambiente será rodado
    public void run ()
    {        
        // Uma execução infinita
        do
        {
            // Redesenha a tela
            repaint();

            // Dorme durante um tempo para redesenhar novamente
            try
            {
                Thread.sleep(1000L);
            }
            catch (InterruptedException ex)
            {
                // Exibe uma mensagem de controle de erro
                System.out.println("ERROR>" + ex.getMessage());
            }
        }
        while (true);
    }

}


CLASSE JANTARDOSFILOSOFOS

package JANTARDOSFILOSOFOS;

import javax.swing.JFrame;

public class JantarDosFilosofos extends JFrame
{

    public JantarDosFilosofos ()
    {
        // CRIA UMA NOVA GRADE NA TELA
        add(new Grade());

        // DEFINE O TITULO
        setTitle("Jantar dos Filósofos");
        // INFORMA O MÉTODO DE SAÍDA
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // SETA O TAMANHO
        setSize(410, 410);
        // SETA A LOCALIZAÇÃO
        setLocationRelativeTo(null);
        // SETA A VISIBILIDADE
        setVisible(true);
        // SETA SE É REDIMENSIONAVEL
        setResizable(false);
    }

    public static void main(String[] args)
    {
        new JantarDosFilosofos();
    }

}

Agora teste o programa, e tcharãnnnnnnnnnnn, muito bom né!? É isso aí pessoal, até a próxima!


segunda-feira, 24 de junho de 2013

[Tutorial] [Video] [Illustrator] Desenhos em Pixel-Art

Olá pessoal! Neste tutorial vou ensinar como fazer uma arte um tanto diferente, uma pixel-art! Com este tipo de art você desenha com pixels, que permite os seus desenho parecerem imagens de 8-bits, muitos de vocês podem utilizar esse tutorial, somente para fazer suas artes ou ainda criar os sprites dos seus games, que ensino a fazer aqui no blog! Mas enfim, vamos lá, inicialmente para quem não entendeu nada do que eu to falando, vou mostrar abaixo uma pixel-art que desenvolvi.


TCHAAAAAAAARÃN! Se você percebeu que é o Superman e o Batman, fiz um bom trabalho ( HUAHAHUHA, por mais que tenha ficado péssimo o trabalho, impossível não perceber, mas enfim ). Essa pixel-art faremos no Illustrator, para quem não tiver esse programa, não se preocupe, pretendo realizar esse tutorial no Photoshop, e até mesmo no Paint. As ferramentas que vamos utilizar nesse tutorial é Rectangular Grid Tool ( para fazer nossos "pixels" ), Live Paint Bucket ( para pintar os pixels ) e Eyedrooper Tool ( o conta gostas ). Mas já falei demais................ vamos ao vídeo-tutorial! Primeiro a imagem que usei neste tutorial.


SIIIIIIM, é o Mordecai de Apenas um Show (Regular Show), se você não conhece não vive a infância de agora ( HUAHUAHU isso porque já sou velho ). Mas enfim, agora com essa imagem, vejamos o video!



WOW, não sei se o video ficou bom, mas enfim, o resultado, aqui, agora, JÁ!


O que acharam?? Bom pessoal é isso ai, libertem sua criatividade! Até a próxima!

sexta-feira, 21 de junho de 2013

[Blog] Redes Sociais

Olá pessoal que acompanha o blog, um informe rapidinho, estão liberadas, nossas três redes sociais, WOOOOOOOOW demorou mas estamos juntos. Curtam, compartilhem, sigam, inscrevam-se e sejam felizes!

FACEBOOK: 
TWITTER: https://twitter.com/itscaiqueck
YOUTUBE: http://www.youtube.com/user/8itoporcento

quinta-feira, 20 de junho de 2013

[Tutorial] [Java] PAC-MAN - Preparação

Olá pessoal! Aqui estamos com mais um inicio de tutorial ( esse pelo jeito vai ser muuuuuuuuito MUITOOOOO longo ), aqui vamos desenvolver um jogo completo do personagem PAC-MAN, com tudo, TUDO que temos direto no jogo ( hehehe completíssimo ). Como eu nunca vi esse material na internet, vou auxiliar vocês a conhecer um jogo por completo. É uma base para continuar o jogo de plataforma ( que conta com colisões, gravidades, vetores, etc.... ). Inicialmente, na preparação, vamos observar o principio do jogo. Observem abaixo.

PERSONALIDADE DO PACMAN NO JOGO

Anda para todas as direções, come as comidas, tem a cereja, e ainda as pílulas de poder. Necessita comer todos itens na tela para passar de nível, ganha um score diferente para cada item coletado.

PERSONALIDADE DE CADA FANTASMA DO JOGO

Blinky (Vermelho) – É o Boss principal do jogo que constrói maior dificuldade, começa o nível em uma velocidade constante igual dos outros fantasmas do jogo, porém após você devorar certa quantidade de comida, ele começa a aumentar sua velocidade. Anda no jogo pelo sentido horário. Sempre escolhe o caminho mais curto.

Pinky (Rosa) – É (quase) sempre o primeiro que sai do jogo depois do Blinky. Anda no jogo pelo sentido anti-horário. Sempre mantém sua aceleração.

Inky (Azul) – Perigoso e imprevisível. Diferentes voltas em tempos diferentes. É controlado com a proximidade do Blinky. Percorre o caminho mais longo. Considerado meio anti-social.

Clyde (Laranja) – O mais lerdo e desatento.

Temporariamente os fantasmas se desligam, e vão para suas casas (quatro cantos do jogo), até que persigam novamente o Pacman, as vezes nem dá tempo de eles chegarem em casa. Desligam-se somente 4 vezes para cada vida, e nível do jogo. Os fantasmas saem da casa central em modo de desligamento. O ciclo dos fantasmas é:

Ao iniciar o jogo: 7 segundos desligados, 20 segundos atacando, 7 segundos desligados, 20 segundos atacando, 5 segundos desligados, 20 segundos atacando, 5 segundos dormindo, atacando até o reiniciamento.

Se o Blinky entrar no modo de aceleração ele não desligara mais, e será aleatoriamente desligado. Se o Pacman comer a pílula de poder, os fantasmas entram no modo azul, e o modo de desligamento é pausado, todos fantasmas ficam lentos. Ao acabar o poder, eles retornam para onde estavam e a contagem continua.

RASCUNHO DE LÓGICA

PACMAN
> Andar sobre a tela
> Verificar colisão com o Tile (Mapa do Jogo); com a comida; com a pílula de poder; com a cereja.

FANTASMAS
> Traçar e percorrer o caminho para encontrar o Pacman no jogo, conforme sua personalidade (PathFinder).
> Verificar colisão com o Pacman, e o Tile.
> Controlador de tempo.
> Mudança para o modo azul.

TILE MAP
> Conter comidas, cerejas, e blocos de colisão.

DESENHO
> Controlar desenhos do jogo, e suas posições (x,y) assim como suas distâncias.

ANIMAÇÃO
> Controlar a animação dos sprites.

COMUNS
> Definir variáveis globais.

NÍVEL
> Representar o nível do jogo.

MENU
> Controla menus do jogo.

VECTOR2

> Uma classe auxiliar para manipular facilmente o plano (x,y).

GRADE

> Controla o ambiente do jogo.




E é isso aí!!!!!! Agora com nosso esquema, na parte 1 do tutorial ( lançada no sábado, provavelmente ) será criada a classe Desenho, Comuns, Menu, Vector2 e Grade ( parcialmente, nesse tutorial iremos testar o funcionamento de cada parte ). Até lá ;)

domingo, 16 de junho de 2013

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

Hello people! Aqui estamos com a parte 2 de criação do nosso mini-jogo estilo Atari ( hehehe ). Nesta parte, vamos abordar duas classes, a principal e a Grade do jogo, a gigante, a enorme, a complexa! Acompanhem com calma que no fundo é bem fácil.

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

CLASSE GRADE

A classe GRADE, é a principal do jogo, que manipula todos gráficos na tela, assim como toda interação entre os objetos, eu poderia fazer um texto gigante para explicar ela inteira, mas o código já é maior ainda, e tem muitos comentários, então aproveitem todo código.

package INVASORESDOESPACO;

// Importações necessárias para a classe
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: GRADE
 * OBJETIVO: AMBIENTE DO JOGO
 *
 */

// EXTENDE A CLASSE AOS ATRIBUTOS E MÉTODOS DA CLASSE JPANEL
// IMPLEMENTA A PROCESSO DE EXECUÇÃO E A CLASSE COMUNS
public class Grade extends JPanel implements Runnable, Comuns
{

    // DEFINE A DIMENSÃO DO AMBIENTE
    private Dimension dimensão;

    // CRIA UMA ARRAY COM OS ALIENS DO JOGO
    private ArrayList aliens;
    // CRIA UM JOGADOR PARA O JOGO
    private Jogador jogador;
    // CRIA UM TIRO PARA O JOGADOR
    private Tiro tiro;

    // DEFINE AS POSIÇÕES DE (x,y) PARA O ALIEN
    private int alienX = 150;
    private int alienY = 5;

    // DEFINE A DIREÇÃO DO MOVIMENTO PADRÃO
    private int direção = -1;
    // DEFINE A QUANTIDADE DE MORTES DOS ALIENS
    private int mortes = 0;
    // DEFINE A QUANTIDADE DE VIDAS DO JOGADOR
    private int vidas = 3;

    // VALIDA QUE O JOGO ESTÁ EM EXECUÇÃO
    private boolean estaJogando = true;

    // DEFINE A IMAGEM PARA A EXPLOSÃO
    private final String explosao = "explosão.png";
    // DEFINE A IMAGEM PARA OS ALIENS
    private final String alienimg = "alien.png";

    // MENSAGEM DO JOGO
    private String mensagem = "FIM DE JOGO!";

    // THREAD PARA ANIMAR O JOGO
    private Thread animador;

    // MÉTODO CONSTRUTOR DA CLASSE
    public Grade ()
    {
        // POSSIBILIDADE DE INTERAÇÃO COM O TECLADO
        addKeyListener(new TAdapter());

        // DEFINE O FOCO PARA ESSE JPANEL
        setFocusable(true);
        // DEFINE SUA DIMENSÃO
        dimensão = new Dimension(LARGURA, ALTURA);
        // SETA A COR DO PLANO DE FUNDO
        setBackground(Color.BLACK);

        // INICIA O JOGO
        initJogo();
    }

    // CONTROLA AS NOTIFICAÇÕES DO THREAD
    @Override
    public void addNotify()
    {
        // DEFINE ESTE COMO ELE MESMO
        super.addNotify();
        // INICIA O JOGO
        initJogo();
    }

    // MÉTODO PARA INICIAR O JOGO
    public void initJogo ()
    {
        // CRIA UMA NOVA LISTA DE ALIENS
        aliens = new ArrayList();

        // CARREGA A IMAGEM DO ALIEN
        ImageIcon alien_ = new ImageIcon(alienimg);

        // MAPA DE ALIENS, DISPOSTOS EM 4 LINHAS X 6 COLUNAS
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                // CRIA UM NOVO ALIEN PASSANDO COMO PARÂMETOS SUAS POSIÇÕES NA TELA
                Alieniginas alien = new Alieniginas(alienX + 18*j, alienY + 18*i);
                // SETA A IMAGEM DO ALIEN CRIADO
                alien.setImagem(alien_.getImage());
                // ADICIONA O ALIEN NA ARRAY DO JOGO
                aliens.add(alien);
            }
        }

        // CRIA UM NOVO JOGADOR
        jogador = new Jogador();
        // CRIA UM NOVO TIRO
        tiro = new Tiro();

        // SE O THREAD ESTIVER NULL, OU O JOGO NÃO ESTIVER RODANDO
        if (animador == null || !estaJogando)
        {
            // INSTÂNCIA PARA O THREAD ESTA CLASSE
            animador = new Thread(this);
            // INICIA A EXECUÇÃO DO THREAD
            animador.start();
        }
        
    }

    // MÉTODO PARA DESENHAR ALIENS NA TELA
    public void desenharAliens (Graphics g)
    {
        // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS
        Iterator it = aliens.iterator();

        // ENQUANDO EXISTIR UM PRÓXIMO CURSOR, CAPTURA UM ALIEN DA ARRAY,
        // SE ESTE ALIEN ESTIVER VISÍVEL ENTÃO DESENHA ELE NA TELA, COM SUA
        // POSIÇÃO (x,y), SE ELE ESTIVER MORRENDO ENTÃO MATA O ALIEN NA TELA
        while (it.hasNext())
        {
            Alieniginas alien = (Alieniginas) it.next();

            if (alien.isVisivel())
            { g.drawImage(alien.getImagem(), alien.getX(), alien.getY(), this); }

            if (alien.isMorrendo()) 
            { alien.morrer(); }
        }
    }

    // MÉTODO PARA DESENHAR JOGADOR NA TELA
    public void desenharJogador (Graphics g)
    {
        // SE O JOGADOR ESTIVER VISÍVEL ENTÃO DESENHA ELE NA TELA, COM SUA
        // POSIÇÃO (x,y), SE ELE ESTIVER MORRENDO ENTÃO MATA O JOGADOR NA TELA
        // E FINALIZA O JOGO

        if (jogador.isVisivel())
        { g.drawImage(jogador.getImagem(), jogador.getX(), jogador.getY(), this); }

        if (jogador.isMorrendo())
        { jogador.morrer(); estaJogando = false; }
    }

    // MÉTODO PARA DESENHAR TIRO NA TELA
    public void desenharTiro (Graphics g)
    {
        // SE O TIRO ESTIVER VISÍVEL ENTÃO DESENHA ELE NA TELA, COM SUA
        // POSIÇÃO (x,y)
        if (tiro.isVisivel())
        { g.drawImage(tiro.getImagem(), tiro.getX(), tiro.getY(), this); }
    }

    // MÉTODO PARA DESENHAR BOMBA NA TELA
    public void desenharBomba (Graphics g)
    {
        // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS
        Iterator it = aliens.iterator();

        // ENQUANDO EXISTIR UM PRÓXIMO CURSOR, CAPTURA UM ALIEN DA ARRAY,
        // E OBTEM A BOMBA DESSE ALIEN, SE A BOMBA NÃO ESTÁ DESTRUIDA
        // ENTÃO DESENHA ELA NA TELA COM SUAS POSIÇÕES (x,y)
        while (it.hasNext())
        {
            Alieniginas alien = (Alieniginas) it.next();

            Alieniginas.Bomba bomba = alien.getBomba();

            if (!bomba.isDestruido()) 
            { g.drawImage(bomba.getImagem(), bomba.getX(), bomba.getY(), this); }
        }
    }

    // MÉTODO PARA DESENHAR A PONTUAÇÃO NA TELA
    public void desenharScore (Graphics g)
    {
        // DEFINE A STRING DE EXIBIÇÃO
        String score = "Pontuação: " + mortes;

        // CRIA UM ESTILO DE FONTE
        Font estilo = new Font("Consolas", Font.BOLD, 12);

        // SETA A COR DA FONTE
        g.setColor(Color.white);
        // SETA O ESTILO DE FONTE
        g.setFont(estilo);
        // DESENHA A STRING COM A POSIÇÃO (x,y)
        g.drawString(score, 10, 20);
    }

    // MÉTODO PARA DESENHAR VIDAS NA TELA
    public void desenharVidas (Graphics g)
    {
        // DEFINE A STRING DE EXIBIÇÃO
        String vida = "VIDAS";
        // CRIA UM ESTILO DE FONTE
        Font estilo = new Font("Consolas", Font.BOLD, 12);
        // CRIA A MÉTRICA DA FONTE
        FontMetrics metrica = this.getFontMetrics(estilo);

        // OBTÉM O TAMANHO DA STRING NA TELA
        int width = metrica.stringWidth(vida);
        // CALCUPA A DISTÂNCIA DA BORDA PARA POSICIONAR A STRING
        int distancia = (15 * vidas) + (5 * vidas) + 25 + width;

        // PARA CADA VIDA DO JOGADOR, DESENHA UMA IMAGEM DA VIDA,
        // ALTERANDO A POSIÇÃO COM BASE NOS CALCULOS PARA DEFINIR
        // A POSIÇÃO DE CADA UMA EM (x,y)
        for (int i = 0; i < vidas; i++)
        {
            g.drawImage(jogador.getImagem(), LARGURA - width, 10, this);
            width += JOGADOR_WIDTH + 5;
        }

        // SETA A COR DA FONTE
        g.setColor(Color.white);
        // SETA O ESTILO DE FONTE
        g.setFont(estilo);
        // DESENHA A STRING COM A POSIÇÃO (x,y)
        g.drawString(vida, LARGURA - distancia, 20);
    }

    // MÉTODO PARA DESENHAR NA TELA COM ATUALIZAÇÃO
    @Override
    public void paint (Graphics g)
    {
        // DEFINE O PAINT COMO ELE MESMO
        super.paint(g);

        // SETA UMA COR
        g.setColor(Color.black);
        // DESENHA UM RETÂNGULO DO TAMANHO DA TELA
        g.fillRect(0, 0, dimensão.width, dimensão.height);
        // SETA UMA COR
        g.setColor(Color.green);

        if (estaJogando)
        {
            // DESENHA UMA LINHA PARA REPRESENTAR A BASE
            g.drawLine(0, BASE, LARGURA, BASE);
            // DESENHA TODOS OBJETOS DO JOGO CHAMANDO OS MÉTODOS CRIADOS
            // ANTERIORMENTE
            desenharAliens(g);
            desenharJogador(g);
            desenharTiro(g);
            desenharBomba(g);
            desenharVidas(g);
            desenharScore(g);
        }

        // ATIVA A SINCRONIA
        Toolkit.getDefaultToolkit().sync();
        // PAUSA
        g.dispose();
    }

    // DEFINE O CICLO DE ANIMAÇÃO E EXECUÇÃO DO JOGO NA TELA
    public void cicloAnimacao()
    {
        // VERIFICA SE JÁ MORRERAM TODOS OS ALIENS, CASO ISSO TENHA ACONTECIDO
        // PARA O JOGO, E DEFINE A MENSAGEM
        if (mortes == NUMERO_DE_ALIENS)
        {
            estaJogando = false;
            mensagem = "VOCÊ VENCEU!";
        }

        // JOGADOR COMEÇA A OPERAR
        jogador.atuar();

        // CONTROLA O TIRO SE ESTE ESTIVER VISÍVEL
        if (tiro.isVisivel())
        {
            // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS
            Iterator it = aliens.iterator();

            // OBTEM AS POSIÇÕES (x,y) DO TIRO
            int tiroX = tiro.getX();
            int tiroY = tiro.getY();

            // ENQUANTO O EXISTIR UM PRÓXIMO CURSOR, ELE CAPTURA UM ALIEN
            // DA ARRAY, RESGATA SEU POSICIONAMENTO EM (x,y) VERIFICA SE
            // O ALIEN ESTÁ VISÍVEL E O TIRO TAMBÉM, SE ESTIVER VERIFICA SE
            // O TIRO ATINGIU O ALIEN CAPTURADO, CASO ISSO ACONTEÇA, DEFINE
            // UMA NOVA IMAGEM PARA O ALIEN, INFORMA QUE O ALIEN ESTÁ MORRENDO,
            // ACRESCENTA UMA MORTE NO JOGO, E TERMINA O TIRO
            while (it.hasNext())
            {
                Alieniginas alien = (Alieniginas) it.next();

                int alienX_ = alien.getX();
                int alienY_ = alien.getY();

                if (alien.isVisivel() && tiro.isVisivel())
                {
                    if (tiroX >= alienX_ &&
                        tiroX <= (alienX_ + ALIEN_WIDTH) &&
                        tiroY >= alienY_ &&
                        tiroY <= (alienY_ + ALIEN_HEIGHT))
                    {
                        ImageIcon explosao_ = new ImageIcon(explosao);
                        alien.setImagem(explosao_.getImage());
                        alien.setMorrendo(true);
                        mortes++;
                        tiro.morrer();
                    }
                }
            }

            // PERCORRE O TIRO NO EIXO Y PARA CIMA, CASO O TIRO SAIA DA TELA
            // TERMINA O TIRO, CASO CONTRÁRIO CONTINUA SUBINDO
            int y = tiro.getY();
            y -= 4;
            
            if (y < 0)
            { tiro.morrer(); }
            else
            { tiro.setY(y); }
        }

        // CONTROLE DE ALIENIGINAS
        // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS
        Iterator itAlien = aliens.iterator();

        // ENQUANTO O EXISTIR UM PRÓXIMO CURSOR
        while (itAlien.hasNext())
        {
            // CAPTURA UM ALIEN E OBTEM SEU POSICIONAMENTO EM X
            Alieniginas alien1 = (Alieniginas) itAlien.next();
            int x = alien1.getX();

            // SE A DIREÇÃO FOR PARA DIREITA E ULTRAPASSAR A BORDA
            // INVERTE A DIREÇÃO PARA ESQUERDA, CRIA UM NOVO CURSOR,
            // E ENQUANTO EXISTIREM ALIENS DESCE A POSIÇÃO EM Y
            if (x >= LARGURA - BORDA_DIREITA && direção != -1)
{
                direção = -1;

                Iterator itAlienAux = aliens.iterator();

                while (itAlienAux.hasNext())
                {
                    Alieniginas alien2 = (Alieniginas) itAlienAux.next();
                    alien2.setY(alien2.getY() + VAI_ABAIXO);
                }

            }

            // SE A DIREÇÃO FOR PARA ESQUERDA E ULTRAPASSAR A BORDA
            // INVERTE A DIREÇÃO PARA DIREITA, CRIA UM NOVO CURSOR,
            // E ENQUANTO EXISTIREM ALIENS DESCE A POSIÇÃO EM Y
            if (x <= BORDA_ESQUERDA && direção != 1)
            {
                direção = 1;

                Iterator itAlienAux = aliens.iterator();

                while (itAlienAux.hasNext())
                {
                    Alieniginas alien = (Alieniginas) itAlienAux.next();
                    alien.setY(alien.getY() + VAI_ABAIXO);
                }
            }
        }

        // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS
        Iterator itAliensAux2 = aliens.iterator();

        // ENQUANTO O EXISTIR UM PRÓXIMO CURSOR, CAPTURA UM ALIEN DA ARRAY
        // OBTEM SUA POSIÇÃO EM Y, SE ELE CHEGAR NA BASE, É FIM DE JOGO POR
        // INVASÃO DOS ALIENS. E TAMBÉM ATUA O ALIEN NA POSIÇÃO X COM BASE
        // NA DIREÇÃO
        while (itAliensAux2.hasNext())
        {
            Alieniginas alien = (Alieniginas) itAliensAux2.next();
            if (alien.isVisivel())
            {
                int y = alien.getY();

                if (y > BASE - ALIEN_HEIGHT)
                {
                    estaJogando = false;
                    mensagem = "INVASÃO!";
                }

                alien.atuarX(direção);
            }
        }

        // CONTROLE DE BOMBAS
        // CRIA UM CURSOR DE POSICIONAMENTO NA ARRAY DOS ALIENS PARA BOMBAS
        Iterator itBomba = aliens.iterator();
        // CRIA UM RANDOM
        Random random = new Random();

        // ENQUANTO O EXISTIR UM PRÓXIMO CURSOR
        while (itBomba.hasNext())
        {
            // ESTABELECE UM VALOR ALEATÓRIO PARA ATIRAR A BOMBA
            int tiro_ = random.nextInt(15);

            // CAPTURA UM ALIEN DA ARRAY
            Alieniginas alien = (Alieniginas) itBomba.next();
            // CAPTURA A BOMBA PARA ESTE ALIEN
            Alieniginas.Bomba bomba_ = alien.getBomba();

            // SE O TIRO FOR IGUAL A CHANCES DE ACERTAR, E O ALIEN ESTIVER VISÍVEL
            // E A ULTIMA BOMBA ESTIVER DESTRUIDA, ENTÃO DISPARA OUTRA BOMBA, NA
            // POSIÇÃO (x,y) DO ALIEN
            if (tiro_ == CHANCES && alien.isVisivel() && bomba_.isDestruido())
            {
                bomba_.setDestruido(false);
                bomba_.setX(alien.getX());
                bomba_.setY(alien.getY());
            }

            // OBTEM AS POSIÇÕES DA BOMBA
            int bombaX = bomba_.getX();
            int bombaY = bomba_.getY();

            // OBTEM AS POSIÇÕES DO JOGADOR
            int jogadorX = jogador.getX();
            int jogadorY = jogador.getY();

            // SE O JOGADOR ESTIVER VISÍVEL E A BOMBA NÃO ESTIVER DESTRUIDA,
            // ENTÃO VERIFICA SE A BOMBA ATINGIU A POSIÇÃO DO JOGADOR EM ALGUM
            // PONTO (x,y), SE FOR VÁLIDO, VERIFICA SE A QUANTIDADE DE VIDAS É 1
            // SE FOR, DEFINE COMO MORTE PARA O JOGADOR E DESTRUIÇÃO PARA BOMBA,
            // CASO CONTRÁRIO DESTRÓI A BOMBA, E TIRA UMA VIDA DO JOGADOR
            if (jogador.isVisivel() && !bomba_.isDestruido())
            {
                if (bombaX >= (jogadorX) &&
                    bombaX <= (jogadorX + JOGADOR_WIDTH) &&
                    bombaY >= (jogadorY) &&
                    bombaY <= (jogadorY + JOGADOR_HEIGHT))
                {
                    if (vidas == 1)
                    {
                        ImageIcon explosao_ = new ImageIcon(explosao);

                        jogador.setImagem(explosao_.getImage());
                        jogador.setMorrendo(true);
                        
                        bomba_.setDestruido(true);
                    }
                    else
                    {
                        bomba_.setDestruido(true);
                        vidas--;
                    }
                }
            }

            // SE A BOMBA NÃO ESTIVER DESTRUIDA DESCE ELA NO PONTO Y
            // SE ELA ATINGIR SOMENTE A BASE, SETA ELA COMO DESTRUIDA
            if (!bomba_.isDestruido())
            {
                bomba_.setY(bomba_.getY() + 1);

                if (bomba_.getY() >= BASE - BOMBA_HEIGHT)
                { bomba_.setDestruido(true); }
            }
        }
    }

    // MÉTODO DE EXECUÇÃO DA CLASSE
    public void run ()
    {
        // DEFINE OS CONTROLES DE TEMPO
        long antesTempo, tempoDiferente, sleep;

        // OBTEM O TEMPO ATUAL
        antesTempo = System.currentTimeMillis();

        // ENQUANTO O JOGO ESTIVER EM OPERAÇÃO
        while (estaJogando)
        {
            // REDESENHA A TELA
            repaint();

            // OPERA AS ANIMAÇÕES
            cicloAnimacao();

            // DEFINE UM O TEMPO ATUAL EM RELAÇÃO AO ANTERIOR
            tempoDiferente = System.currentTimeMillis() - antesTempo;
            // APLICA UM DELAY
            sleep = DELAY - tempoDiferente;

            // NÃO DEIXA ELE SEM DORMIR
            if (sleep < 0)
            { sleep = 2; }

            try
            {
                // TENTA FAZER O THREAD DORMIR
                Thread.sleep(sleep);
            }
            catch (InterruptedException e)
            {
                System.out.println("Erro de interrupção!");
            }

            // DEFINE O NOVO TEMPO
            antesTempo = System.currentTimeMillis();
        }

        // MOSTRA A MENSAGEM DE FIM DE JOGO
        FimDeJogo();
    }

    // MÉTODO PARA DESENHAR A MENSAGEM NA TELA
    public void FimDeJogo ()
    {
        // OBTEM OS GRÁFICOS DA TELA
        Graphics g = this.getGraphics();

        // SETA UMA COR
        g.setColor(Color.black);
        // CRIA UM RETANGULO
        g.fillRect(0, 0, LARGURA, ALTURA);

        // SETA A COR
        g.setColor(new Color(0, 32, 48));
        // DEFINE UM NOVO RETANGULO
        g.fillRect(50, LARGURA/2 - 30, LARGURA-100, 50);
        // SETA A COR
        g.setColor(Color.white);
        // DEFINE UM NOVO RETANGULO
        g.drawRect(50, LARGURA/2 - 30, LARGURA-100, 50);

        // DEFINE O ESTILO DA FONTE
        Font estilo = new Font("Consolas", Font.BOLD, 14);
        // DEFINE A MÉTRICA DA FONTE
        FontMetrics metrica = this.getFontMetrics(estilo);

        // SETA UMA COR
        g.setColor(Color.white);
        // SETA UM ESTILO DA FONTE
        g.setFont(estilo);
        // DESENHA A MENSAGEM NA TELA
        g.drawString(mensagem, (LARGURA - metrica.stringWidth(mensagem))/2, LARGURA/2);
    }

    // CRIA UMA CLASSE DE CAPTURA DO TECLADOR
    private class TAdapter extends KeyAdapter {

        // DISPARA O MÉTODO DE SOLTA DE TECLA DO JOGADOR
        @Override
        public void keyReleased(KeyEvent e)
        {
            jogador.keyReleased(e);
        }

        // DEFINE O MÉTODO DE TECLA PRESSIONADA DO JOGADOR
        @Override
        public void keyPressed(KeyEvent e)
        {
            // O JOGADOR SE MOVIMENTA
            jogador.keyPressed(e);

            // CAPTURA SUA POSIÇÃO (x,y)
            int x = jogador.getX();
            int y = jogador.getY();

            // SE ESTIVER JOGANDO
            if (estaJogando)
            {

                // OBTEM A TECLA PRESSIONADA
                int key = e.getKeyCode();

                // SE A TECLA FOR Z E O TIRO DO JOGADOR NÃO ESTIVER VISÍVEL
                // DISPARA OUTRO TIRO NA TELA
                if (key == KeyEvent.VK_Z)
                {
                    if (!tiro.isVisivel())
                    { tiro = new Tiro(x, y); }
                }
            }

        }
    }
}

WOOOOOOOOOOOOOOAH BIG! 605 linhas de puro código de funcionamento para um jogo tão simples como esse. UFA, mas agora vem a parte mais suave e final para o jogo funcionar.

CLASSE INVASORES DO ESPAÇO

A classe InvasoresDoEspaço é a mais básica somente para gerar o JFrame a abrir o JPanel na tela. Observem abaixo.

package INVASORESDOESPACO;

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

/*
 *
 * AUTOR: CAIQUE MONTEIRO ARAUJO
 * DATA: 09/06/2013
 * CLASSE: INVASORESDOESPACO
 * OBJETIVO: TELA DO JOGO
 *
 */

public class InvasoresDoEspaco extends JFrame implements Comuns
{

    // MÉTODO CONTRUTOR DA CLASSE
    public InvasoresDoEspaco ()
    {
        // CRIA UMA NOVA GRADE NA TELA
        add(new Grade());

        // DEFINE O TITULO
        setTitle("Invasores do Espaço");
        // INFORMA O MÉTODO DE SAÍDA
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // SETA O TAMANHO
        setSize(LARGURA, ALTURA);
        // SETA A LOCALIZAÇÃO
        setLocationRelativeTo(null);
        // SETA A VISIBILIDADE
        setVisible(true);
        // SETA SE É REDIMENSIONAVEL
        setResizable(false);
    }

    // MÉTODO PRINCIPAL
    public static void main(String[] args)
    {
        // INSTÂNCIA UM NOVO JOGO
        new InvasoresDoEspaco();
    }

}

FINALMENTE ESSE MINI JOGO TÁ COMPLETO! UHUUUUU, tá, básico mais enfim tenho orgulho desse código. Abaixo eu mostro pra vocês a tela do jogo. ( PS. No jogo Snake eu dei os sprites que fiz, nesse usem a criatividade e criem um para o alien, jogador, bomba, tiro e explosão, as dimensões dessas imagens, estão no código do jogo )