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.
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.
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!
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á :)
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);
}
}
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!
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
CLASSE GRADE
CLASSE JANTARDOSFILOSOFOS
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!
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: facebook.com/opapeldiario
TWITTER: https://twitter.com/itscaiqueck
YOUTUBE: http://www.youtube.com/user/8itoporcento
FACEBOOK: facebook.com/opapeldiario
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.
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á ;)
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.
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.
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 )
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 )
Assinar:
Postagens (Atom)