18 de setembro, 20061 Projeto Conceitual de Jogos Saulo Souto saulo.souto@meantime.com.br Geber...

Preview:

Citation preview

18 de setembro, 2006 1

Projeto Conceitual de Jogos

Saulo Soutosaulo.souto@meantime.com.br

Geber Ramalhoglr@cin.ufpe.br

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

18 de setembro, 2006 28

Obrigado!Dúvidas?

saulo.souto@meantime.com.br