Terça, 12 de Junho de 2007
Arquivo Diário
mostre o seu universo
Arquivo Diário
Publicado por mogli__ em 12 Jun 2007 | sob: t.i.
Faltou dizer: pretendo fazer alguns posts técnicos na área de TI, talvez até criar outra categoria.
Percebi o quanto ajudam blogs e fóruns ao redor da internet, e é - no mínimo - ético fazer o mesmo.![]()
Comecei a pesquisar sobre animações em Java forçado pela necessidade de desenvolver um jogo, requisitado como trabalho semestral de uma disciplina da graduação.
Na verdade o foco da questão é a análise do sistema, mas como prefiro o código àquelas caixinhas de necessidade discutível que a UML oferece, deixei isso para o resto da equipe, lendo apenas o necessário para não bancar um fantoche nas aulas.
Partindo de alguns sussurros “utilize sprites…” para o começo da pesquisa, achei várias fontes de material muito – muito, indeed – bom. Destaco o Developing Games in Java e o Killer Game Programming.
Créditos destas duas referências ao colega Cláudio Raso, integrante da equipe.
A seqüência foi ler os códigos fornecidos em paralelo com o conteúdo. Alguma coisa foi compreendida desta forma, mas o que mais ajudou foi um exemplo deveras simples, que me inspirei em fazer ao seguir o que nosso Professor tanto diz: quebre a complexidade.
Ok, um jogo pode ser algo que leve meses para ser desenvolvido. As variáveis, os controles, as condicionais… Pode ser impossível de começar se pensarmos assim.
O exemplo que eu segui, que é o código disposto aqui, trata-se do seguinte conjunto: um fundo, um chão e uma esfera. A esfera deve mover-se de acordo com as teclas esquerda e direita, respeitando os limites da tela.
O jogo deve ser encerrado quando a aplicação for fechada.
Temos aí os casos de uso e os requisitos funcionais do sistema, para quem deseja fazer pontes com a análise.
I wanna code!
É interessante abstrair qualquer conhecimento sobre layouts (Gridbag e afins), porque a exibição dos componentes gráficos – na minha sugestão – não segue este tipo de procedimento.
Cada elemento é “pintado” na tela – herdeira do Frame (isso, AWT mesmo) – com o método drawImage. Existem várias alternativas para isso (drawString, drawRect…) que podem ser muito úteis, mas não são necessárias no nosso exemplo.
Este método tem quatro parâmetros: a imagem, a coordenada X, a coordenada Y e um observador – que é o próprio objeto.
Se o canto superior esquerdo da janela é a coordenada (0, 0) e eu mostro um desenho a partir destes valores, será que não podemos seguir a exibição quadro a quadro dos desenhos animados para montar o nosso jogo? Pensemos assim:
. Tempo 1: exibir a esfera em (10, 50);
. Tempo 2: exibir a esfera em (11, 50);
. Tempo 3: exibir a esfera em (12, 50);
. Tempo 4: exibir a esfera em (13, 50);
Fica fácil concluir que a esfera está se movimentando horizontalmente para a direita, certo?
Para tanto, precisamos incrementar o valor X da esfera e chamar o método draw repetidas vezes. É… duas coisas diferentes, quase simultâneas. Se você pensou “programação paralela?!” está no caminho certo.
Na verdade é uma vertente bem mais simples do que a ciência da programação paralela, vamos apenas lidar com uma Thread, porque temos mais de uma tarefa para ser executada o tempo todo: incrementar o X da esfera (de acordo com o teclado, é claro) e “pintar” o desenho.
Aqueles livros indicados anteriormente dão uma boa explicação sobre Threads, desde a compreensão inicial até a forma de implementar. Não é complicado e não vou me ater a isso aqui.
Maravilhoso, nossa teoria está quase pronta. Basta que verifiquemos se a esfera ainda não chegou ao limite da tela, pois isso impediria o movimento.
Da mesma forma como a tela, cada imagem tem como ponto (0, 0) o seu canto superior esquerdo. Portanto, se o X da esfera for 0 ela não poderá ir para a esquerda, e se o X mais a largura dela for igual à largura da tela, não poderá ir para a direita. Portanto:
. Se a coordenada X da esfera for 0, impede movimento para esquerda;
. Se a coordenada X da esfera mais a sua largura for igual à largura da tela, impede o movimento para direita;

Em teoria, é isso. Note que não há qualquer solução pronta chamada Sprite. Na verdade, sprite é um conceito de quadro a quadro, até onde eu pude entender.
Para o exemplo que discutimos foram utilizadas quatro classes: LimitePrincipal, Gestor (inner class do LimitePrincipal), ControleEsfera e EntidadeEsfera, como segue:
ControleEsfera
- aEntidadeEsfera
+ ControleEsfera()
+ caminhaDireita()
+ caminhaEsquerda()
+ confereColisaoDireita(int)
+ confereColisaoEsquerda(int)
+ getImagem()
+ getX()
EntidadeEsfera
- aImagemEsfera
- aX
+ getImagemEsfera()
+ serImagemEsfera(Image)
+ getX()
+ setX(int)
LimitePrincipal
- aControleEsfera
- aGestor
- aImagemChao
- aImagemFundo
- aThread
- serialVersionUID
+ LimitePrincipal ()
+ criaTela()
+ movimentoDireita()
+ movimentoEsquerda()
+ run()
+ paint(Graphics)
+ main(String [] args)
Gestor
+ keyPressed(KeyEvent)
+ keyReleased(KeyEvent)
+ keyTyped(KeyEvent)
Copie, melhore e devolva:
. Fonte;
. Imagens;
Não há duvida de que a maneira exposta é extremamente simples. Podem ser utilizados os demais métodos do listener, pode ser criado um controle de aceleração, pode variar a coordenada Y, pode… Enfim, há diversos recursos e possibilidades que foram abstraídos para facilitar o entendimento, e espero que tenhamos atingido isso.
Questione, comente, sugira.
Façamos da colaboração nossa ferramenta de evolução.
Faltou dizer: a orientação a objetos do exemplo está bem fraca e eu não expliquei o modelo MVC que foi utilizado porque não são o foco da questão. Ilustrou-se, apenas, uma das maneiras de realizar movimentos em Java.
![]()