18 de setembro, 20061 projeto conceitual de jogos saulo souto [email protected] geber...
TRANSCRIPT
18 de setembro, 2006 1
Projeto Conceitual de Jogos
Saulo [email protected]
Geber [email protected]
Desenvolvendo Jogos em J2ME para celulares
Aula 2Prática de jogos em J2ME
18 de setembro, 2006 2
Exercício 1- Criar o famigerado “Alô mundo!”
- Conceitos de Display- Criação e exibição de um High-Level Displayable- Conceitos de adição e tratamento de Comandos
18 de setembro, 2006 3
Exercício 2- Incrementar o “Alô Mundo”
- Conceitos de Graphics e suas funções- Fontes- Criação e exibição de um Low-Level Displayable- Tratamento de teclas- Criação e renderização de Imagens
18 de setembro, 2006 4
Nosso Jogo!Shot´em up game simplificadíiiiiiiiiissimo!! “ Star Hero é um jogo singleplayer, no estilo shoot’em up . O jogo consiste em uma espaçonave controlada pelo jogador que trafega pelas galáxias, atirando em inimigos. Essas ações resultam em pontos para o jogador. O objetivo do jogo é acumular o máximo de pontos possíveis.”
18 de setembro, 2006 5
Já Temos as Características... Work! Projetando as classes. Precisamos de:
– Um MIDlet (óbvio!)– Uma classe que trata os comandos alto-nível e possui o
looping básico do jogo (lê entrada, atualiza estado e pinta a tela)
– Uma classe que representa um elemento do jogo (Sprite)– Uma classe representando a nave– Uma classe representando os inimigos– Uma classe representando as balas– Uma classe representando a tela principal com a lógica
principal do jogo– Uma classe com todas as constantes (facilitar o acesso)
18 de setembro, 2006 6
Projeto de classes
startApp()pauseApp()destroyApp()
ShipMidlet
ShipController
Sprite
Ship
Fire
Enemy
ShipGameScreen Constantsrun()setPaused()setGameOver()commandAction()
loadGameObjects()update()paint()keyPressed()
setX()setY()intersects()update()draw()
update()draw()
update()draw()
update()draw()
MIDlet
<<extends>><<extends>>
<<extends>>
<<extends>>
CommandListener
Runnable
<<implements>>
<<implements>>
*
*
18 de setembro, 2006 7
Constants Comandos do jogo Características dos objetos Características do aparelho (largura e altura) Imagens usadas pelos objetos
Método para carregar as imagens (loadImages())
18 de setembro, 2006 8
ShipMidlet Possui referência para a tela principal do jogo Possui referência para o controlador do jogo Inicializa os objetos acima no startApp() Inicializa o looping do jogo no controlador Mostra a tela do jogo
18 de setembro, 2006 9
ShipController Thread que contêm o looping do jogo Trata todos os comandos “alto nível”do jogo Controla o estado de pause/resume do jogo (lembrar
que não tem relação com o pauseApp())
18 de setembro, 2006 10
Sprite Posição x e y na tela Altura e largura Representação gráfica Detecção de colisão Velocidades horizontal e vertical Métodos abstratos update() e draw()
18 de setembro, 2006 11
Ship É um Sprite Array de balas Indicação se a nave está explodindo Animação das imagens Métodos para mover a nave (exercício) Método pra disparar balas (exercício)
18 de setembro, 2006 12
Fire É um Sprite Renderiza a imagem (exercício)
– Não possui animação (uma imagem apenas) Tratamento ao sair da tela Atualiza a posição, dada a velocidade (exercício)
18 de setembro, 2006 13
Enemy É um Sprite Possui um comportamento ingênuo (randômico) Imagens animadas
18 de setembro, 2006 14
ShipGameScreen Inicializa e possui todos os objetos do jogo (Nave,
Inimigos e Balas) (exercício) Centraliza a atualização dos estados dos objetos
(exercício) Controla colisão de balas com inimigos (exercício) Controla colisão de inimigos com a nave (exercício) Renderiza todos os objetos (exercício) Controla e pinta informações do jogo (pontuação, level
e vidas) Trata pressionamento das teclas (esquerda,direita e
fire) (exercício)
18 de setembro, 2006 15
BUILD & RUN!
18 de setembro, 2006 16
Limitações– Tamanho das telas– Memória heap– Número de cores– Som– Tamanho do JAR– Latência da rede– Custo alto no uso da rede
18 de setembro, 2006 17
Otimize, se necessário Obfuscadores para diminuir tamanho de código
– Proguard, Retroguard, etc. Cautela no uso de herança e excesso de classes Evite usar classes anônimas ou aninhadas Acessos a variáveis estáticas e métodos estáticos é
mais rápido Arrays no lugar de Vectors Loops de trás pra frente (comparação com 0,null e false
é mais rápida) Reuse objetos Cuidado no uso de Strings
18 de setembro, 2006 18
Otimização (cont.) Combine várias imagens em uma só
Número de cores das imagens Uso do Clip pra pintura Preocupações
– Tamanho do Jar (64k ~ 100k)– Memória (200k ~ 600k)– Processamento (5 fps ~ 10 fps)
1 PNG 0.7k
4 PNG 1.6k
18 de setembro, 2006 19
Exercício (Portar para MIDP 2.0) Fazer nosso Sprite herdar do Sprite de MIDP 2.0 Usar colisão do sprite de MIDP2.0 Usar GameCanvas
– Usar tratamento de teclas usando getKeyStates()– Usar back buffer usando getGraphics()– Usar full screen
Adição de som (sugestão MIDI)
18 de setembro, 2006 20
Pacote Jogos MIDP 2.0MIDP 2.0 Packages:
– javax.microedition.lcdui.game
– Vide API http://java.sun.com/javame/reference/apis/jsr118/
Layer
TiledLayer Sprite
LayerManager
GameCanvas
*
game
Canvas
lcdui
Displayable
18 de setembro, 2006 21
Sprite
Sprite s = new Sprite(image, frameWidth, frameHeight);
s.move(10, 0);s.nextFrame();
s.setFrameSequence(new int[]{0, 1, 2, … , 1, 1, 1, 1});
s.nextFrame();
18 de setembro, 2006 22
Herdar Sprite de MIDP 2.0 Passos gerais
– Fundir imagens separadas– Usar frame sequence no lugar de vetores de
imagens– Alterar classe Sprite para herdar do Sprite do
MIDP 2.0– Alterar classes dos objetos para adaptações da
nova interface de Sprite
18 de setembro, 2006 23
Herdar Sprite de MIDP 2.0 Detalhando....
– Fundir imagens separadas Adaptar método Contants.loadImages() (exercício) Transformar vetores de imagens em frame sequences na classe
Constants (exercício)– Alterar classe Sprite
Declarar herança Remover declaração de campos já herdados Delegar posicionamento a métodos do Sprite MIDP 2.0 (exercício) Adaptar interface do construtor para receber frame sequence Implementar draw() usando Sprite.paint()
– Usar frame sequence para controlar as animações nas classes Ship, Enemy e Fire
Converter chamadas a setImage(…) em setFrameSequence(…) Inicializar frame sequences nos contrutores e nas mudanças de
estado das classes (exercício) Remover métodos draw(). Atualizar frames no update()
– Adaptar inicialização das classes usando novo construtor Adaptar classe ShipGameScreen para passar frame sequence no
lugar do vetor de imagens (exercício)
18 de setembro, 2006 24
Melhorias no uso de MIDP 2.0 Fazer nosso Sprite herdar do Sprite de MIDP 2.0 Usar colisão do sprite de MIDP2.0 Usar GameCanvas
– Usar tratamento de teclas usando getKeyStates()– Usar back buffer usando getGraphics()– Usar full screen
Adição de som (sugestão MIDI)
18 de setembro, 2006 25
Um pouco mais sobre porte Importância do porte
– Boa parte do desenvolvimento (~ 40%)– Pensar no porte desde o projeto do jogo
Exemplos de variações– Tamanho de tela– API de som– Versão MIDP– Bugs do celular– Idioma– Funcionalidades do jogo– etc…
Escala– Chega-se a gerar +1000 versões de uma aplicação
18 de setembro, 2006 26
Boas práticas para o porte Manter código único
– Pré-processamento //#ifdef <symbol> http://antenna.sourceforge.net/ http://eclipseme.org/index.html
– Aspectos Pesquisas acadêmicas
Sistemas de build– Responsável por gerar as várias versões da aplicação– Pré-processa código antes de compilar– Gerencia resources: seleciona arquivos (imagens, sons,
etc) por versão– Empacota tudo gerando executáveis (jar e jad)– http://ant.apache.org/manual/
18 de setembro, 2006 27
Dicas finais Sites interessantes
– http://www.forum.nokia.com– http://www.motocoder.com– http://wireless.java.sun.com– http://www.microjava.com– http://www.midlet-review.com
Listas de discussão– kvm-interest– j2me-brasil