quinta-feira, 6 de outubro de 2011

Desenvolvendo para Dispositivos Móveis

 Uso de memo´ ria


Os dispositivos para os quais se desenvolve em Java ME, em geral, possuem pouca memo´ ria, sendo isso um fator de risco para o desenvolvimento de aplicac¸o˜ es desse tipo, juntamente com a capacidade de processamento. Para evitar isso, deve-se ter um cuidado maior para essa classe de software.

A utilizac¸a˜o de estruturas de dados e tipos de dados mais simples e´ um bom comec¸o para reduzir o uso de memo´ ria.  Outra sa´ıda e´ reduzir o nu´ mero de objetos criados, ou reduzir o tamanho dos objetos que sa˜o utilizados na aplicac¸a˜o. As imagens utilizadas tambe´m sa˜o uma grande fonte de Out of Memory Error, a excec¸a˜o que ocorre ao se utilizar memo´ ria em excesso.

Se mesmo com esses cuidados ainda existem problemas com memo´ ria, voceˆ pode usar um profiler para auxiliar a encontrar usos desnecessa´rios ou ineficientes de memo´ ria. Um Profiler e´ uma ferramenta que ajuda a encontrar bottlenecks da sua aplicac¸a˜o, achando memory leaks e rastreando a vida dos objetos. Com essas informac¸o˜ es, e´ mais fa´cil encontrar problemas na implementac¸a˜o que ocasionam os erros de uso de memo´ ria da sua aplicac¸a˜o.


 Resoluc¸a˜ o


Os diferentes dispositivos que suportam aplicac¸o˜ es em Java ME possuem resoluc¸o˜ es de tela diferentes. Assim, na hora de desenvolver esse tipo de software, e´ preciso ter em mente alguma resoluc¸a˜o um pouco mais espec´ıfica para a qual sera´ desenvolvida a aplicac¸a˜o.

E´ muito mais fa´cil desenvolver para uma resoluc¸a˜o espec´ıfica do que tentar fazer um software mais geral que rode em va´rias resoluc¸o˜ es diferentes. Normalmente sa˜o lanc¸adas algumas verso˜ es do software, cada uma para uma resoluc¸a˜o dierente. Isso tambe´m ajuda na questa˜o de capacidade do dispositivo. Geralmente dispositivos com uma mesma resoluc¸a˜o da tela possuem uma capacidade de processamento e memo´ ria pa- recidos, facilitando com que uma aplicac¸a˜o funcione em uma quantidade maior de aparelhos mo´ veis ao ser desenvolvida especificamente para um conjunto de dispositivos similares.


Configurac¸o˜ es e perfis


A escolha da configurac¸a˜o e sua versa˜o, assim como a versa˜o do perfil adotado pelo pro- gramador, devera´ levar em conta o dispositivo para o qual se esta´ desenvolvendo a aplicac¸a˜o, assim como as funcionalidades da aplicac¸a˜o sendo desenvolvida. Essa escolha acaba definindo em que tipos de dispositivos a sua aplicac¸a˜o ira´ rodar.  Por esse motivo, e´ fundamental que se verifique as configurac¸o˜ es e perfis suportados pelo dispositivo de destino da sua aplicac¸a˜o.


  Desenvolvendo Jogos



 A classe MIDLet


A classe MIDlet corresponde a`s aplicac¸o˜ es do MIDP, e deve ser estendida para que o software que gerencia as aplicac¸o˜ es do dispositivo consiga controlar e modificar o estado das aplicac¸o˜ es (rodando ou pausada, por exemplo). A classe principal de sua aplicac¸o˜ es deve es- tender a esta classe e implementar os me´todos utilizados para criar, comec¸ar, pausar e destruir a aplicac¸a˜o. A MIDLet funciona como uma interface entre o gerenciador de aplicac¸o˜ es e a sua aplicac¸a˜o. Essa comunicac¸a˜o funciona atrave´s de sinais enviados entre o software gerenciador do dispositivo e a aplicac¸a˜o.

Para comec¸ar a sua aplicac¸a˜o, a classe MIDlet possui o me´todo startApp, que faz com que o estado atual se torne Active, enviando um sinal para o software gerenciador de aplicac¸o˜ es. Caso alguma excec¸a˜o ocorra durante a execuc¸a˜o desse me´todo, a aplicac¸a˜o e´ destru´ıda auto- maticamente e o me´todo destroyApp e´ chamado. A aplicac¸a˜o tambe´m pode ser pausada com o pauseApp, entrando no estado Paused.  Nesse estado, o MIDlet deve liberar todos os recursos alocados.

Ale´m dos me´todos que enviam um sinal ao MIDlet para a mudanc¸a de estado, ha´ tambe´m me´todos da classe que enviam um sinal ao gerenciador de aplicac¸o˜ es para informar da mudanc¸a de estado da sua aplicac¸a˜o, como o notifyDestroyed e notifyPaused.  Ao utilizar o notifyDes- troyed, por exemplo, o software gerenciador na˜o ira´ chamar o destroyApp, mas o pro´ prio MI- Dlet deve ter realizado as mesmas operac¸o˜ es que o me´todo de destruic¸a˜o, como a liberac¸a˜o de recursos.

Atrave´s da combinac¸a˜o desses me´todos da classe MIDlet monta-se o ciclo de vida de sua aplicac¸a˜o. E´ importante manter correta a comunicac¸a˜o entre a aplicac¸a˜o e o software gerenciador de aplicac¸o˜ es, estando sempre atento a` questa˜o de liberac¸a˜o de recursos e troca de sinais para mudanc¸a de estado.


  Commands


Os commands do Java ME sa˜o usados para gerar e tratar eventos. Por exemplo, um comando pode ser associado a um bota˜o, ou imagem, de modo que, quando este for selecionado, ou clicado, o evento sera´ disparado.

Um command guarda a informac¸a˜o semaˆntica de uma ac¸a˜o, como pode ser visto pelos tipos de comandos existentes, mostrados mais abaixo. Desse modo, ele e´ responsa´vel apenas pelo sig- nificado, e na˜o a` ac¸a˜o propriamente dita. A ac¸a˜o fica como responsabilidade da implementac¸a˜o de um CommandListener associado a` tela em o Command se encontra.

Um comando deve ser criado da seguinte maneira:


Command(String shortLabel, String longLabel, int commandType, int priority)


Onde shortLabel e´ o nome abreviado do comando, longLabel e´ o nome completo do co- mando e commandType e´ o tipo do comando. Ha´ tambe´m um outro construtor para objetos da classe Command, com a auseˆncia do paraˆmetro longLabel.

Os tipos poss´ıveis do commandType sa˜o os seguintes:


OK

ITEM

SCREEN

HELP

BACK

CANCEL

EXIT

STOP


A prioridade de um comando so´ e´ importante se algum objeto disparar mais de um evento de uma vez, neste caso, somente o comando de maior prioridade e´ avaliado.

Estes comandos devem enta˜o ser tratados por uma classe que implementa a interface Com- mandListener.  Nesta classe sera´ definido o me´todo commandAction que vai decidir que ac¸a˜o deve ser tomada quando cada evento e´ disparado.


Exemplos de implementac¸o˜ es de commands e CommandListeners podem ser encontrados no final desta  apostila, na sec¸a˜o Estudo de Caso - Liga Quatro ou neste site:  http://pt. wikibooks.org/wiki/J2ME/Li%C3%A7%C3%B5es/CommandListener


  Displays e Displayables


O Display e´ u´ nico por MIDlet e e´ o responsa´vel por func¸o˜ es relacionadas a` tela do dispo- sitivo.  Para obter uma refereˆncia ao Display, a aplicac¸a˜o deve utilizar o me´todo getDisplay. Atrave´s dessa classe, e´ poss´ıvel chamar me´todos para obter algumas informac¸o˜ es importantes para a sua aplicac¸a˜o, como o nu´ mero de cores do aparelho, ou ate´ mesmo se ele suporta cores. A classe Display tambe´m possui me´todos para controlar func¸o˜ es do dispositivo, como vibrar, atrave´s do me´todo vibrate, e um efeito de luz do aparelho, com o me´todo flashBackLight.


Um objeto so´ possui a capacidade de ser inserido no Display ao estender a classe Disayable. Pore´m, um Displayable apenas tem capacidade para ter comandos, listeners, t´ıtulos e tickers associados a ele.  Tudo que e´ mostrado e a sua interac¸a˜o com o usua´rio e´ definida atrave´s de subclasse, como e´ o exemplo do Canvas.  A utilizac¸a˜o do Displayable e´ feita com os me´todos setCurrent e getCurrent da classe Display, que troca e retorna o objeto do tipo Displayable atualmente na tela, respectivamente.

Caso na˜o seja definido nas subclasses do Displayable, a configurac¸a˜o inicial do seu objeto sera´:

Na˜o vis´ıvel no Display;

T´ıtulo null;

Nenhum ticker associado ao Displayable em questa˜o;

Nenhum command existente;

Nenhum listener para comandos.



 Canvas


A classe Canvas e´ uma subclasse de Displayable, e e´ utilizada para objetos da sua aplicac¸a˜o que precisam fazer alterac¸o˜ es gra´ficas na tela, ou receber eventos de teclas pressionadas no dispositivo. Em geral, os jogos utilizam muito essa classe, para poder interagir com o usua´rio tanto na recepc¸a˜o de est´ımulos quanto na apresentac¸a˜o dos resultados desses est´ımulos.



Esta classe e´ responsa´vel por tratar eventos de entrada, como teclas pressionadas, soltas ou mantidas pressionadas (keyPressed, keyReleased e keyRepeated, respectivamente) e tambe´eventos com um pointer de um PDA (similares aos de tecla).

E´  poss´ıvel verificar qual das teclas foi pressionadas com o me´todo getKeyCode, mas em Java ME existe um artif´ıcio que e´ recomendado para os desenvolvedores de jogos, que e´ o sistema de Game Actions.

Os Game Actions sa˜o definidos para aplicac¸o˜ es porta´veis que utilizam as teclas de setas de um dispositivo e eventos relacionados a jogos. O MIDP proveˆ os seguintes Game Actions: UP, DOWN, LEFT, RIGHT, FIRE, GAME A, GAME B, GAME C e GAME D. Cada Game Action pode estar a associado a mais de um Key Code, pore´m cada tecla so´ pode estar associada a` um Game Action. A aplicac¸a˜o pode traduzir um Key Code para um Game Action atrave´s do me´todo getGameAction e fazer o oposto atrave´s de getKeyCode. Apesar de va´rios Key Codes poderem estar associados ao mesmo Game Action, apenas um deles e´ retornado com este me´todo.


Outra func¸a˜o do Canvas e´ o controle gra´fico do que e´ exibido.  Isso e´ feito atrave´s do set fullScreenMode, que tanto coloca quanto tira do modo de exibic¸a˜o em tela cheia, e o me´todo repaint, que renderiza o Canvas por completo ou apenas uma regia˜o dele, art´ıficio muito u´ til para reduzir o tempo gasto com processamento para repintar uma a´rea sem alterac¸o˜ es.

  Sprites  e Tiles


Entre as bibliotecas do Java ME, existem as classes Sprite e TiledLayer, que sa˜o utiliza- das para fazer os objetos animados e o fundo do seu jogo, respectivamente.  Um Sprite, por sua definic¸a˜o, e´ uma imagem ou animac¸a˜o em duas ou treˆs dimenso˜ es que sera´ utilizada para representar um objeto, e muitas vezes sa˜o usados para detectar coliso˜ es ou fazer algum tipo de interac¸a˜o do jogo. Ja´ os Tiles sa˜o usados para representar o fundo da tela, usualmente uma paisagem, um tabuleiro ou alguma cena de um jogo.


 Sprites


Para a classe Sprite, um arquivo de imagem e´ dividido em va´rios frames de tamanho igual, e voceˆ pode criar livremente uma sequeˆncia dos frames para gerar sua animac¸a˜o. Para animar sua sequeˆncia, sa˜o usados me´todos como o nextFrame, setFrame e prevFrame. Com esta classe do Java ME tambe´m e´ poss´ıvel definir a a´rea de colisa˜o de um sprite, assim como verificar se houve colisa˜o entre dois sprites, entre um sprite e um Tile ou ate´ mesmo entre um sprite e uma imagem, utilizando me´todos como defineCollisionRectangle e collidesWith.




Os Sprites em Java ME sa˜o produzidos a partir de uma u´ nica imagem com todos os frames que sera˜o utilizados para renderizar a animac¸a˜o.

E´ poss´ıvel fazer apenas um frame, mas nos emais casos a imagem fonte e´ dividida igualmente em frames de uma determinada largura e altura. A sequeˆncia da animac¸a˜o e´ criada atrave´s de uma Frame Sequence, que nada mais e´ do que um array com os ´ındices dos frames gerados.

Um objeto do tipo Sprite pode ter um pixel de refereˆncia. Esse pixel e´ definido por padra˜o como a posic¸a˜o (0,0) do sprite, podendo ser redefinida para qualquer outra posic¸a˜o, ate´ mesmo fora dos limites do sprite.  Esse pixel existe para permitir algumas operac¸o˜ es que sa˜o realiza- das baseadas em algum referencial, como transformac¸o˜ es de rotac¸a˜o e espelhamento do sprite. 

Admin: Bruno

Olá Galera! muito grato por estarem acessando nosso blog. Espero que seja possível transmitir de forma compreensível um pouco de meus conhecimentos em programação, para esta comunidade de desenvolvedores que cresce cada vez mais! Espero que Gostem! Abraço! E meu enorme obrigado à Renato Simões, Átila Soares,Wanderson Quinto, Emerson e a toda galera que sempre ajudou meu sincero obrigado....
Especialmente a Natalia Failache e Rita de Cassia que sempre apoiaram este sonho....

De seu amigo Bruno Rafael.