terça-feira, 27 de novembro de 2012

O Gerenciamento de Memória Manual no Objective-C

Olá a todos!!!

Toda essa introdução e cronologia que apresentei foram exclusivamente realizadas para que entendamos o assunto mais macabro referente à linguagem Objective-C: Seu gerenciamento de memória.

A evolução do gerenciamento de memória no Objective-C acompanha os avanços das Frameworks e plataformas da Apple. Sabemos que quando estamos trabalhando nessa linguagem, podemos chegar a ter de trabalhar com o gerenciamento de memória singular das linguagens C e C++ de bibliotecas que venhamos a utilizar. Portanto são 3 linguagens não gerenciadas que devemos tratar de maneira correta para não termos problemas de Memory Leak ou Dangling Pointers no código.

As versões anteriores do Mac OS X 10.5 possuíam gerenciamento de memória manual assim como no C e C++. Essa realidade também se tornou constante nas plataformas IOS até a versão 5.

No caso do Objective-C, todas as classes devem, direta ou indiretamente, herdar de NSObject da Foundation para ter acesso aos métodos de gerência manual de memória. O que acontece na prática, é que cada objeto criado na memória que é filho de NSObject incrementa um contador denominado de Reference Count/Retain Count.

Para alocarmos um objeto na memória, usamos os métodos alloc e copy. Ambos criam o objeto, mas o segundo serve especialmente para criarmos uma cópia de um outro objeto. Da mesma forma, para desalocarmos, chamamos o método release do objeto em questão.

Na prática, alloc e copy incrementam o contador, e release decrementa. Quando o contador chegar a zero, o objeto se torna imediatamente inválido (isso não significa que será imediatamente desalocado, mas mesmo assim perdemos o acesso ao mesmo).

Se você entendeu até aqui, podemos ir para o passo 2 e mais importante com relação ao gerenciamento de memória manual no Objective-C. A fim de gerar boas práticas de programação na linguagem e facilitar o desenvolvimento, criaram-se convenções que estabelecem que:
  1. Somos responsáveis por chamar o método release dos objetos que criamos com os operadores: alloc e copy já mencionados, e os operadores new (responsável por chamar o alloc e o "construtor default" do objeto num comando só) e mutableCopy.
  2. Não somos responsáveis por desalocar da memória os objetos que criamos por meio de Factory Methods que, no Objective-C, são chamados de Convenience Constructors. Um exemplo de tais métodos são os da classe NSString que nos retornam uma NSString alocada e não necessitamos fazer chamada a alloc, copy, new ou mutableCopy.
Um guia completo sobre gerenciamento de memória manual pode ser encontrado aqui. A documentação da Apple é um guia excelente que deve ser usado abusivamente.

Até aqui, entendemos que devemos chamar release dos objetos que criamos usando os métodos já referidos. Isso significa dizer que quando temos a POSSE DO OBJETO devemos desalocá-lo.

Sendo assim, temos o caso em que podemos receber um objeto por referência e desejarmos manter a referência sobre o objeto ORIGINAL na classe, ou seja, sem utilizar copy. Para tal, chamamos o método retain do objeto. Esse irá incrementar em 1 a referência do objeto em questão (o que não ocorreria com copy, aonde criamos uma nova instância e, portanto, um novo retain count).

E no caso em que criamos os nossos próprios Convenience Constructors? Se somos responsáveis pela remoção do objeto da memória nesse caso, como a faremos?

Esse é o ponto em questão que devemos nos focar para entender de vez o gerenciamento de memória manual. Para gerar o release dos objetos criados em um Convenience Constructor, chamamos antes de retornar o objeto no método (ou seja, antes do fim do escopo) o método autorelease. Basicamente, este método dirá ao compilador que desejamos decrementar o retain count desse objeto mais tarde. Mas quando seria esse mais tarde?

Ai é que entram as AutoReleasePools. Toda a vez que o método autorelease for chamado, uma referência desse objeto será adicionada à ÚLTIMA AUTORELEASEPOOL CRIADA.

Vamos ver um exemplo em código:


Assim, todo código que estiver entre uma NSAutoreleasePool e [pool drain] que tiver um objeto chamando o método autorelease, uma referência desse objeto será adicionada à pilha. Quando o método drain for chamado, um release para cada referência dentro da pilha será chamado. Portanto, não há garantias que o objeto continue válido após o fim do escopo de uma NSAutoreleasePool.

É importante notar que no caso de NSAutoreleasePools jamais chamamos o método release!!! Devemos em vés disso chamar o método drain, que se assegurará de dar release nas referências de objetos e na pilha em questão.

Nas novas versões do Xcode (a partir da 4.2), com o novo compilador (LLVM 3.0), os projetos já suportam blocos de @autoreleasepool. Segundo a documentação, eles são mais rápidos e trabalham melhor com o novo modelo de gerenciamento de memória (o qual será comentado no próximo post). Ou seja, o código demonstrado abaixo realiza a mesma coisa que o anterior, mas é o novo padrão da Apple que deve ser seguido:


Um último tópico a ser destacado a respeito das @autoreleasepool é com relação ao momento em que se justifica a criação de uma pool. Observe a seguir os momentos em que devemos realizar tal ação:
  1. Se estivermos a desenvolver uma aplicação que não se baseia no Application Kit (o Application Kit instancia automaticamente uma pool no início de cada ciclo de eventos). Um caso desse tipo de aplicação são as criadas sobre o template Command Line Tool;
  2. Se um determinado ciclo de código gera muitos objetos temporários instanciados de um Convenience Constructor;
  3. Se criarmos uma thread secundária (cada thread deve possuir sua própria @autoreleasepool).

Ufaaa!!! Por hora é só. No próximo post, irei demonstrar as principais features da linguagem, concatenando com todos os conceitos aqui apresentados. Se você ainda não entendeu, não se preocupe. Esse é o ponto que irá te retirar no estágio larval em Objective-C para o estágio Newbie...

Até lá...

Curiosidades sobre a Apple

Bom Dia!

Neste post estarei trazendo algumas curiosidades a fim de nos interarmos ainda mais nos acontecimentos que tornaram o ambiente de desenvolvimento das plataformas Apple da maneira como vemos hoje. Perceberemos também que Steve Jobs inferiu indiretamente na indústria de games com algumas ações que realizou durante o tempo que trabalhou em sua empresa NeXT.


A respeito do Macintosh:
  • O Mac OS 8 foi o primeiro Mac a usar processadores Power PC. Seu SO era chamado de Copland e foi lançado para competir com o Windows 95 e 98 da Microsoft. Teve releases de 1997 a 1999 e nesse tempo deu-se origem aos iBooks (em 1999). Foi nessa versão também que deu-se origem à API Carbon.

  • O Mac OS 9 foi o último da linha clássica de Macs. Surgiu em 1999 e tornou-se obsoleto em 2002.

  • O Mac OS 10.3 foi o último a usar processadores Power PC. A partir dai, a maioria das aplicações clássicas se tornaram obsoletas.

  • O primeiro iMac surgiu em 1998 e incorporava o Mac OS 8. Foi o primeiro produto a ser prefixado com i, o qual significa individual.

  • O MacBook PRO surgiu em 2006 substituindo as linhas anteriores de notebook da Apple (Power Book e iBook).

A respeito de Steve Jobs:
  • Steve Jobs fundou a Apple em 1975 com Wozniac e lá permaneceu por 10 anos. Antes disso ele havia trabalhado com seu parceiro criando circuitos eletrônicos e, pouco antes de fundarem a empresa, na Atari, onde inclusive teve a oportunidade de desenvolver um Pong.

  • Os primeiros computadores lançados pela Apple foram o Apple I (sucesso de vendas), Apple II e Apple III. 

  • A partir do fracasso do Apple III, duas divisões na Apple se formaram: Uma ficou responsável pelo desenvolvimento do Apple Lisa, um computador de grande porte e potência, e a de Jobs ficou responsável pela parte que deu início ao desenvolvimento da linha Macintosh, que eram computadores que tinham o objetivo de serem de mais baixa potência e de custo baixo. No Apple Lisa e Macintosh foram criadas uma gigantesca quantidade das características que se tornaram convenções nos futuros computadores.

  • O Apple Lisa acabou se tornando um fracasso em virtude do Macintosh. Assim, criou-se uma grande rivalidade entre os dois grupos da empresa. Em meados de 1984, ambas as divisões foram reagrupadas tendo Steve como coordenador. O gênio extravagante de Jobs acabou iniciando conflitos do mesmo com a empresa, fazendo-o sair da Apple em 1985.

  • Com sua saída da Apple, Steve Jobs fundou a NeXT e trabalhou nos anos seguintes no Sistema Operacional NeXT Step. Neste computador, alguns softwares importantíssimos para a indústria de games foram desenvolvidos. São eles:
    • O primeiro Web Browser;
    • Os jogos Wolfestein 3D, Doom e Quake;

  • O NeXT Step utilizava o Objective-C como linguagem base.

  • Em 1986, Jobs compra um estúdio de Computação Gráfica que mais tarde seria chamado de Píxar, estúdio responsável por gigantes catálogos do cinema com total renderização 3D. Graças a isso, mais tarde com a compra da Píxar pela Disney, Jobs se tornaria o maior acionista individual da Disney.

  • Em 1997, a Apple compra a NeXT e Steve Jobs retorna à empresa inicialmente como consultor. No entanto, a sua genialidade acabaram por fazê-lo ocupar o cargo de CEO na empresa até o fim de sua vida. O NeXT Step e seus produtos vieram a se tornar o Mac OS X, um computador com núcleo Unix/BSD com incrível potência e capacidade, e os produtos da linha iWorks. Paralelo ao lançamento do Mac OS X veio o iPod, e então tudo veio a desencadear as grandes invenções da empresa que convivemos hoje.

Por hora é só, no próximo post estarei apresentando os conceitos relacionados ao gerenciamento de memória do Objective-C. 

Até lá!

As Frameworks da Apple

Olá a todos!!!

Neste post irei dar continuidade aos assuntos referentes ao Objective-C, Porém focando na cronologia dos ambientes de desenvolvimento oferecidos pela Apple desde muito cedo, para que entendamos como as coisas chegaram a ficar da maneira em que estão.

A primeira grande API de desenvolvimento da Macintosh considerável foi a Carbon. Esta é uma API procedural desenvolvida em C que sucedeu a Toolbox API e foi usada nas versões Mac OS 8 e 9, e nas versões do Mac OS X 32 bits anteriores à 10.8 (Mountain Lion), onde então se tornou depreciada.

A Cocoa Framework foi criada no Mac OS X 10.5 (Leopard), onde surgiram os primeiros Macs com processador 64 bits. Desde então, os desenvolvedores são encorajados a portar suas aplicações para Cocoa usando Objective-C.

Alguns programas conhecidos que usaram Carbon: Final Cut Pro (versões anteriores à X), iTunes (até a versão 10.4) e Adobe Photoshop (até Abril de 2010).

A Cocoa consistem em três Frameworks: 
  • Foundation: Contém as principais funcionalidades do Objective-C implementadas. Corresponde a todas as coleções e tipos primitivos básicos;
  • Application Kit: Representam as principais funcionalidades para se construir um App;
  • Core Data: Usado para criar-se persistências e databases.
A framework Foundation usa outra framework base conhecida como Core Foundation (CF). Esta é uma API escrita em C que possui basicamente as mesmas funcionalidades de Foundation, porém mais voltadas para aplicações multiplataforma e de mais baixo nível. Portanto, a Core Foundation é mais baixo nível que a própria Cocoa.
Muito código da Foundation usa a Core Foundation como já comentado, porém de modo menos completo. Algumas funcionalidades da CF simplesmente inexistem na Foundation.

Por hora é só!
Até mais ver...

sábado, 24 de novembro de 2012

Objective-C

Olá a todos!!!

Neste tópico irei introduzir alguns conceitos referentes à linguagem Objective-C.

O Objective-C é uma extensão da linguagem C que incorpora conceitos da linguagem Smalltalk (a primeira linguagem orientada a objetos). Sua principal diferença com relação ao C++ é que o C++ foi construído a partir da raiz incorporando conceitos de C, ou seja, não foi apenas uma extensão.

É importante ressaltar que a escolha do Objective-C pela Apple como linguagem padrão de suas plataformas não foi arbitrária, mas sim resultado do legado das bibliotecas já construídas na empresa NeXT e o SO NeXTStep, precursor do Mac OS X. Ou seja, Objective-C representa um legado mais do que uma escolha.

Assim, podemos entender por que o Objective-C e suas classes padrões da Cocoa possuem o prefíxo NS (NextStep).

Mais tarde, desenvolveu-se a versão 2.0 do Objective-C que visou acrescentar as características do Standard C99, Standard esse que visou tornar o C mais próximo do C++, porém mantendo o paradigma estrutural.

Assim, tudo o que representa uma extensão do C e, portanto, um conteúdo de Objective-C é precedido por @. Além disso, as implementações dos header files (.h) passam a ser sufixadas com .m para Objective-C (híbrido de C com as novas implementações prefixadas com @), e sufixadas com .mm para Objective-C++ (híbrido de C++ com as novas implementações prefixadas com @).

Um dos aspectos mais interessantes da linguagem Objective-C é que ela é uma linguagem compilada dinamicamente em tempo de execução. Isso significa que o Objective-C é compilado por um compilador que permite despacho dinâmico de métodos e tipos. 

Ou seja, em tempo de execução são definidos qual método corresponde à chamada do método (portanto, não existe o vínculo do objeto com a implementação, mas sim uma mensagem de um objeto para uma implementação), e qual é o tipo do objeto que estamos trabalhando. A esse conceito damos o nome de Duck Typing.
O fato de não precisarmos definir qual é o tipo de objeto, sendo o compilador inteligente o suficiente para entender qual ele é, nos da uma flexibilidade incrível para trabalhar com void pointers (chamados em Objective-C de ID), sendo muito comum, portanto, encontrarmos na Cocoa classes que recebem um ponteiro para um objeto qualquer (do tipo id) e para um método qualquer (do tipo sel - Selector, que é basicamente o mesmo que um ponteiro para uma função).

O Objective-C é também uma das linguagens precursoras do uso de interfaces (chamada na linguagem de Protocol). O java inclusive copiou a forma como Objective-C trabalha com herança (somente 1 herança por classe e sem limite de implementações de interfaces).

Por hora é só. Para mais informações sobre a linguagem, consultar o seguinte link que mostra um apanhadão do funcionamento da linguagem.

SEE YOU NEXT MISSION

O Xcode

Olá a todos!!!

Neste post irei falar sobre minhas recentes descobertas a respeito do Xcode. Devido a comentários e certas experiências prévias com esta IDE, sempre desacreditei desta ferramenta. Mas confesso hoje que o Xcode possui grande chance de se tornar uma plataforma interessante de desenvolvimento muito mais do que já é no futuro.

A primeira vantagem que elenco é que o Xcode é uma ferramenta compacta. Utilizando o design já conhecido da Apple, temos tudo o que precisamos a priori para desenvolver nas barras laterais e painel superior. O ponto negativo, por outro lado, também seria esse fator, já que muitas das funcionalidades presentes em outras IDEs inexistem no Xcode.

Uma coisa que me incomodou muito quando iniciei o desenvolvimento usando o Xcode foi a ausência de um gatilho prático para visualizar o resultado de um output. Para exibição de logs, o Xcode conta com uma barra inferior que, por algum motivo, não abre quando compilamos um projeto. Assim, logo aparece na tela que a compilação foi finalizada com sucesso, mas nenhum output é mostrado a priori. É um detalhe um tanto quanto besta e newbie, mas também por outro lado é um erro de design.

Painel Superior do Xcode com as principais opções.

Como já foi comentado acima, o Xcode é organizado em 3 barras: As duas laterais e a inferior. Esse conjunto de barras recebe o nome de Views.
  • A barra inferior mostra as informações de depuração e o output. 
  • A barra da direita mostra as propriedades do que estamos trabalhando (arquivo, imagem) e nos da acesso a ajuda rápida e aos guias de programação da Apple.
  • A barra da esquerda exibe a organização do projeto em pastas lógicas, a hierarquia das classes, erros no código e informações de depuração. Também oferece uma barra de pesquisa para localizarmos informações no código.
O Xcode também possui esquemas de visualização diferentes do editor de código. Para contextualizar, a opção central dos botões do grupo Editor do painel central exibe o .h e o .m respectivo ao  arquivo que se esta trabalhando emparelhados.

Um aspecto interessante do Xcode a se ressaltar são os Schemes presentes no painel central. Nele, configuramos para qual plataforma Apple queremos compilar nosso projeto.

A organização do projeto em pastas lógicas é iniciado da seguinte forma:

Pastas lógicas
  • Pasta com o nome do projeto: Contém todas as classes referentes ao projeto;
  • Frameworks: Contém as bibliotecas que estamos utilizando da API Cocoa. No caso estou usando a Framework Foundation;
  • Products: É o resultado do nosso projeto. Nesse caso, o produto do código dependerá do template que foi usado na criação do projeto. No meu caso, o resultado gerado será uma tela de console.
O aspecto que diferencia o Xcode de demais IDEs é a sua ferramenta de analise do código (disponível através do atalho SHIFT + COMMAND + B). Este comando faz com que o Xcode analise o código buscando possíveis problemas, como, por exemplo, memory leaks, loops infinitos e variáveis não inicializadas.


No próximo post estarei introduzindo alguns conceitos referentes a linguagem Objective-C para, então demonstrar suas principais características.

SEE YOU NEXT MISSION

Desenvolvimento do jogo para IOS

Olá a todos!!!

Até então foram demonstrados diversos conceitos e funcionalidades a respeito do desenvolvimento do projeto em Android. Apesar do mesmo ainda não estar finalizado, decidi inserir um break point momentâneo e trabalhar com o ambiente de desenvolvimento IOS já que a entrega do protótipo do jogo para a matéria de Programação de Jogos da Dispositivos Móveis também se aproxima.

Na minha opinião, desenvolver jogos para a plataforma IOS da Apple é altamente mais complexo do que desenvolver jogos para Android. Para comprovar tal afirmação, elenco os seguintes motivos:
  • Para desenvolvermos uma aplicação em IOS, na prática temos que desenvolver o projeto num Macintosh. Apesar da excelência do produto, há de se concordar que o preço não é acessível;
  • Para testar o resultado, não dispomos de acesso licito aos devices (iPhone, iPad, iPod) como fazemos em Android, a menos que pague-se os 99 dólares da licença de desenvolvedor. A vantagem é que a licença Apple Developer nos da "acesso" à Apple Store;
  • Concatenando com o comentário acima exposto, a Apple Store é considerada um meio de difícil publicação. Alguns dos motivos envolvem a espera na fila de produtos a serem lançados, a lista de exigências para seu produto ser aceito (a mais conhecida delas é que a aplicação deve remover todo o seu conteúdo da memória 5 segundos após ser fechada), a passagem dos dados do produto é recebida por eles apenas via fax, dentre outros motivos;
  • Talvez o maior motivo, a Apple utiliza como linguagem padrão para suas Aplicações o Objective-C que, apesar de possuir alguns elementos interessantes, é a princípio mais difícil de aprender;
  • O Xcode tem as suas peculiaridades, mas ainda não possui o prestígio e a qualidade de IDEs como o Visual Studio e Eclipse.

Apesar disso, diversas são as vantagens de se desenvolver para IOS e Mac OS. Dentre as principais razões, destaco:
  • As plataformas da Apple são muito mais instáveis que as demais;
  • Ao desenvolvermos uma aplicação, devemos nos preocupar apenas com a resolução do dispositivo em questão. Questões que envolvem versão do Sistema Operacional e Hardware são homogêneas para todos os aparelhos (desconsiderando diferenças de desempenho entre plataformas diferentes, como iPhone VS iPad), uma vez que a Apple oferece update gratuito do IOS para as novas versões do SO que venham a surgir;
  • Para quem já programou usando os recursos do Sistema Operacional Windows e a sua temida e mal falada Notação Húngara (existe alguém que ainda não use Windows Form ou XNA?), irá se maravilhar com a diferença entre esta e a Cocoa (API nativa do Mac que nos oferece acesso aos recursos do SO). Até mesmo os header files das frameworks da Cocoa são extremamente organizados e passíveis de leitura;
  • Querendo ou não, a Apple Store é muito mais organizada que o Google Play/Android Market. Pra começar, você dificilmente (para não dizer nunca) irá baixar uma aplicativo em seu IOS que venha infestado de propagandas ou com uma qualidade horrível. Além de que, aplicativos IOS e Mac OS possuem mais tendência a serem comprados devido ao poder aquisitivo do público que consome os produtos dessas plataformas e a dificuldade para se craquear tais produtos ser maior (lembrem-se que o Android é Open Source e isso sempre irá soar negativo para aplicações comerciais);
  • E por fim, o motivo que talvez faça muita gente preferir de cara aprender a desenvolver para dispositivos móveis a partir do IOS é que, apesar da ausência de acesso free aos recursos de um device físico, o emulador de iPhone e iPad são simplesmente fenomenais. A performance e a abertura dos mesmos acontecem em tempo real no Mac. 

Bem, por hora é isso. No próximo post estarei expondo o funcionamento do Xcode...

Até a próxima!

sábado, 10 de novembro de 2012

Audio do menu

Olá a todos!!!

A música do menu pode ser ouvida aqui. Para produção dos elementos sonoros do game, estou utilizando o Garage Band e os loops existentes. O resto é criatividade, paciência e um pouco de talento.

Por hora é só... Até mais!!!

Learning Exploder - Versão 1.0

Olá a todos!!!

Hoje estarei falando sobre o processo de desenvolvimento inicial do jogo Learning Exploder.

Em geral, o processo durou 40 horas e o resultado foi entregue na primeira parcial da matéria de Programação de Jogos para Dispositivos Móveis.

Mais detalhes podem ser consultados neste vídeo...

Enquanto estava fazendo esse vídeo lembrei o quão terrível é trabalhar com esse emulador do Android. Tive que reiniciar o mesmo 3 vezes para o emulador reconhecer o projeto.

Para ter acesso ao jogo, baixe este arquivo, copie para o SD-Card de seu Android, e execute o arquivo a partir do celular. Provavelmente, o aparelho irá bloquear a instalação do jogo, por ter já por definição de fábrica a proibição da instalação de aplicativos não adquirido no Android Market / Google Play.

Até mais!

Aspectos gráficos - Learning Explorer

Olá pessoal!

Hoje estarei falando dos aspectos gráficos do jogo "Learnig Exploder" que estamos desenvolvendo.
Vamos lá!


(Figura 1 - Tela Inicial 1)
Figura 1 - Tela Inicial 1


Eu sempre procuro usar cores associadas a proposta do projeto, assim, na figura 1 podemos ver o fundo simples em degradê azulado, optei por essa cor pelo seu significado relacionado a inteligência, assim como o amarelo do logotipo que também inspira o conhecimento, já que nosso objetivo neste jogo é mexer com o raciocínio ao se deslocar pelos labirintos(fases) com a associação de palavras que irão despertar uma percepção positiva no jogador, que irá aprender novas palavras de uma maneira divertida, bem como inspira-se a pesquisar outras além das escolhidas para o Learnig Exploder!
Associada as cores, também preso pelo significado das formas básicas, o circulo é associado a diversos significados, dentre ele destaco a qualidade de ciclo. Utilizando a ideia de ciclo, coloquei as representações do alfabeto e dos números no interior do circulo para formar o conceito de que sempre temos algo a aprender em qualquer área e que o aprendizado inicial é a base de todos o conhecimento!

Figura 2 - O Círculo e o Aprendizado Básico
Figura 2 - O Círculo e o Aprendizado Básico

A estrela completa o simbolo com a ideia de várias direções e escolhas que temos na vida, também considerada um simbolo de sucesso, demonstra que o conhecimento nos dá oportunidades para fazermos as melhores escolhas.

Figura 3 - Estrela
Figura 3 - Estrela

Por fim, a tela inicial montada, o logotipo tem um efeito de rotação e os botões aparecem através de animação.

Figura 4 - Tela Menu Inicial
Figura 4 - Tela Menu Inicial

Os fundos das fases seguiram os conceitos de cores também e a princípio são como o fundo do menu inicial com a cor alterada se acordo com o nível da fase, mas serão feitos fundos mais elaborados assim que possível. A sequência de cores é: amarelo, verde, azul, roxo, laranja, vermelho, prata e dourado.

Figura 5 - Fundo Amarelo (Fase 1)
Figura 5 - Fundo Amarelo (Fase 1)


A animação clássica de início de fase foi reproduzida com a inspiração (a pedidos) do efeito utilizado no logotipo da Capcom. Segue o Sprite:  

Figura 6 - Ready
Figura 6 - Ready
Figura 7 - Go!!!

A bolinha é uma animação bem simples:
Figura 8 - Bolinha
Figura 8 - Bolinha
E aqui temos as "Cerâmicas" que utilizaremos a princípio, elas tem uma versão contornado para ser usada como efeito:

Figura 9 - "Cerâmica" Borboleta
Figura 9 - "Cerâmica" Borboleta
Figura 10 - "Cerâmica" Cartas
Figura 10 - "Cerâmica" Cartas
Figura 11 - "Cerâmica" Tulipa
Figura 11 - "Cerâmica" Tulipa
Figura 12 - "Cerâmica" Beija-Flor
Figura 12 - "Cerâmica" Beija-Flor
Figura 13 - "Cerâmica" Abóbora
Figura 13 - "Cerâmica" Abóbora

E, um exemplo de animação da abóbora quebrando:

Figura 14 - "Cerâmica" Abóbora Quebrando
Figura 14 - "Cerâmica" Abóbora Quebrando

A explosão será utilizada em alguns efeitos como por exemplo a chamada da tela game over, quando o jogador é vencido em uma fase ela recebe várias explosões.

Figura 15 - Explosão

A tela de créditos tem os dados do curso e das disciplinas a qual apresentaremos o jogo.
Figura 16 - Tela Créditos
Essa é a tela de Game Over que aparece após a explosão, ainda está sem animações, mas pretendemos dar uma agitada nela.
Figura 17 - Tela Game Over

Por enquanto são esses os assets prontos para utilizar e alguns inclusive já implementados!
Até a próxima!



O projeto

Olá a todos!!!

Vamos começar a falar sobre o projeto...

Na etapa de construção da engine, percebi o quão lento é trabalhar com certas coisas usando a SDK, em especial o tratamento de imagens. Infelizmente, apesar de eu conhecer em geral OpenGL, não tinhamos tempo hábil para aprender OpenGL ES, e organizar uma engine acelerada por GPU para o projeto.

Esse fator foi essencial para eu e a Keli termos de repensar o jogo que estávamos nos propondo a desenvolver, pois o Ceramic Destroyer original exigiria um trabalho intenso do processador para calcular as colisões e remover os píxels da imagem.

Assim surgiu a ideia do Learning Exploder, um jogo educativo para Android cujo o objetivo seria controlar uma bolinha usando o acelerômetro por um labirinto visto de cima visando coletar todas as letras em ordem para formar uma palavra em inglês. Essa palavra poderia representar uma imagem, um som ou até mesmo a resposta de uma pergunta.

Esse projeto será utilizado por nós, além de para as disciplina de Programação de Jogos para Dispositivos Móveis e Oficina de Jogos IV, para a matéria de Cultura Religiosa, onde estaremos criando desafios relacionados a essa área do conhecimento ao invés de inglês.

Ainda, estarei utilizando o jogo e o trabalho para fins científicos no Instituto TECPAR, onde trabalho como bolsista de iniciação científica.

No próximo post, minha colega Keli estará descrevendo como está o processo de produção da arte para o jogo...

SEE YOU NEXT MISSION

sexta-feira, 9 de novembro de 2012

Engine para o jogo - parte 2

Olá a todos!!!

Vamos dar continuidade nesse post aos assuntos referentes à engine. Para recaptular, estou descrevendo as principais funcionalidades implementadas para a construção do jogo, levando em conta todo o conhecimento adquirido em Android. Vamos lá:

  • Input: Essa é uma das partes mais complexas da engine, pois leva em consideração todos os tópicos e encrencas já descritas em tópicos anteriores do blog. Primeiramente, desenvolvi os managers de input para Single-Touch, Multi-Touch, Keyboard e Accelerometer, seguindo a lógica do beginning android 4 games development. Por fim, cada manager é devidamente configurado por uma classe genérica de tratamento de input e esta fica responsável por retornar as informações desejadas pelo usuário da engine sobre determinado sensor de eventos.
  • Auxiliar de desenho: Para o desenho, implementei uma classe que renderiza primitivas, texto e bitmaps de forma fácil. No caso dos bitmaps, a classe aceita somente objetos de uma classe que implemente a interface de Bitmap. Assim, classe auxiliar de desenho pode fabricar instâncias de Bitmap com todos os métodos de retorno de informações a respeito do bitmap em questão já ajustadas. Essa classe auxiliar de desenho também oferece maneiras de carregar fontes.
  • Game Manager: Essa classe condensa todos os recursos da engine. Assim, para ter acesso a todos os recursos, basta que cada classe do jogo guarde uma referência da instância do Game Manager. 
    • Essa classe é filha de Activity, ou seja, roda sobre a thread principal e deve ser sincronizada com a classe de Game Loop que roda em outra thread. 
    • Ela também é responsável por setar a próxima tela de jogo a ser exibida. Na lógica da engine, cada tela de jogo é tratada como filha da interface Screen e é a partir da transição de uma tela para outra que funciona a grande lógica dos games desenvolvidos com a engine. Assim, é possível criar novas telas para o jogo sem modificar o Game Manager, além da facilidade da abstração de cada tela, que facilita e muito a correção de bugs.
    • Em geral, o esquema de desenvolvimento utilizando o Game Manager torna invisível grande parte das implementações da engine e usa grande parte dos principios de Padrões de Projeto, tendo o esquema de transição de telas o Padrão Strategy como carro chefe.
  • Matemática: Para cálculo da matemática, a engine utiliza as classes de matrizes e pontos oferecidas pelo Android. Para os Vetores, utilizo a excelente biblioteca desenvolvida pelo professor Vinícius Godoy de Mendonça. Para cálculo de colisão, desenvolvi classes básicas para cálculo de colisão entre box alinhados e circulos e circulos com circulos. A parte de colisão entre dois boxes é oferecida pelo Android.
  • Sprites: Para tratamento de animações, desenvolvi uma classe que recebe as configurações referentes ao comportamento da animação e o nome do arquivo, e a partir disso faz todo o trabalho sujo. Essa classe tem suporte a imagens da pasta drawable e assets, a sprites com sequência de quadros configurável e calcula o tempo de transição de quadro, bastando para o usuário apenas chamar o método update no campo de atualização da lógica do jogo em uma classe derivada da interface Screen.
    • Com relação à transformações, desconhecia as matrizes Android quando iniciei a implementação da classe e acabei fazendo o cálculo da escala de imagens manualmente. Ainda não tive tempo hábil para continuar a implementação dessa classe utilizando os recursos de matrizes.

Todas as ideias aqui apresentadas correspondem às principais implementações da engine que desenvolvi para o projeto. Disponibilizei as interfaces neste link para consulta.


Espero que tenham gostado. E qualquer sugestão não deixem de postar... Até mais!

Engine para o jogo - parte 1

Olá a todos!!! 

O último post marcou a primeira fase do projeto Android, a qual tinha como objetivo estudar as tecnologias envolvidas, assim como as facilidades e dificuldades para o desenvolvimento do jogo. Neste post, irei contextualizar o resultado dos estudos para o desenvolvimento do jogo.

Para o projeto, juntei tudo que havia aprendido e iniciei o desenvolvimento de uma engine baseada no framework do livro já citado Beginning Android 4 Games Development. A seguir, os principais elementos da engine:

  • Audio: A engine possui suporte para os formatos de audio reproduzíveis pelo Sistema Operacional, mas é encorajado o uso do formato OGG por ser free e ser muito utilizado em games. 
    • Um aspecto importante é que toda música reproduzida no Android não pertence ao escopo da aplicação, mas sim ao próprio sistema. Ou seja, se não nos precavermos quanto ao pausamento dos sons a cada saída e fechamento, a música continuará tocando com a aplicação fechada.
    • A parte de audio da engine é dividida em três partes:
      • Uma classe principal que deve servir de fábrica para músicas e sound effects;
      • Uma classe para tratamento de sound effects, que usa como base os recursos da classe Sound Pool do Android;
      • Uma classe para tratamento de músicas, a qual usa como base os recursos da classe Media Player do Android;
  • Leitor de arquivos: Apesar do Android possuir suporte a SQLite, para jogos pequenos seria mais interessante gravar os dados de um jogo em um arquivo de persistência no formato txt. Essa classe é responsável por facilitar a leitura e escrita em arquivo das informações desejadas.
  • Game Loop: O game loop do jogo é controlado pela thread que contém a Surface View. 
    • Para resolver os problemas de diferença de velocidade entre os dispositivos, esse game loop foi programado para tentar seguir uma quantidade definida de frames por segundo, fazendo a aplicação dormir caso sobrem alguns milissegundos para que o celular possa processar outras aplicações, e guardando os milissegundos excedidos caso a aplicação não tenha rodado no tempo máximo que o fps em questão suportaria. 
    • Quando o tempo excedido alcançar o tempo por loop (representado por 1 segundo dividido pelo número de fps), o game loop trata esse excesso e pula uma quantidade de quadros para compensar o tempo perdido, levando em consideração que o gargalo está no desenho. Ou seja, pulando o desenho e mantendo o update da lógica do jogo, o mesmo não apresentará problemas de lentidão em dispositivos mais lentos.
    • A forma como construí esse game loop foi essencial para rodar os jogos na mesma velocidade no celular, tablet e emulador.

Estarei especificando as demais funcionalidades relevantes da engine no próximo post.

Até la!

Desenho, Áudio e Android Manifest

Olá a todos!!! 

Durante os posts anteriores estive estabelecendo uma visão geral do desenvolvimento com Android, mas até agora todos os assuntos abordados servem tanto para Layouts como para Jogos. A partir deste post é que as diferenças entre ambos começarão a aparecer. Vamos lá!

Quando estamos desenvolvendo aplicações em layout, atribuímos elementos a um objeto do tipo Layout como, por exemplo, um LinearLayout. Mas, para jogos desejamos ter uma superfície de desenho em que possamos exibir e animar os gráficos do jogo.

Existem dois tipos de superfícies de desenho: Uma View e uma Surface View. A diferença entre ambas é que, na primeira alternativa, o desenho continua sendo processado quando a aplicação é pausada, e a segunda estabelece uma ligação direta com a tela de desenho e pode ser controlada por uma thread.

Obviamente, para jogos a segunda opção é muito mais interessante. Uma surface view oferece possibilidades inclusive de trabalhar com a GPU (embora que, para desenvolver um projeto 3D, seja necessário trabalhar exclusivamente com a NDK).

O ponto fraco da surface view é, obviamente, o aumento da complexidade do código ao se utilizar threads. Muitas vezes o código deverá ser planejado visando evitar problemas de colisão entre as threads, mas nada que o java não ofereça saídas elegantes.

A forma como escrevemos o back buffer, ou seja, a superfície contendo todos os elementos que desenharemos no frame correspondente é oferecido pela classe Canvas do Android. Essa classe oferece um apanhado de diversas formas primitivas para desenho (pontos, retângulos, linhas, paths) e suporte a desenho de bitmaps, dentre outras coisas.

O Android também oferece uma classe para tratamento de texto chamada Typeface. Essa classe transforma strings de modo fácil em uma fonte TrueType inserida na pasta Assets. Um aspecto importante a se ressaltar é que todo tipo de asset e resource (músicas, sons, ttf, imagens) devem ser decodificadas via código para poderem ser processadas devidamente no jogo. 


Vamos aproveitar o restinho do tópico para falar sobre implementação de músicas no Android. As classes responsáveis pelo tratamento de músicas e sons são, respectivamente, MediaPlayer e SoundPool. A diferença entre ambas está nas funcionalidades. A sound pool possui foco no controle de canais diferentes e de múltiplos sons tocando ao mesmo tempo, enquanto a media player é mais adequada para arquivos de áudio mais longos. Particularmente, gostei mais de trabalhar com a MediaPlayer, apesar de ter ouvido outros desenvolvedores que preferiram a SoundPool.

Aqui finalizo a minha visão geral sobre a API Android. Para os desenvolvedores interessados, esses tópicos apresentaram um importante overview das dificuldades e facilidades a serem encontradas no processo. Para fechar o tópico, gostaria de chamar a atenção para um dos arquivos criados quando iniciamos um novo projeto em Android. Estou falando do Android Manifest!

Esse arquivo XML representa as configurações gerais do projeto. Nele, encontramos qual imagem será usada para representar a aplicação no menu, a versão mínima suportada pela aplicação, qual é a versão da API usada, o nome da aplicação, dentre outras coisas. Esse arquivo também é responsável por conter as permissões que deverão ser pedidas ao usuário para se acessar os recursos do aparelho, como bluetooth, wi-fi e o power manager. Neste arquivo também inserimos todas as activities do projeto.

Bem, por hoje é só....
SEE YOU NEXT MISSION

Android e eventos

Olá a todos!!!

Antes de falar sobre o objetivo deste tópico, que é dar continuidade às explicações sobre como funciona o desenvolvimento de jogos para Android, gostaria de dar uma retrospectiva sobre o que foi dito até agora ao longo dos posts.

Primeiramente defini o objetivo deste blog: registrar o processo de desenvolvimento de um jogo para Android e um jogo para IOS.

Em seguida, retratei que iniciaria o desenvolvimento do projeto pelo Android e transpareci a ideia de criar um jogo baseado no já existente "Ceramic Destroyer".

Em seguida, apresentei um overview da linguagem Java e a IDE Eclipse e, por último, iniciei as postagens sobre o funcionamento da Android SDK e seu desenvolvimento utilizando emuladores e dispositivos externos.

Neste post, falarei darei continuidade ao post anterior.

Vamos continuar pelo tratamento de eventos. O Android possui tratamento de eventos de teclado (keyboard), touch screen (single-toach e multi-toach), acelerômetro, giroscópio, termômetro, bluetooth, e muitos outros.

A parte de teclado é na verdade bem trivial. Basicamente, devemos implementar uma classe que implementa um listener para o teclado e o Android trata de nos avisar quando alguma coisa foi pressionada ou liberada, bastando para nós tratar esse evento da maneira que desejarmos. 
O problema realmente foi o novo ADT (Android Development Tool) que foi lançado trazendo terríveis erros aos códigos legados do ADT anterior, além de bugs no emulador. Dentre as alterações mais chatas no emulador, esta o teclado. Basicamente, no antigo ADT era possível utilizar as teclas do teclado no computador para testar as funcionalidades do teclado e isso foi removido. Também, o teclado emulado que fica presente na parte direita do emulador não está funcionando. Esses detalhes tornam pouco interessante a programação de funcionalidades usando o keyboard sem ter um dispositivo externo com teclado para testar essas funcionalidades (não foi o meu caso).

Com relação aos recursos de touch screen, devemos nós desenvolvedores nos precaver na programação para que nosso código identifique dinamicamente se o dispositivo alvo suporta multi-touch. De resto, a programação é semelhante ao teclado.

Um ponto interessante a se destacar na programação de códigos multi-touch é a dificuldade em se captar esses eventos. O livro "Beginning Android 4 Games Development" trás alguns tópicos interessantes a respeito do tratamento desses eventos. O Android não oferece maneiras interessantes de captar qual foi o dedo que teve um evento na tela. Esse problema se agrava principalmente quando queremos saber qual, dentre os 10 dedos que estão na tela, realmente se moveu.
A solução envolve um escovamento dos bits do evento para saber qual foi o índice em que ocorreu o evento. Um ponto a se considerar também é que o livro acima citado trás uma solução diferente de sua versão anterior (chamada de Beginning Android Games), mas os mesmos comentários da versão anterior para o código se mantêm, o que torna extremamente confuso o entendimento de como funciona o tratamento de eventos multi-touch.

Dentre os demais eventos tratáveis, falarei do Acelerômetro, pois foi o último que estudei e implementei. Esta funcionalidade é tão trivial quanto os demais tratamentos de eventos. Um aspecto interessante da programação envolvendo acelerômetro é um método misterioso (MAIS UM???) que devemos implementar para utilizar o acelerômetro. Acontece que devemos implementar a interface SensorEventListener para receber os eventos deste sensor, e nela existe um método que nunca é chamado (onAccuracyChanged(Sensor sensor, int accuracy)). Essa interface será utilizada para qualquer outro tipo de sensor (giroscópio, termômetro,...)

Por hora é só. No próximo post estarei falando sobre como se desenham gráficos usando Android. Até mais!

Activities, Assets e Resources

Olá a todos!!!

Neste post irei prosseguir as ideias do post anterior, dando um foco maior para o funcionamento do Android já para o desenvolvimento de jogos.

No post anterior falamos sobre como funciona a interface de criação de layouts e que essa interface cria códigos XML que estabelecem uma ponte dos elementos do layout para a API Java onde serão implementadas a lógica de cada elemento.

Cada um desses layouts XML fica na pasta Res juntamente com outros arquivos XML de configuração e com as imagens drawable, as quais já foram discutidas serem uma maneira de facilitar o processo de exibição de imagens de tamanhos diferentes para resoluções diferentes.

A pasta Assets, assim como a pasta Res, necessita de uma maneira de estabelecer relações diretas com a API Java para que possam ser referenciadas dentro do código. Ora quem faz esse trabalho tanto para Res quanto para Assets é o arquivo R.java. Esse arquivo é responsável por estabelecer a ligação entre o recurso e o Java. Felizmente, o Eclipse faz o trabalho sujo de atualizar esse arquivo sempre que um recurso ou asset é adicionado ou removido.

Entendida a forma como funcionam essas ligações, vamos entender como funciona uma aplicação no Java. Toda a lógica do Android é baseada em Atividades (Activity), ou seja, toda classe que deseje representar uma nova janela deverá extender esta classe.

A ponte entre uma Activity e outra é denominada Intent e representa a maneira como nos comunicamos  no momento da finalização de uma Activity e o início de outra. A classe que representa a mensagem entre activities é chamada de Bundle.

Cada Activity possui um ciclo de vida, e é de extrema importância levar em conta todo esse ciclo. Toda a vez que a aplicação é interrompida (quando o despertador toca, quando uma ligação é recebida pelo telefone, dentre outras razões), o método onPause() é chamado pelo Android. O mesmo acontece quando o usuário retorna à aplicação através do método onResume(). Métodos com onCreate() e onDestroy() informam, respectivamente, quando a Activity é criada e destruída.

Por hora é só. No próximo post estarei apresentando como o Android dá suporte aos eventos e como criamos surfaces de desenho para os jogos.

SEE YOU NEXT MISSION

quinta-feira, 8 de novembro de 2012

Android Básico

Olá a todos!!!

Hoje vou falar sobre como funciona o processo de desenvolvimento de aplicativos no Android.

Android é um Sistema Operacional móvel desenvolvido pela Google que roda sobre um núcleo Linux. Para desenvolver para esta plataforma existem duas maneiras. 

A primeira é utilizando a Android SDK e Java, e a segunda é utilizando a NDK. A primeira alternativa trás formas mais fáceis de chegar ao resultado desejado, já a segunda trás uma API nativa para desenvolvimento em C/C++ que se apresentam como uma alternativa mais otimizada e com acesso a recursos ofuscados pela SDK.

Criando-se um projeto no Eclipse usando a SDK, é possível perceber as seguintes pastas:
  • Assets: Pasta que conterá todos os arquivos externos extras ao jogo.
  • Res: Tem como objetivo armazenar os arquivos XML que são utilizados quando estamos trabalhando com Layouts. Também armazena as imagens da aplicação, mas é possível armazena-las dentro da pasta Assets. O interessante desta pasta é que, no caso de layouts, armazenam-se versões da mesma imagem de tamanhos diferentes em pastas diferentes, e assim o Android pode decidir de acordo com a resolução do aparelho qual imagem utilizar.
  • Src: Pasta que contém os arquivos .java. É importante ressaltar que o nome do package da aplicação deve ser único.


Para desenvolvermos uma aplicação com layout, basicamente temos que trabalhar com arquivos XML que deverão especificar os tipos e as características dos elementos de layout (buttom, image view, radio buttom,...). Além disso, esses arquivos deverão estabelecer a ponte entre o elemento e o código de sua lógica que será implementado nas classes java (bem ao estilo Pattern Observer). 

Observe abaixo na figura que, na parte esquerda temos alguns exemplos de componentes como uma TextView, CheckBox, RadioButton, Button, SelectBox, dentre outras... E para construir o layout basta arrastá-los para a tela preta, formando assim códigos XML que podem ser alterados nos layouts de configuração XML. Ainda é possível definir as propriedades de cada elemento, como tamanho, cor e quem será o listener do elemento.


Nesse post foquei em explicar basicamente como funciona a interface de criação de layouts. No próximo post estarei falando sobre como desenvolver uma aplicação do tipo jogo.

Até mais!

Android, emuladores e dispositivos externos

Olá a todos!!!

Neste post irei falar sobre a plataforma de desenvolvimento Android.

Em primeiro lugar, os emuladores. Para cada versão do Sistema Operacional, temos uma versão de emulador. Quando criamos o nosso projeto, especificamos qual será a versão de compatibilidade (versão mínima) e a versão do SO que desejaremos utilizar a API. Isso delimita o que podemos e o que não podemos usar no desenvolvimento da aplicação.

Um ponto a se considerar é a lentidão dos emuladores Android. Realmente é péssimo o desempenho no PC ou no MAC. Realizei testes com o jogo e outras aplicações durante o processo de desenvolvimento e pude constatar que a perda de FPS chegava a ser maior que a metade.

Também realizei os mesmos testes em um celular Samsung Galaxy Next (também conhecido como Samsung Galaxy Mini) e obtive uma performance um pouco maior, apesar deste dispositivo ter se mostrado não forte o suficiente para rodar o jogo tranquilamente em 30 FPS.

Por fim, realizei os testes em um tablet Genesis GT-7220 e obtive resultados bem satisfatórios, provando que os tablets possuem um desempenho mais interessante para jogos.

Todas estas comparações mostram a importância de se desenvolver com cuidado uma aplicação em Android, em especial um game. Recaptulando:

1- Desenvolver uma aplicação em Android é complexo, pois devemos estar constantemente tomando cuidado com as versões dos Sistemas Operacionais, tentando manter o mais multi-versão possível (compatível com várias versões do Sistema Operacional Android).

2- O hardware dos dispositivos que contém o Android são muito heterogêneos. Ou seja, deve-se ter atenção a tópicos como qual será a resolução empregada, como esse jogo se portará em dispositivos rápidos e lentos, e quais são os recursos extras que se deseja utilizar (nem todos os celulares tem teclado de botões por exemplo).

3- Para desenvolver um jogo, é importante ter um dispositivo externo, pois os emuladores de Android são terrívelmente lentos.


Nos próximos posts estarei falando sobre como é desenvolver aplicativos de Layout e jogos usando o Android e quais são as peculiaridades envolvidas.

Até mais!

Eclipse

Olá a todos!!!

Neste post irei falar sobre algumas peculiaridades que observei no período em que programei em Java usando o Eclipse. Gostaria de ter tido alguma experiência com o netbeans para poder oferecer uma comparação mais interessante entre os ambientes de desenvolvimento, mas infelizmente por hora só poderei oferecer as informações que obtive com a experiência.

O Eclipse foca muito nos recursos de facilitação da escrita do código de forma automática. É possível escrever de forma rápida e fácil simplesmente digitando parcialmente as palavras referentes ao comando ou classe e, com o pressionar de um ctrl + espaço, a IDE realiza o trabalho de auto-completar. Isso facilita enormemente o trabalho de passagem de parâmetros (o Eclipse auto-completa o nome dos parâmetros descritos na implementação do método), criação de estruturas, fechamento de chaves e parênteses e inclusão de packages.

Usando a inteligência de detecção de erros da ferramenta, é possível se programar "orientado a erros", escrevendo-se, por exemplo, variáveis, objetos e estruturas ainda não criadas e deixar que o Eclipse ofereça as opções disponíveis para corrigir o erro. A forma como ele detecta o tipo do objeto/variável que desejamos criar é também muito interessante.

Além deste recurso, alguns atalhos oferecidos também são muito úteis.Os que mais utilizei durante o desenvolvimento foram:

1- Command/CTRL + Shift + O: Encontra as packages que estão sendo usadas no projeto, mas que ainda não foram importadas e as inclui.

2- Command/CTRL + Shift + C: Comenta as áreas de código selecionadas.

3- Command/CTRL + Shift + F: Edenta automaticamente o código.


Por fim, gostaria de falar um pouco sobre o depurador do Eclipse. Confesso que tive certo preconceito ao iniciar a utilização do mesmo, pois grande parte dos ambientes de desenvolvimento possuem um depurador fraco se comparados ao do Visual Studio. Apesar disso, utilizei em excesso o depurador do Eclipse e consegui fiscalizar normalmente a compilação do código e os pontos de falha.
Além disso, usando o depurador no Android é possível controlar a aplicação pelo depurador em toda situação. Até mesmo quando fechamos o aplicativo, o depurador continua trabalhando. Quando paramos a depuração, o aplicativo também fecha, o que facilita o fechamento do programa quando o desejarmos.

No próximo post estarei falando sobre o meu processo de aprendizado com o Android.

Abraço!

Java

Olá a todos!!!

Nesse post irei falar sobre minha experiência com Java durante o período de desenvolvimento até então.

Em primeiro lugar, iniciei o estudo da linguagem Java e suas principais características. Até então não possuía uma experiência aprofundada com linguagens gerenciadas. Assim, percebi que o Java usa em grande quantidade os conceitos de Design Patterns que gostaria de reforçar neste projeto.

O primeiro aspecto que me chamou a atenção foi a forma como a linguagem trabalha para ser multiplataforma. O Java roda sobre uma Máquina Virtual (JVM), a qual tem como responsabilidade isolar o aplicativo do Sistema Operacional em questão. Após compilado, o código Java transforma-se em bytecode, sendo este  o código de máquina da JVM.

Esse bytecode, apesar de interessante, tem alguns problemas no que referem à facilidade de observá-lo e entender o código Java que está por trás dele. Isso torna o Java uma linguagem meio perigosa no quesito facilidade de engenharia reversa, e ofuscadores de código podem vir chegar a serem necessários para impedir essa leitura.

Com relação à linguagem, Java é mais fortemente tipado do que C++, o que acaba forçado a realizar casts para tudo. O operador ternário também exige uma variável para armazenar o retorno.

Também programando em Java passei a utilizar mais loops ao estilo foreach, e também achei interessante o caso dos LABELED LOOPS que aparentemente foram desenvolvidos para evitar a única possível necessidade de um goto em Java.

Com Java, passei a trabalhar pela primeira vez em um projeto envolvendo multithreads, e "felizes" foram os momentos em que eu descobri que um erro estava sendo causado pela ausência de um semáforo, o que me fez entender alguns casos críticos famosos de se trabalhar com multiplas threads.

Outro aspecto interessante da linguagem é a sua ausência de sobrecarga de operadores. É muito estranho trabalhar assim com certas classes matemáticas como matrizes e vetores, pois nada fica tão natural usando apenas métodos como ficaria usando os operadores.

Além disso, achei interessante a forma como Java trabalha com a diferença entre classes abstratas e interfaces. Utilizei muito de ambas para fortalecer os princípios de um bom código Orientado a Objetos. Muitas coisas na linguagem se fortalecem no princípio do uso de interfaces, como por exemplo tornar um objeto clonável.

Cada objeto criado em Java é filho de uma classe do tipo Object, a qual contém um método para impressão de dados (semelhante a uma sobrecarga de um operador << e >> em C++), métodos para facilitar o uso do objeto dentro de threads, dentre outros. Os métodos dessa classe também podem ser sobrescritos para que se programe o comportamento desejado.

Também me confundi em alguns momentos enquanto trabalhava com cópias, pois toda passagem de parâmetro em java trabalha por padrão com referências, necessitando de especificações mais braçais para que uma cópia efetiva do objeto seja efetuada.

O último aspecto da linguagem que gostaria de reforçar são as Inner Classes e Annonymous Inner Classes. Ambas as formas de implementação são estranhas à linguagem C++ com que eu estava habituado. 
Inner Classes são classes que criamos dentro de outras classes. Para criar objetos das mesmas é necessário ter acesso à classe que a contém, e de métodos factory para gerar objetos. 
Annonymous Inner Classes são classes que especificamos diretamente na passagem de um argumento que recebe uma classe contendo a implementação da interface ou classe abstrata. Isso possibilita que não necessitemos implementar uma classe que usaremos uma única vez em uma passagem de parâmetro

Bem, por hora é só. No proximo post estarei falando sobre a minha experiência com o compilador Eclipse, sendo este o segundo objetivo do trabalho com Android.

 SEE YOU NEXT MISSION

sábado, 1 de setembro de 2012

Organização das Atividades

Olá a todos!!!

Finalizei a organização das atividades do projeto para android. Elas podem ser encontradas no seguinte link:

https://www.pivotaltracker.com/projects/630789#

Agora para finalizar a etapa inicial do projeto resta somente a produção de um documento básico de Game Design. Estarei fazendo isso nas próximas horas...

 SEE YOU NEXT MISSION