Baixe o app para aproveitar ainda mais
Prévia do material em texto
Daniel Ricardo dos Santos Diogo de Campos Mauricio Oliveira Haensch Desenvolvendo Jogos com Java ME Daniel Ricardo dos Santos Diogo de Campos Mauricio Oliveira Haensch Desenvolvendo Jogos com Java ME PET Computac¸a˜o UNIVERSIDADE FEDERAL DE SANTA CATARINA CENTRO TECNOLO´GICO DEPARTAMENTO DE INFORMA´TICA E ESTATI´STICA PROGRAMA DE EDUCAC¸A˜O TUTORIAL Licenc¸a: Atribuic¸a˜o-Uso Na˜o-Comercial-Compartilhamento pela mesma Licenc¸a 2.5 Brasil • Para cada novo uso ou distribuic¸a˜o, voceˆ deve deixar claro para outros os termos da licenc¸a desta obra. • Qualquer uma destas condic¸o˜es podem ser renunciadas, desde que Voceˆ obte- nha permissa˜o do autor. • Nada nesta licenc¸a prejudica ou restringe os direitos morais dos autores. Suma´rio 1 Introduc¸a˜o p. 5 1.1 A plataforma Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 5 1.2 Java Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 5 1.3 Java Micro Edition (ME) . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 6 1.4 Java Standard Edition (SE) . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 6 1.5 Java Enterprise Edition (EE) . . . . . . . . . . . . . . . . . . . . . . . . . . p. 6 2 Java ME p. 7 2.1 O que e´ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 7 2.1.1 Aplicac¸o˜es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 7 2.1.2 Vantagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 7 2.2 Principais diferenc¸as entre Java SE e Java ME . . . . . . . . . . . . . . . . . p. 8 2.3 Configurac¸o˜es e perfis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 9 2.4 JCP e JSRs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 11 3 Ferramentas de desenvolvimento p. 12 3.1 Sun Wireless Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 12 3.2 IDEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 12 3.2.1 NetBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 12 3.2.2 Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 13 4 Bibliotecas Java ME p. 14 4.1 Java SE x Java ME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14 4.2 Bibliotecas disponı´veis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14 5 Desenvolvendo para Dispositivos Mo´veis p. 16 5.1 Uso de memo´ria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 16 5.2 Resoluc¸a˜o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 16 5.3 Configurac¸o˜es e perfis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 17 6 Desenvolvendo Jogos p. 18 6.1 A classe MIDLet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 18 6.2 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 19 6.3 Displays e Displayables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 20 6.4 Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 20 6.5 Sprites e Tiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 21 6.5.1 Sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 21 6.5.2 TiledLayer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 22 6.6 Sons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 23 7 Estudo de Caso - Liga Quatro p. 26 7.1 Introduc¸a˜o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 26 7.2 Estrutura do co´digo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 26 7.2.1 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 26 7.2.2 Eventos do menu principal . . . . . . . . . . . . . . . . . . . . . . . p. 29 7.2.3 A classe TelaDoJogo . . . . . . . . . . . . . . . . . . . . . . . . . . p. 30 7.2.4 A classe Bola . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 33 7.2.5 PlayTone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 35 8 Bibliografia p. 36 5 1 Introduc¸a˜o 1.1 A plataforma Java Java e´ uma tecnologia que se estende muito ale´m da pro´pria linguagem de programac¸a˜o. Trata-se, na verdade, de uma plataforma de desenvolvimento. A plataforma Java compreende um conjunto de softwares e especificac¸o˜es da Sun Microsys- tems para o desenvolvimento de aplicativos. A grande vantagem desta plataforma e´ a sua com- patibilidade na˜o apenas entre sistemas operacionais, mas tambe´m entre diversas arquiteturas, variando de PDAs e set-top boxes ate´ servidores. As aplicac¸o˜es desenvolvidas nesta plataforma tambe´m sa˜o diversas, variando de aplicativos embarcados a jogos e aplicativos web. Devido a essa grande variedade a plataforma e´ dividida em quatro diferentes ”edic¸o˜es”. Cada edic¸a˜o e´ composta de um pacote de softwares que permitem o desenvolvimento e a execuc¸a˜o de programas escritos na linguagem Java. As plataformas sa˜o desenhadas na˜o para um processador especı´fico, mas para uma Java Vir- tual Machine (JVM) e um compilador com um conjunto de bibliotecas. A principal vantagem do uso da ma´quina virtual e´ aumentar a portabilidade do co´digo. 1.2 Java Card Java Card e´ a edic¸a˜o mais limitada da plataforma Java e e´ destinada a smart cards ou dispo- sitivos similares com pouquı´ssima memo´ria. Seu principal foco e´ a seguranc¸a, com suporte ao encapsulamento de dados no aplicativo, firewall entre aplicativos e criptografia. Atualmente, encontra-se em desenvolvimento a versa˜o 3 da plataforma. 6 1.3 Java Micro Edition (ME) Voltada para dispositivos com pouca capacidade de processsamento e memo´ria limitada, principalmente dispositivos mo´veis. Muito usada em celulares e PDAs, estende-se tambe´m para aparelhos como set-top boxes e Blu-ray players. Apresenta algumas dificuldades no de- senvolvimento devido a grande variedade de dispositivos e suas especificidades. A plataforma Java ME e´ detalhada no pro´ximo capı´tulo. 1.4 Java Standard Edition (SE) E´ a edic¸a˜o usada para o desenvolvimento de aplicac¸o˜es porta´veis de propo´sito geral. Conte´m o que necessa´rio para o desenvolvimento de aplicac¸o˜es desktop e applets, como pacotes de in- terface gra´fica, entrada e saı´da, comunicac¸a˜o com bancos de dados, etc. Atualmente, encontra-se na versa˜o 6. 1.5 Java Enterprise Edition (EE) Java EE e´ a maior das edic¸o˜es de Java, compreendendo tudo o que esta´ presente na Standard Edition ale´m de coisas mais especı´ficas, como o servidor de aplicac¸o˜es GlassFish. Voltada para aplicac¸o˜es que rodam no lado do servidor e pensada para tornar as aplic¸o˜es robustas, seguras, escala´veis e porta´veis. E´ usada para o desenvolvimento de aplicac¸o˜es web e baseadas na arquitetura orientada a servic¸os (SOA), como web services. Atualmente, encontra-se na versa˜o 5. 7 2 Java ME 2.1 O que e´ Java ME e´ uma das edic¸o˜es da plataforma Java e, como tal, e´ composta pela pro´pria lingua- gem, por uma Ma´quina Virtual e por uma colec¸a˜o de APIs. A linguagem e´ a mesma usada nas outras edic¸o˜es, portanto e´ familiar para qualquer pessoa que ja´ tenha programado Java em qualquer plataforma. Para se entender Java ME, enta˜o, e´ necessa´rio conhecer a Ma´quina Virtual e a colec¸a˜o de APIs. Java ME aceita diferentes implementac¸o˜es de ma´quinas virtuais e normalmente a ma´quina virtual e´ definida pela Configurac¸a˜o. Ale´m desses elementos comuns, esta edic¸a˜o da plataforma Java apresenta alguns elementos especı´ficos como Profiles e Configurac¸o˜es, que sera˜o estudados adiante. 2.1.1 Aplicac¸o˜es E´ usado principalmente para o desenvolvimento em sistemasmo´veis e embarcados, alguns exemplos de sistemas que adotam Java ME sa˜o: • Celulares; • PDAs; • Set-top boxes; • Blu-ray players. 2.1.2 Vantagens Por ter um campo de aplicac¸a˜o bem especificado, Java ME apresenta diversas facilidades para os desenvolvedores, tais como: 8 Portabilidade: Um aplicativo criado utilizando Java ME pode ser portado para diversos apare- lhos, desde que sigam as mesmas especificac¸o˜es. Isso e´ muito importante no desenvolvi- mento para celulares, pois um mesmo aplicativo desenvolvido podera´ rodar em modelos de diferentes fabricantes. Boa compatibilidade entre aparelhos: Como ja´ foi citado acima, desde que sigam as mesmas especificac¸o˜es, na˜o ha´ grandes problemas de compatibilidade entre os aparelhos que ira˜o rodar um aplicativo. Constante desenvolvimento: Assim como todo o resto da tecnologia Java, Java ME se encon- tra em constante desenvolvimento, com novas func¸o˜es e capacidades sendo adicionadas a todo momento. Esse processo de desenvolvimento segue a JCP (Java Community Pro- cess), que sera´ detalhado mais a frente. Boa documentac¸a˜o: A plataforma conta com uma vasta documentac¸a˜o online, no pro´prio site da Sun, ale´m de inu´meros outros exemplos e tutoriais que podem ser encontrados em sites e fo´runs. Desenvolimento integrado: Uma das principais vantagens de Java ME e´ o desenvolvimento integrado, proporcionado por ferramentas como o Wireless Toolkit (WTK) e IDEs como o NetBeans. 2.2 Principais diferenc¸as entre Java SE e Java ME As principais diferenc¸as entre Java SE e Java ME sa˜o descritas a seguir: Ma´quina Virtual: As ma´quinas virtuais utilizadas em Java ME sa˜o desenhadas para serem mais compactas e eficientes que a ma´quina virtual utilizada em Java SE, por isso alguns recursos sa˜o perdidos. Nu´meros de ponto flutuante: O suporte a ponto flutuante so´ foi adicionado na versa˜o 1.1 do CLDC, por isso ao desenvolver aplicac¸o˜es para dispositivos mais antigos e´ possı´vel que o desenvolvedor na˜o encontre suporte para esta representac¸a˜o nume´rica. Reflexa˜o: O pacote java.lang.reflect so´ esta´ presente no CDC. Por isso na˜o e´ possı´vel utilizar reflexa˜o em dispositivos de menor capacidade. APIs de alto nı´vel (Swing e AWT): Algumas APIs de mais alto nı´vel, como as utilizadas para interface gra´fica na˜o esta˜o presentes em Java ME. 9 Acesso ao sistema de arquivos: Para se ter acesso ao sistema de arquivos e´ necessa´rio utilizar o PDA Profile, ou uma implementac¸a˜o especı´fica de um fabricante. Grupos de threads: O suporte a grupos de threads, threads que podem ser manipuladas em conjunto, tambe´m so´ e´ provido pelo CDC. A figura abaixo mostra uma visa˜o geral dos componentes de Java ME e como eles se rela- cionam as outras tecnologias Java: 2.3 Configurac¸o˜es e perfis As configurac¸o˜es (Configurations) e perfis (Profiles) representam as configurac¸o˜es e APIs mı´nimas disponı´veis em um dispositivo mo´vel. Cada aplicativo desenvolvido necessita de uma configurac¸a˜o mı´nima para ser rodado, e a garantia de que o dispositivo alvo tera´ essa configurac¸a˜o e´ fornecida pelo sistema de Configu- rations e Profiles. As principais Configurations sa˜o o CDC e o CLDC e o principal Profile e´ o MIDP, que sa˜o explicados a seguir. O MIDP e´ a definic¸a˜o de uma arquitetura, e define va´rias APIs que devem estar disponı´veis em uma plataforma para promover um ambiente de desenvolvimento para as suas MIDlets. A diferenc¸a mais importante entre o MIDP 1.0 e o MIDP 2.0 e´ a introduc¸a˜o de uma API para jogos, 10 que facilita muito a criac¸a˜o deste tipo de aplicativo. A maioria dos aplicativos desenvolvidos para dispositivos mo´veis sa˜o capazes de rodar em plataformas MIDP 1.0, que devem ter as seguintes caracterı´sticas, entre outras: • Tamanho da tela mı´nimo de 96x54pixels. • Input atrave´s de “One handed keyboard” ou “Two handed keyboard” ou Touch Screen. • 128Kbytes de memo´ria para os componentes MIDP. • 8Kbytes de memo´ria para dados das aplicac¸o˜es. • 32Kbytes de memo´ria dinaˆmica. O MIDP 1.0 e´ baseado em aparelhos que seguem a configurac¸a˜o CLDC, ou seja, os apare- lhos compatı´veis com MIDP tambe´m o sera˜o com CLDC. Dispositivos CLDC (Connected Limited Device Configuration) sa˜o os aparelhos mais sim- ples, que possuem uma interface menor e pouca memo´ria e velocidade de processamento. De- vem ter no mı´nimo as seguintes caracterı´sticas: • 128Kb de memo´ria para rodar a ma´quina virtual. • 32Kb de memo´ria dinaˆmica. • Comunicac¸a˜o em rede com baixa largura de banda. • Baixa poteˆncia (para diminuir o gasto de energia). Dispositivos CDC (Connected Device Configuration) sa˜o aparelhos mais potentes que os CLDC e devem ter pelo menos as seguintes caracterı´sticas: • 512Kb de memo´ria para executar a ma´quina virtual. • 256Kb de memo´ria dinaˆmica. • Capacidade para comunicac¸a˜o em rede com alta largura de banda. • Suporte a` persisteˆncia. 11 2.4 JCP e JSRs O Java Community Process (JCP) e´ um processo formalizado para que va´rias partes inte- ressadas colaborem no desenvolvimento de especificac¸o˜es e futuras verso˜es da plataforma Java. Entre os membros da JCP podemos encontrar operadoras de telefonia como a NTT Do- CoMo, desenvolvedores de dispositivos mo´veis como a Nokia, a Sony Ericsson e a Motorola, outras empresas e ate´ mesmo pessoas fı´sicas. Os documentos descrevendo as especificac¸o˜es e tecnologias propostas sa˜o chamados Java Specification Request (JSR). Esses documentos sa˜o publicamente revisados ate´ que um JSR se torne final e seja votado pelo Comiteˆ Executivo da JCP. Um JSR final proveˆ uma implementac¸a˜o de refereˆncia, na forma de co´digo fonte e um Technology Compatibility Kit para verificar a especificac¸a˜o da API. O pro´prio JCP e´ descrito por um JSR, o JSR 215 de 2006. Os JSRs sa˜o especialmente importantes em Java ME, por causa do nu´mero de recursos novos e da velocidade com que mudam em dispositivos mo´veis. Alguns exemplos de JSRs em Java ME: • JSR 30: J2ME CLDC 1.0 • JSR 37: MIDP 1.1 • JSR 68: J2ME Platform Specification • JSR 82: Bluetooth • JSR 118: MIDP 2.0 • JSR 133: Java Game Profile • JSR 139: CLDC 1.1 • JSR 184: Mobile 3D Graphics API for J2ME 12 3 Ferramentas de desenvolvimento 3.1 Sun Wireless Toolkit O Wireless Toolkit, ou WTK, e´ uma ferramenta de auxı´lio ao desenvolvimento de aplicac¸o˜es em Java ME (CLDC e MIDP). O WTK possui exemplos, documentac¸a˜o, func¸o˜es de otimizac¸a˜o e um emulador para dispositivos mo´veis. Ha´ algumas IDEs (Integrated Development Enviroment, ou ambiente de desenvolvimento) que ja´ veˆm com o Sun Wireless ToolKit integrado, outras possuem plugins para integrac¸a˜o e tambe´m e´ possı´vel usar apenas o WTK para desenvolver suas aplicac¸o˜es. 3.2 IDEs Duas IDEs ja´ bem conhecidas para desenvolvimento em Java (e tambe´m em outras lingua- gens de programac¸a˜o) sa˜o o Eclipse e o NetBeans. Ambos os ambientes suportam o desenvol- vimento em Java ME e sera˜o descritos com um pouco mais de caracterı´sticas a seguir. 3.2.1 NetBeans O ambiente de desenvolvimento NetBeans se iniciou como um projeto de dois estudantes, e posteriormente foi comprado pela Sun Microsystems. Por aproximadamente um ano, a empresa manteve o ambiente como software proprieta´rio, mas apo´s esse perı´odo o co´digo foi aberto e a partir disso foram surgindo muitas melhoras no ambiente em si e diversos plugins foram criados. Entre esses avanc¸os, surgiu o NetBeans Mobility Pack, que e´ uma extensa˜o da IDE para desenvolvimento com Java ME. O NetBeans Mobility Pack ja´ vem integrado com o emulador da Sun (WTK), ale´m de su- portar outros emuladores. Essa extensa˜o tambe´m tem algumas ferramentas que auxiliamno desenvolvimento para dispositivos mo´veis, como algumas classes que podem ser utilizadas nas 13 suas aplicac¸o˜es fora as padro˜es da biblioteca Java ME. Um exemplo disso e´ a SplashScreen, que estende a classe Canvas do Java ME e pode ser bem u´til para as aplicac¸o˜es desenvolvidas. O Mobility Pack tambe´m possui o Game Builder, que auxilia o desenvolvimento de jogos. Atrave´s dessa ferramenta, fica mais fa´cil criar Sprites e Tiles para seu jogo, e o Game Builder tambe´m permite a construc¸a˜o de cenas (combinac¸o˜es de objetos esta´ticos e dinaˆmicos) de uma maneira mais simples e ra´pida, ajudando na criac¸a˜o do seu jogo. Ale´m de todas as vantagens do ambiente para o desenvolvimento de aplicac¸o˜es com Ja- vaME, e´ um ambiente gratuito e com boa documentac¸a˜o, ale´m de um forte apoio da comuni- dade. 3.2.2 Eclipse Existem plugins para a IDE Eclipse para desenvolvimento com Java ME. A grande van- tagem de se desenvolver com esse ambiente sa˜o todas as facilidades do Eclipse, que e´ bem poderoso e versa´til para gerac¸a˜o de software em Java. Um dos plugins existentes para desenvolvimento com JavaME no ambiente Eclipse e´ o cha- mado EclipseME. Este plugin e´ um pouco antigo e so´ funciona com algumas verso˜es tambe´m antigas da IDE. Pore´m, existem diversos outros plugins que podem ser utilizados para desen- volvimento de aplicac¸o˜es para a plataforma ME do Java. Esses plugins podem ser encontrados na pro´pria pa´gina da IDE Eclipse, na sec¸a˜o de plugins, mas va´rios deles sa˜o pagos. 14 4 Bibliotecas Java ME 4.1 Java SE x Java ME O Java Micro Edition possui apenas um subconjunto dos componentes da Standard Edition, com uma ma´quina virtual e algumas APIs mais limitadas. As APIs presentes no Java ME sa˜o de- finidas no JCP (Java Community Process). A limitac¸a˜o de memo´ria dos dispositivos que rodam Java ME acabou resultando na retirada de algumas das bibliotecas presentes no Java Standard Edition, para manter a plataforma pequena e adequada ao seu objetivo. Pore´m, o Java Micro Edition na˜o possui apenas uma especificac¸a˜o. Dependendo da configurac¸a˜o e perfil escolhidos, voceˆ pode utilizar diferentes APIs para desenvolver sua aplicac¸a˜o. Com a evoluc¸a˜o do poder de processamento e capacidade de memo´ria dos dispositivos, surgem novas funcionalidades mais complexas atrave´s dos JSRs. Como exemplo disso, podemos citar a auseˆncia de varia´veis do tipo ponto flutuante (como o double) em verso˜es mais antigas de configurac¸o˜es e perfis do Java ME. Devido a` essa diferenc¸a entre as duas edic¸o˜es, nem toda aplicac¸a˜o desenvolvida em Java SE funcionara´ num dispositivo que roda Java ME. 4.2 Bibliotecas disponı´veis Como dito anteriormente, as APIs disponı´veis para desenvolver a sua aplicac¸a˜o resultam da combinac¸a˜o de configurac¸a˜o e perfil adotados pelo programador. Utilizando como exemplo a versa˜o 1.1 do CLDC (Connected Limited Device Configuration), os pacotes presentes para o desenvolvimento da sua aplicac¸a˜o sa˜o: • java.io • java.lang • java.lang.ref • java.util 15 • javax.microedition.io Outra diferenc¸a de bibliotecas entre a Standard Edition e a Micro Edition e´ em relac¸a˜o a` interface das aplicac¸o˜es. O SWT e Swing da edic¸a˜o padra˜o de Java na˜o se encontram na versa˜o ME. A Micro Edition conta com um novo pacote para este fim, chamado java.microedition.lcdui, que pode ser encontrado em qualquer versa˜o do MIDP. A versa˜o 2.0 do MIDP conte´m os se- guintes pacotes: • java.io • java.lang • java.util • javax.microedition.io • javax.microedition.lcdui • javax.microedition.lcdui.game • javax.microedition.media • javax.microedition.media.control • javax.microedition.midlet • javax.microedition.pki • javax.microedition.rms Como podemos notar, existe uma se´rie de pacotes exclusivos do JavaME (os iniciados com javax.microedition). Assim, com a presenc¸a de alguns pacotes exclusivos, tambe´m pode-se afirmar que nem toda aplicac¸a˜o escrita em Java ME funcionara´ na plataforma Java SE. 16 5 Desenvolvendo para Dispositivos Mo´veis 5.1 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. 5.2 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 di- 17 ferente. 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. 5.3 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. 18 6 Desenvolvendo Jogos 6.1 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 todosos 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 gerenci- ador 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. 19 6.2 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. 20 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 6.3 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 Dis- playable. 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. 6.4 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. 21 Esta classe e´ responsa´vel por tratar eventos de entrada, como teclas pressionadas, soltas ou mantidas pressionadas (keyPressed, keyReleased e keyRepeated, respectivamente) e tambe´m 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 setFullScreenMode, 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. 6.5 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. 6.5.1 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. 22 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 demais 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. Segue abaixo um exemplo de sprite com um pixel de refereˆncia influenciandona rotac¸a˜o. Figura 6.1: Imagens retiradas de: http://java.sun.com/javame/reference/apis/jsr118/javax/ microedition/lcdui/game/Sprite.html 6.5.2 TiledLayer Uma TiledLayer se trata de uma imagem composta de uma grade de ce´lulas, onde cada ce´lula e´ preenchida com uma imagem esta´tica chamada tile. Essa composic¸a˜o de imagens menores permite economia de espac¸o, e e´ uma te´cnica muito usada em diversos jogos de duas dimenso˜es. Cada posic¸a˜o na grade da TiledLayer recebe um indı´ce, ao qual e´ associado um tile. Cada um desses tiles e´ considerado esta´tico e fica ligado a` imagem que ele representa. Existe tambe´m um animated tile, que e´ um tile virtual associado dinamicamente a` um esta´tico. Com os tiles animados, ao se utilizar o mesmo animated tile em diversas ce´lulas da grade, e´ possı´vel muda´- las ao mesmo tempo apenas modificando o tile esta´tico ao qual eles esta˜o associados. A grade da TiledLayer possui um nu´mero de ce´lulas de mesmo tamanho distribuı´das por 23 linhas e colunas, definidas na criac¸a˜o do objeto. As ce´lulas da grade na˜o podem receber mais de um tile por vez, mas va´rias ce´lulas podem receber o mesmo tile. Para mudar o conteu´do de uma das ce´lulas, podem ser utilizados os me´todos setCell e fillCells. 6.6 Sons O JavaME possui uma API responsa´vel por funcionalidades multimı´dia, como gravac¸a˜o de a´udio e vı´deo, ale´m dos controle de sons. A Mobile Media API, ou MMAPI, funciona basica- mente atrave´s das classes Manager, Player e os controladores VolumeControl e ToneControl. A classe Manager e´ utilizada para criar os Players. Isso pode ser feito atrave´s do me´todo createPlayer, onde voceˆ passa como paraˆmetros um InputStream do arquivo de som que sera´ tocado e o tipo (wave, midi, mp3, etc). Assim, voceˆ obte´m um Player para tocar o som/mu´sica desejada e devera´ controlar esse novo objeto para obter o efeito desejado. Alguns exemplos de formatos e as Strings que devem ser passados como paraˆmetro para o createPlayer: Wave - audio/x-wav AU - audio/basic MP3 - audio/mpeg Midi - audio/midi Tone - audio/x-tone-seq O Player que foi obtido pode ser utilizado de uma forma simples, apenas chamando o me´todo start para que ele comece e pare ao chegar ao fim da mı´dia especificada. InputStream stream = getClass().getResourceAsStream(sound_file); Player p = Manager.createPlayer(stream, format); p.start(); O Player permite uma maior variedade de ac¸o˜es, com a combinac¸a˜o dos me´todos da classe e o seu sistema de estados. Os estados da classe Player sa˜o: Unrealized, Realized, Started, Closed e Prefetched. A imagem abaixo mostra como sa˜o feitas as transic¸o˜es entre os estados atrave´s dos me´todos mostrados nas flechas presentes na figura. 24 O estado Unrealized indica que o Player na˜o possui nem informac¸o˜es nem recursos ne- cessa´rios para funcionar. Realized indica que apenas os recursos na˜o foram adquiridos ainda. O estado Prefetched significa que todos os recursos ja´ foram adquiridos. Ja´ o estado Closed mostra que o Player esta´ fechado e, por fim, Started e´ o estado de um Player que ja´ foi iniciado. Ale´m dos estados e dos me´todos para se trocar entre eles, a classe Player tem tambe´m me´todos para descobrir a durac¸a˜o da mı´dia a ela atribuı´da, fixar um nu´mero de repetic¸o˜es para a mı´dia e descobrir o estado atual, entre outros (getDuration, setLoopCount e getState, respec- tivamente). A Mobile Media API tambe´m possui o Control, cujos objetos podem ser utilizados para controlar algumas func¸o˜es das mı´dias. Por exemplo, o Player suporta um VolumeControl, que pode ser utilizado para controlar o volume do au´dio desse Player. Existe tambe´m o ToneControl, que e´ responsa´vel por manipular sequeˆncias de tons monotoˆnicos, uma outra forma de produzir sons para a sua aplicac¸a˜o. A classe Manager ainda possui o me´todo playTone, que e´ uma maneira bem mais simples de se colocar sons no seu jogo. Este me´todo recebe como paraˆmetros a nota, a durac¸a˜o e o volume, e produz um tom monotoˆnico como resultado. Este tipo de som pode ser u´til em diversos tipos de jogos ou aplicac¸o˜es, que na˜o necessitam de algo mais complexo do que pequenos tons para os efeitos sonoros. Ha´ apenas o risco de esse tipo de soluc¸a˜o ocupar muitos recursos da CPU, 25 que acontece apenas em casos de dispositivos que na˜o possuem suporte para gerac¸a˜o de tons. 26 7 Estudo de Caso - Liga Quatro 7.1 Introduc¸a˜o Nesta sec¸a˜o vamos falar um pouco sobre o jogo que no´s escolhemos para implementar na plataforma Java ME, o Liga Quatro. O jogo, tambe´m conhecido em ingleˆs como Four in a Row, Four in a Line, ou pelo nome registrado Connect 4, e´ um jogo simples de tabuleiro para dois jogadores, que jogam em turnos alternados colocando suas fichas em colunas com o objetivo de ser o primeiro a conectar quatro fichas, seja na vertical, na horizontal ou em qualquer diagonal. Cada jogador escolhe uma coluna por turno e sua ficha e´ depositada no primeiro espac¸o livre daquela coluna. Este jogo foi escolhido por dois motivos principais: a possibilidade de se comparar a implementac¸a˜o do jogo em Java ME e Java SE, ampliando o aprendizado da tecnologia em estudo, e a interface simples. A possibilidade de comparac¸a˜o de implementac¸o˜es se deu porque os bolsistas envolvidos ja´ estavam desenvolvendo o jogo em Java SE para a disciplina de Estruturas de Dados. Essa comparac¸a˜o permitiu uma ana´lise detalhada das diferenc¸a entre as duas tecnologias e as dificul- dades de se portar o co´digo para uma plataforma mo´vel. Uma das maiores dificuldades foi modificar alguns trechos para se adaptar a` baixa capaci- dade de processamento e de memo´ria dos dispositivos mo´veis. 7.2 Estrutura do co´digo 7.2.1 Commands Aqui esta˜o declarados os atributos da classe MidletL4 do tipo Command. O construtor do Command recebe como primeiro paraˆmetro o texto que sera´ mostrado ao usua´rio para represen- tar o comando. Outro paraˆmetro e´ o tipo de comando, que pertence a um Enum (BACK, EXIT, 27 HELP, OK, CANCEL, SCREEN, STOP, ITEM). O terceiro paraˆmetro corresponde a` prioridade do comando com relac¸a˜o aos outros comandos da mesma tela, sendo o menor nu´mero a maior prioridade. Neste caso, como todos teˆm a mesma prioridade, os comandos ira˜o aparecer na ordem em que sa˜o adicionados. Com prioridades diferentes, os comandos ficam listados por ordem de maior prioridade para menor, para facilitar o acesso do usua´rio aos comandos mais importantes. private Command botaoIrParaMenu = new Command("Voltar", Command.BACK, 0); private Command botaoOK = new Command("OK", Command.OK, 0); private Command botaoSairDoJogo = new Command("Sair", Command.EXIT, 0); A nossa classe MidletL4 implementa a interface CommandListener e precisamos implemen- tar o me´todo commandAction. Assim, ele recebe um comando e a tela (Displayable) em que o comando foi executado. No co´digo demonstrado, fazemos comparac¸o˜es para saber em qual tela o jogo se encontra atualmente. Ha´ algumas telas em que so´ existe uma ac¸a˜o possı´vel, como por exemplo as telas de Splash. Desse modo, na˜o e´ preciso saber qual comando foi executado, ja´ que obrigatoriamente deveremos passar para a tela seguinte. Sempre que o comando botaoSairDoJogo for executado, a ac¸a˜o e´ fechar o aplicativo, na˜o importando em qual tela o jogo se encontra atualmente. Ja´ com o comando botaoIrParaMenu, podemos notar que existe uma condic¸a˜o que verifica se o usua´rio esta´ no meio do jogo. Caso isso seja verdade, o jogo fica pausado e a tela de menu recebe um novo bota˜o ”Continuar Jogo”. /** * Recebe os eventos que ocorreram, e a tela em qual ocorreu e * realiza a ac¸~ao correspondente. * * @param comando *O evento recebido. * @param tela * A tela na qual o evento ocorreu. 28 */ public void commandAction(Command comando, Displayable tela) { if (tela == telaSplashL4) { trocarTela(getTelaSplashPET()); } else if (tela == telaSplashPET) { trocarTela(getTelaMenu()); } if (tela == telaOpcoes) { setarOpcoes(); trocarTela(getTelaMenu()); } else if (comando == botaoSairDoJogo) { fecharMIDlet(); } else if (tela == telaVitoria || tela == telaDerrota || tela == telaEmpate) { trocarTela(telaMenu); } else if (comando == botaoIrParaMenu) { if (Controlador.getInstance().jogoNaoAcabou() && tela == telaJogo) { pausado = true; telaMenu.insert(0, getBotaoDeContinuarJogo()); } trocarTela(telaMenu); } } As trocas de tela sa˜o feitas utilizando o me´todo abaixo: /** * Troca a tela atualmente exibida no celular. * * @param proximaTela 29 * Tela a ser exibida. */ public void trocarTela(Displayable proximaTela) { display = getDisplay(); display.setCurrent(proximaTela); } 7.2.2 Eventos do menu principal Os comandos executados na tela principal do jogo sa˜o tratados de forma um pouco diferente. Os comandos foram associados a` boto˜es da telaMenu. Assim, toda vez que um bota˜o e´ pressi- onado, emitindo um evento, o comando e´ disparado e tratado por um ItemCommandListener. /** * Cria um Listener para comandos nos itens do menu principal do jogo. */ private ItemCommandListener listenerDeItens = new ItemCommandListener() { public void commandAction(Command comando, Item item) { if (item == botaoDeNovoJogo) { Controlador.getInstance().resetar(); comecarNovoJogo(); if (pausado == true) { pausado = false; telaMenu.delete(0); //Remove a opcao de continuar o jogo } } else if (item == botaoDeContinuarJogo) { trocarTela(telaJogo); pausado = false; telaMenu.delete(0); } else if (item == botaoDeOpcoes) { 30 trocarTela(getTelaOpcoes()); } else if (item == botaoDeAjuda) { trocarTela(getTelaAjuda()); } else if (item == botaoDeSobre) { trocarTela(getTelaSobre()); } else if (item == botaoDeSair) { fecharMIDlet(); } } }; Como cada Item (bota˜o) possui somente um comando, o me´todo so´ precisa avaliar qual foi o item pressionado. Abaixo, temos um exemplo de associac¸a˜o de um comando a um bota˜o. Em seguida, associ- amos ao bota˜o o ItemCommandListener mostrado no co´digo acima. botaoDeNovoJogo.addCommand(botaoOK); botaoDeNovoJogo.setItemCommandListener(listenerDeItens); 7.2.3 A classe TelaDoJogo A classe TelaDoJogo estende GameCanvas e e´ responsa´vel pela tela principal do jogo, incluindo detecc¸a˜o das teclas pressionadas, atualizac¸a˜o do que e´ mostrado na tela e efeitos sonoros. O me´todo abaixo e´ responsa´vel pela atualizac¸a˜o da tela. Os paraˆmetros recebidos servem para delimitar a regia˜o que sera´ redesenhada na tela, para questo˜es de minimizac¸a˜o de esforc¸o em certos momentos da execuc¸a˜o do programa. O me´todo flushGraphics chamado e´ o que atualiza na tela aquilo que estava no buffer dentro de a´rea desejada. 31 /** * Atualiza uma parte da tela do jogo. * @param x * Posic¸~ao horizontal em pixels onde comec¸a a a´rea a ser atualizada. * @param y * Posic¸~ao vertical em pixels onde comec¸a a a´rea a ser atualizada. * @param largura * Largura em pixels da a´rea a ser atualizada. * @param altura * Altura em pixels da a´rea a ser atualizada. */ public void refresh(int x, int y, int largura, int altura) { layer.paint(g, 0, 0); flushGraphics(x, y, largura, altura); } Para a detecc¸a˜o de estı´mulos do usua´rio, o me´todo keyPressed e´ definido recebendo o co´digo da tecla pressionada como paraˆmetro. O que fazemos e´ detectar se o que foi passado corresponde a`s teclas 4, 6 ou 5, que movimentam a ficha do jogador para esquerda, para a direita ou confirma a jogada, respectivamente. Ha´ outro trecho condicional que verifica se o co´digo da tecla pressionada corresponde a` algum gameAction. O gameAction e´ um mapeamento das teclas especiais de movimentac¸a˜o um aparelho celular especı´fico para jogos. Assim, com os dois tipos de verificac¸a˜o de teclas apresentados abaixo, e´ possı´vel utilizar tanto as teclas nume´ricas quanto as direcionais para se jogar. /** * Detecta as teclas que s~ao pressionadas durante o jogo. * @param keyCode * Co´digo da tecla pressionada. */ public void keyPressed(int keyCode) { switch (keyCode) { case KEY_NUM4: 32 controle.clicouParaEsquerda(); return; case KEY_NUM6: controle.clicouParaDireita(); return; case KEY_NUM5: controle.clicouPraBaixo(); controle.animando = true; return; } switch (getGameAction(keyCode)) { case LEFT: controle.clicouParaEsquerda(); return; case RIGHT: controle.clicouParaDireita(); return; case DOWN: controle.clicouPraBaixo(); controle.animando = true; return; case FIRE: controle.clicouPraBaixo(); controle.animando = true; return; } } Para fazer a tela do jogo, sa˜o utilizadas va´rias camadas. Cada camada adicionada e´ posici- onada num array, e a camada mais pro´xima do usua´rio e´ a situada na primeira posic¸a˜o, e a da u´ltima posic¸a˜o e´ a que fica ao fundo de todas. Desse modo, o me´todo append insere a camada adicionada no final do array e portanto mais ao fundo. Demonstrando o sistema de camadas da classe GameCanvas, no me´todo abaixo adicionamos primeiramente a grade transparente do 33 tabuleiro, que e´ na verdade a camada que fica acima de todas na tela, em seguida as duas bolas usadas para a animac¸a˜o das jogadas e por u´ltimo o fundo com o tabuleiro totalmente pintado. Assim, as bolas ficam na frente do fundo e por tra´s das grades, o que cria o efeito das bolas deslizando para dentro do tabuleiro. /** * Junta as camadas com imagens do fundo, sprites e grade * transparente do tabuleiro da tela do jogo. */ private void juntarCamadasDeImagens() { layer.append(tabuleiro.getTabuleiroTransparente()); layer.append(bolaDeEscolha.getSprite()); layer.append(bolaAuxiliarDeAnimacao.getSprite()); layer.append(tabuleiro.getFundoDoTabuleiro()); flushGraphics(); } 7.2.4 A classe Bola Os objetos da classe Bola possuem os sprites das fichas utilizadas no jogo, assim como me´todos para operar sobre esses sprites. Este campo e´ o pro´prio sprite, que vai ser utilizado nos me´todos da classe. private Sprite bola; Segue abaixo a sequeˆncia que representa a ordem dos frames do sprite e serve para definir a animac¸a˜o da bola. Os nu´meros dos frames sa˜o definidos durante a criac¸a˜o do sprite. Neste caso, ao executar a sequeˆncia (com o me´todo bola.nextFrame()), a bola parece estar caindo. private int[] sequenciaDeSaida = {0, 1, 2, 4}; bola.setFrameSequence(sequenciaDeSaida); 34 Para criar o sprite, passamos como paraˆmetro a imagem contendo os frames desejados, e tambe´m a dimensa˜o do sprite (neste caso, a altura e a largura sa˜o iguais). bola = new Sprite(imagemDaAmarela, diametro, diametro); Abaixo temos o me´todo responsa´vel por mover a bola para a direita. O me´todo inicia to- mando a posic¸a˜o atual da bola. A seguir, o sprite e´ atualizado para o u´ltimo frame da sequeˆncia do sprite, que representa uma imagem vazia. Essa imagem e´ pintada na tela com o me´todo refresh da classe TelaDoJogo. Isso faz com que a bola suma na tela do usua´rio. Logo apo´s, o sprite e´ movido uma casa para a direita e o sprite e´ atualizado para o primeiro frame da sequeˆncia, que conte´m a bola cheia. Essa bola e´ pintada novamente na tela com o mesmo me´todo, fazendo com que ela reaparec¸a. Por questo˜es de otimizac¸a˜o, o me´todo refresh() pinta apenas a a´rea em que a bola esta´ se movimentando, para na˜o pintar desnecessariamenteas regio˜es em que na˜o ha´ modificac¸a˜o na tela. /** * Move a bola para uma casa para a direita. */ public void moverParaDireita() { int x = bola.getX(); int y = bola.getY(); bola.setFrame(3); TelaDoJogo.getInstance().refresh(x, y, diametro, diametro); bola.move(diametro, 0); bola.setFrame(0); TelaDoJogo.getInstance().refresh(x + diametro, y, diametro, diametro); } Este me´todo simples move o sprite x pixels no eixo x e y no eixo y. 35 public void mover(int x, int y) { bola.move(x, y); } 7.2.5 PlayTone Para a utilizac¸a˜o de sons no jogo, optamos pelo uso do me´todo playTone. Este me´todo pertence a` classe Manager do Java ME e e´ responsa´vel por produzir um tom, dado sua durac¸a˜o e a nota. Os sons presentes no Liga Quatro sa˜o produzidos apo´s cada jogada e ao mostrar a tela de vito´ria, derrota ou empate. Um exemplo pode ser conferido abaixo: /** * Toca o efeito sonoro da bola amarela. */ public void tocarEfeitoBolaAmarela() { try { Manager.playTone(79, 100, 100); Thread.sleep(100); Manager.playTone(77, 100, 100); } catch (InterruptedException ex) { ex.printStackTrace(); } catch (MediaException ex) { ex.printStackTrace(); } } O me´todo playTone recebe como primeiro paraˆmetro a nota, que deve ser um nu´mero entre 0 e 127 e e´ calculada atrave´s de uma fo´rmula encontrada em http://java.sun.com/javame/ reference/apis/jsr118/. Como segundo paraˆmetro, e´ passada a durac¸a˜o da nota em milis- segundos. O terceiro paraˆmetro do me´todo corresponde ao volume do tom, que deve ser entre 0 e 100. Assim, produzimos dois tons para o efeito sonoro da bola amarela, com uma pausa entre eles. O Thread.sleep e´ utilizado para que os tons produzidos na˜o se sobreponham durante sua execuc¸a˜o. 36 8 Bibliografia CLDC 1.1 http://java.sun.com/javame/reference/apis/jsr139/ MIPD 2.0 http://java.sun.com/javame/reference/apis/jsr118/ IDE Netbeans http://www.netbeans.org/ Sun http://www.sun.com/ Wikipedia http://en.wikipedia.org/wiki/Java_Community_Process The Java ME Frequently Asked Questions List http://bellsouthpwp.net/m/c/mcpierce/javamefaq.html Introdução A plataforma Java Java Card Java Micro Edition (ME) Java Standard Edition (SE) Java Enterprise Edition (EE) Java ME O que é Aplicações Vantagens Principais diferenças entre Java SE e Java ME Configurações e perfis JCP e JSRs Ferramentas de desenvolvimento Sun Wireless Toolkit IDEs NetBeans Eclipse Bibliotecas Java ME Java SE x Java ME Bibliotecas disponíveis Desenvolvendo para Dispositivos Móveis Uso de memória Resolução Configurações e perfis Desenvolvendo Jogos A classe MIDLet Commands Displays e Displayables Canvas Sprites e Tiles Sprites TiledLayer Sons Estudo de Caso - Liga Quatro Introdução Estrutura do código Commands Eventos do menu principal A classe TelaDoJogo A classe Bola PlayTone Bibliografia
Compartilhar