Você está na página 1de 345

Cleuton Sampaio

Manual do Indie Game Developer

Versão Android e iOS

Cleuton Sampaio Manual do Indie Game Developer Versão Android e iOS
Cleuton Sampaio Manual do Indie Game Developer Versão Android e iOS

Manual do Indie Game Developer - Versão Android e iOS CopyrightEditora Ciência Moderna Ltda., 2013

Todos os direitos para a língua portuguesa reservados pela EDITORA CIÊNCIA MODERNA LTDA. De acordo com a Lei 9.610, de 19/2/1998, nenhuma parte deste livro poderá ser reproduzida, transmitida e gravada, por qualquer meio eletrônico, mecânico, por fotocópia e outros, sem a prévia autorização, por escrito, da Editora.

Editor: Paulo André P. Marques Produção Editorial: Aline Vieira Marques Assistente Editorial: Amanda Lima da Costa Capa: Carlos Arthur Candal Diagramação: Equipe Ciência Moderna

Várias Marcas Registradas aparecem no decorrer deste livro. Mais do que simplesmente listar esses nomes e informar quem possui seus direitos de exploração, ou ainda imprimir os logotipos das mesmas, o editor declara estar utilizando tais nomes apenas para fins editoriais, em benefício exclusivo do dono da Marca Registrada, sem intenção de infringir as regras de sua utilização. Qualquer semelhança em nomes próprios e acontecimentos será mera coincidência.

FICHA CATALOGRÁFICA

MELO JUNIOR, Cleuton Sampaio de.

Manual do Indie Game Developer - Versão Android e iOS

Rio de Janeiro: Editora Ciência Moderna Ltda., 2013.

1. Informática 2. Linguagem de Programação 3. Jogo eletrônico

I — Título

ISBN: 978-85-399-0460-2

CDD 0001.642

005.133

323.43

Editora Ciência Moderna Ltda. R. Alice Figueiredo, 46 – Riachuelo

Rio de Janeiro, RJ – Brasil

Tel: (21) 2201-6662/ Fax: (21) 2201-6896

E-MAIL: LCM@LCM.COM.BR WWW.LCM.COM.BR

CEP: 20.950-150

07/13

Dedico este livro à minha esposa, Fátima e aos meus filhos:

Rafael, Tiago, Lucas e Cecília.

“Escolha uma profissão que você ame, e nunca terá que trabalhar um só dia em sua vida.”

Confúcio, filósofo e pensador Chinês: (551 a.c – 479 a.c)

Sumário

Capítulo 1 - Introdução ����������������������������������������������������������������������1

Sobre as plataformas

1

Sobre o código-fonte

2

Capítulo 2 - Revisão de conceitos ������������������������������������������������������3

Tipos básicos de Games

3

Jogos de ação

7

Macro funções de um game

8

Model / View / Controller

10

Objetos e elementos típicos de um Game

11

Jogabilidade

13

Fatores de sucesso de um Game

14

Capítulo 3 - Kit de ferramentas para criação de games����������������17

Ferramentas gráficas

17

Imagens

17

Transparência e canal alpha

18

Unidades de medida

20

Arquivos de imagem

21

Ferramenta para “Sketch”

22

Ferramentas para desenho Raster

23

Ferramentas para desenho vetorial

24

Comparação entre renderização raster e vetorial

25

Game engines

28

HTML 5 + Javascript

28

Nativos

28

Usar a plataforma nativa

30

Ambientes multiplataforma

30

Prototipadores

31

Bibliotecas auxiliares

31

Capítulo 4 - Prototipação do game ��������������������������������������������������33

Usando o Codea

34

Um tutorial rápido em Codea

35

Criando o protótipo do “AsteroidNuts” no Codea

39

Sumário — VII

Usando o “Processing”

49

Um tutorial rápido no “Processing”

51

Criando o protótipo do “AsteroidNuts” com o “Processing”

54

Crie vários protótipos

64

Capítulo 5 - Física de games�������������������������������������������������������������65

Os primórdios

66

Conceitos básicos

66

Aceleração e movimento

68

Colisão

70

Deteção de colisão

72

Engines de física

76

Bullet Physics Library

76

Chipmunk physics engine

77

Box2D

77

Física com Box2D

78

Preparando o laboratório

79

O laboratório Java

80

Normalização e ajuste para renderização

85

Fundamentos do Box2D

87

Força e atrito

93

Corpos circulares

97

Rotação dos corpos

98

Desenhando corpos como polígonos

100

Desenhando corpos como imagens

102

Torque e impulso

107

Deteção de colisão

110

Juntas ou junções

113

Usando o Box2D em plataformas móveis

123

Box2D no Android

123

Box2D no iOS

132

Capítulo 6 - Renderização com OpenGL ES 2�0 ��������������������������143

OpenGL ES

144

Fundamentos

146

Coordenadas dos vértices e da textura

146

Buffers

150

VIII �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Programas de sombreamento

152

Matrizes

154

Exemplo utilizando Android e projeção perspectiva

159

Entendendo a GLSurfaceView

160

A

implementação

163

Concluindo

175

Exemplo utilizando iOS e projeção perspectiva

176

Entendendo o GLKit

176

Criando uma aplicação OpenGL ES

178

A

implementação

179

Achatando as coisas

190

Implementação em Android

190

Implementação em iOS

193

Capítulo 7 - Framework de Física e Renderização ����������������������195

Um framework básico

196

O

esquema XML do arquivo de modelo de game

197

Proporcionalidade dos GameObjects

200

Coordenadas e VBOs

201

Movimento e rotação de objetos

204

Atualização do mundo Box2D

205

Renderização do modelo

206

Mipmaps

207

Uso do Framework

209

Conclusão

212

Capítulo 8 - Técnicas Comuns em Games ������������������������������������215

Como exibir um HUD

215

Aumentando o framework de game

220

Integrando o game em uma aplicaç�o móvel

226

Plataforma Android

227

Plataforma iOS

231

Tempo e movimento

233

Game Loop

234

Movimento

247

Efeito de paralaxe

256

Técnicas de paralaxe

257

Exemplo de paralaxe com camadas de GameObjects

258

Sumário — IX

Implementação Android

261

Implementação iOS

267

Games do tipo plataforma

273

Implementação Android

276

Implementação iOS

278

Sistemas de partículas

280

Composição

280

Um exemplo

281

Implementação em Android

283

Implementação iOS

291

Conclusão

296

Capítulo 9 - Vamos Criar um Game����������������������������������������������297

Limitações

299

Licença de uso do código-fonte

299

A concepção

300

Jogos casuais

301

Jogabilidade

301

Implementação Básica

302

I18N e L10N

302

Alterações no modelo do game

303

Alterações na carga do nível corrente

307

Alterações no Game Loop

309

Colisões

311

Registro de tempos

315

�est�o de memória no iOS

323

Uso do GLKBaseEffect

324

Procure Memory Leaks

327

Verifique se está realmente liberando a memória

328

Conclusão

332

Possíveis melhorias no game

333

Capítulo 1 Introdução

Quando eu comecei a desenvolver games, li muitos livros sobre o assunto e fiz muitas pesquisas no �oogle. Muitos dos problemas que eu passei no início tive que batalhar muito para resolver sozinho. Dessa forma, reuni um conjunto de técnicas ao longo do meu aprendizado, que são úteis até hoje. Durante esse aprendizado, notei que é muito difícil encontrar guias práticos de uso, com exemplos simples, o que nos força a ler muito e escrever muitas provas de conceito, perdendo tempo neste processo. Então, resolvi colocar no papel tudo o que eu havia aprendido, e que po- deria ser útil para outras pessoas. Assim, nasceu a ideia deste livro, que é um guia prático com soluções para os problemas comuns no desenvolvimento de games móveis. Eu queira algo mais que um “recipe book” (livro de receitas), porém me- nos que uma referência completa. Um livro que você consegue ler rapidamen- te e consultar sempre que precisar, com inúmeros exemplos em código-fonte, além de um game completo. Neste livro, eu assumo que você, leitor, leitora, é um desenvolvedor ex- periente e que deseja criar games para plataformas móveis, especialmente:

Android e iOS. Apesar de já haver escrito livros introdutórios sobre o assunto, este é um livro para profissionais que desejem entrar no lucrativo negócio de desenvolvimento de games, tornando-se um “Indie �ame Developer” (desen- volvedor independente de games). Ao longo do livro, você construirá um framework simples, porém abran- gente, e que pode ser utilizado para criar games móveis biplataforma (Android e iOS) rapidamente. O game exemplo do livro “Bola no Quintal”, foi feito em apenas 1 semana para as duas plataformas! A melhor maneira de aproveitar todo o conteúdo é ler com a “mão na mas- sa”, rodando todos os exemplos de código.

Sobre aS plataformaS

Este livro apresenta exemplos em Android e iOS, logo, você deverá ter instalados os dois kits de desenvolvimento. Nada impede que você opte por uma das duas plataformas, pois o livro n�o obriga você a conhecer ambas. A

2 — Manual do Indie �ame Developer - Vers�o Android e iOS

plataforma Android utilizada é a última vers�o disponível (4.2, API = 17), po- rém, os exemplos podem ser executados em qualquer dispositivo com versão “�ingerbread” (maior ou igual a 2.3). A plataforma iOS utilizada é também a última vers�o disponível (6.1), com Xcode 4.5. Se optar por utilizar as duas plataformas, será necessário utilizar um com- putador Mac / OS X, com versão mínima “Mountain Lion”, podendo desen- volver para Android e iOS.

Sobre o código-fonte

Todo o código-fonte do livro está disponível para download, em formato zip. Você poderá encontrá-lo nos seguintes locais:

• Site da editora: http://www.lcm.com.br, procure pelo título do livro;

• Site específico deste livro: http://www.indiegamerbrasil.com;

• Site “The Code Bakers”: http://www.thecodebakers.com.

Se tiver alguma dúvida ou dificuldade para instalar os projetos ou sobre o livro, por favor me contate:

Capítulo 2 Revisão de conceitos

Que coisa apaixonante! S�o capazes de despertar emoções, tanto

negativas como positivas e são obras de arte “vivas”, que deixamos para a posteridade. Se você nunca criou um game, n�o sabe qu�o boa é a sensaç�o de saber que as pessoas passam horas se divertindo com a sua criação. Se alguém me diz que criou um compilador, ou um sistema operacional, certamente vai me impressionar. Agora, se alguém me diz que criou um Game, certamente vai chamar minha atenção imediatamente. Para mim, o “ultimate fight” de todo programador é criar um �ame. Isto é o que diferencia os bons dos comuns. Para mim, desenvolver um �ame é a maior prova de competência para

um programador. É realmente um desafio muito grande, pois existem muitos aspectos a serem abordados. Um game é um projeto de software complexo, com vários recursos, de áreas diferentes envolvidas.

�ames

tipoS báSicoS de gameS

Existe mais de uma maneira de classificarmos um game, dependendo do ponto de vista. Se estivermos falando sobre visualização, podemos começar com:

Games 2D: aqueles em que jogamos nos movendo apenas em duas direções. Podem até utilizar recursos para dar “ilusão” de profundi- dade (como “paralaxe”, vis�o isométrica etc), mas nos movemos em um plano. Existem jogos que permitem mudar de plano (e perspec-

tiva), como o “Fez” (http://en.wikipedia.org/wiki/Fez_(video_game)),

mas ainda são basicamente 2D nos movimentos;

Games 3D: aqueles em que jogamos nos movendo em seis graus de

movimentos possíveis de: aproximaç�o / afastamento (eixo “z”), di- reita / esquerda (eixo “x”), cima / baixo (eixo “y”), e rotações em cada eixo. Alguns games 3D não permitem isso tudo, restringindo as rotações, por exemplo; Há uma certa confusão quando falamos em “Games 3D”. Algumas pessoas confundem este conceito com ilusão 3D. Na verdade, o conceito que a litera- tura e os “gamers” mais aceitam é o dos “6 graus de liberdade”.

4 Manual do Indie �ame Developer - Vers�o Android e iOS

Manual do Indie �ame Developer - Vers�o Android e iOS Ilustraç�o 1: Seis graus de liberdade

Ilustraç�o 1: Seis graus de liberdade (autor: Horia Ionescu, Wikipedia http://en.wikipedia.org/wiki/Six_degrees_of_freedom)

A figura anterior nos mostra os movimentos possíveis em um verdadeiro �ame 3D. Podemos: correr, pular, saltar, rolar (nos três eixos) etc. Alguns ga- mes limitam o movimento somente aos três eixos, evitando rotações, porém, mesmo assim, não se limitam a um plano, como os Games 2D. Também podemos classificar um �ame quanto ao seu tipo de projeç�o, que é a maneira como o modelo é projetado na tela.

que é a maneira como o modelo é projetado na tela. Ilustraç�o 2: Projeç�o 3D Se

Ilustraç�o 2: Projeç�o 3D

Se for um Game 3D, isto é mais crítico ainda. A tradução do modelo “espa- cial” para o modelo 2D da tela pode ser feito de várias maneiras:

Projeção Ortográfica” (ou ortogonal): é a ilus�o de 3D criada ao criarmos projeções ortogonais ao plano, ou seja, não há diferença de tamanho entre objetos próximos e objetos distantes. Desta forma, mostramos os elementos em um ângulo diferente do que veríamos apenas de cima, ou de lado. Evita os cálculos complexos de projeção 3D e mantém uma boa ilusão para o jogador.

Capítulo 2 - Revis�o de conceitos � 5

Visão Isométrica”: n�o é uma projeç�o, mas uma forma de mos- trarmos os objetos. Neste tipo de visão, rotacionamos um pouco os eixos para mostrar mais detalhes dos objetos, criando a ilusão 3D. Neste caso, o ângulo entre os eixos (x, y, z) no plano é igual, ou seja:

120 graus. Normalmente, a vis�o isométrica é utilizada com proje- ç�o ortográfica. Era muito comum nos anos 80 e 90, embora alguns jogos ainda a utilizem. Alguns exemplos famosos que usam visão isométrica: Q*Bert (Gottlieb), Civilization II (MicroProse), Diablo (Blizzard);

Projeção Perspectiva”: vem do desenho tradicional, no qual as partes mais próximas parecem maiores do que as mais distantes. Também é conhecida como perspectiva cônica. Dão maior ilusão de realidade aos games, porém exigem maior complexidade de progra- maç�o e poder de processamento. Os jogos mais modernos, como:

Battlefield, Assassin’s Creed, Halo e outros apresentam visão em perspectiva;

Creed , Halo e outros apresentam visão em perspectiva; Ilustraç�o 3: Projeções 2D de um cubo

Ilustraç�o 3: Projeções 2D de um cubo

É claro que procurei simplificar ao máximo o conceito de projeç�o 3D,

mas é apenas para facilitar o entendimento. Se quiser saber mais, recomendo um bom livro, como o “Mathematics for Game Developers”, de Christopher Tremblay (Amazon). Porém, existem bons artigos introdutórios na Wikipedia:

• Isometric graphics in video games and pixel art: http://en.wikipedia.

Também existem classificações de games quanto às suas características, algumas delas s�o:

Arcade”: este termo é mal interpretado, mas sua origem vem das máquinas de jogos, conhecidas aqui como “Fliperama”. Jogos “ar- cade” possuem regras simples, partidas rápidas, com pontuação,

6 — Manual do Indie �ame Developer - Vers�o Android e iOS

vidas, vis�o Isométrica etc). Exemplos de “arcades” clássicos: “Spa- ce invaders” e “Pac-Man”. Os jogos “arcade” evoluíram e hoje est�o disponíveis em várias plataformas, incluindo mobile;

Jogos de Ação: desafiam o jogador fisicamente, seja por coorde- nação motora, visão de movimento ou tempo de reação. Possuem várias subcategorias, como: plataforma, tiro e luta. Exemplos clás- sicos: “River raid” (Atari), “Sonic” (SE�A), “Super Mario (Ninten- do) e outros mais modernos, como: “Angry Birds” (Rovio), “Jetpa- ck joyride” (Halfbrick). Na verdade, “arcades” s�o jogos de aç�o, só que com regras e visual mais simples;

Aventura (adventure): jogos que desafiam a inteligência do joga- dor, colocando-o em determinado mundo, com uma miss�o a cum- prir. Nos primórdios da computaç�o pessoal, os jogos de aventura eram simples, muitas vezes textuais, ou com poucos gráficos. Eu gosto de citar os exemplos do Renato Degiovani, como: “Serra Pe- lada” e “Angra-I”. Hoje em dia, muitos jogos de aventura também misturam características de jogos de ação, como os “Shooters”;

Role Playing Game (RPG): s�o derivados dos famosos jogos de RPG textuais, como “Dungeons & Dragons”. Na verdade, são jogos de aventura, nos quais o jogador assume um papel e uma vida para- lela em um universo virtual. A principal diferença para os jogos de aventura tradicionais é a duração do jogo, que pode ser indetermi- nada. Hoje em dia, os jogos RPG ganharam versões multiusuário online, como os MMORPG – Massively Multiuser On-line RP� (RP�s on-line massivamente multiusuários). Exemplos: “World of Warcraft” (Blizzard) e “Ragnarök” (�ravity Corp);

Tile based games: podem ser jogos de aç�o ou RP�, nos quais os personagens se movem em um “tabuleiro”, de casa em casa. Exis- tem vários padrões e ferramentas para criar “Tile Based Games”, como o padr�o TMX (https://github.com/bjorn/tiled/wiki/TMX- -Map-Format) e TiledEditor (http://www.mapeditor.org/). Alguns RPGs e jogos de aventura são também “Tile Based”;

Menu games: s�o jogos de simulaç�o e RP�, com interface baseada em escolha. Parecem muito com os jogos de cartas, como: “Magic”. Você tem uma série de atributos e vai desafiando os outros jogado- res, acumulando vitórias ou amargando derrotas. Um bom exemplo é o “Mafia Wars” (Zynga);

Capítulo 2 - Revis�o de conceitos � 7

Simuladores: simulam veículos ou atividades. Existem simuladores de voo (Microsoft Flight Simulator), de carro (�ran Turismo – Sony), de cidade (SimCity – Maxis). S�o mais difíceis e desafiadores;

Estratégia: s�o uma mistura de simulaç�o e RP�, no qual o joga- dor tem que conquistar um objetivo, geralmente através da guerra. Exemplos: “Age of Empires” (Microsoft) e “Civilization” (Micro Prose); Outra classificaç�o importante é quanto ao público-alvo do �ame, por exemplo:

Infantis: jogos para crianças, geralmente n�o alfabetizadas ou em fase de alfabetização. São simples e visuais;

Jogos para meninas: as meninas est�o cada vez mais “tomando de assalto” o mundo dos games e existem jogos específicos para elas, como: jogos de vestir, jogos de cozinhar, jogos de princesas;

Casual games (jogos casuais): s�o feitos para quem n�o é jogador habitual (ou “gamer”). S�o para pessoas que jogam casualmente, sem ter isto como atividade constante. Podem ser de vários tipos, mas, geralmente, são simples, com poucas regras, fácil jogabilidade e baixo comprometimento (você n�o tem que criar uma “carreira”). Podem ser quebra-cabeças simples, como: “Where is my water” (Disney) ou jogos de tiro, como “Angry Birds” (Rovio);

Hardcore games: s�o feitos para jogadores habituais ou “gamers”. Normalmente, exigem um comprometimento maior do jogador, que tem que criar uma “carreira” virtual, que pode ser comunicada em redes sociais de games. �eralmente possuem várias sequências, como: “Assassin’s Creed” (Ubisoft), “Battlefield” (EA �ames) ou “�ran Turismo” (Sony);

Jogos de ação

O objetivo principal deste trabalho são jogos de ação. Em primeiro lugar, porque todos os elementos clássicos (Player Object, NPC, �ame loop) s�o en- contrados neles e, em segundo lugar, porque são uma “porta de entrada” para o desenvolvimento de games. Os jogos de aç�o podem ser divididos também em subcategorias, como:

Plataforma: s�o jogos 2D com ilus�o 3D, nos quais o jogador se move entre plataformas, de diversas altitudes, pulando, correndo e saltando. Ele pode ter que enfrentar desafios físicos, como abismos,

8 — Manual do Indie �ame Developer - Vers�o Android e iOS

ou mesmo adversários. Exemplos s�o: “Sonic” (SE�A), “Super Ma- rio” (Nintendo) e, mais modernamente, “Super Meat Boy” (Team Meat);

Tiro: seu objetivo é matar inimigos atirando diretamente neles ou derrubando-os. Podem ser simples como o “Angry Birds” (Rovio), ou complexos, como o “Doom” (Id Software / Nerve Software). En- tre os jogos de tiro, existem os “First Person Shooters”, nos quais a vis�o é a do jogador (em primeira pessoa), ou “Third Person Shoo- ters”, nos quais a visão é externa ao jogador;

Luta: s�o jogos nos quais o jogador é desafiado a derrotar lutado- res, que podem ser totalmente virtuais, ou avatares controlados por outras pessoas. Alguns exemplos s�o: “Street Fighter” (Capcom) e “Mortal Kombat” (Midway games); Jogos de ação são baseados em tempo, ou seja, a cada fatia de tempo a posiç�o do jogador (e das balas) muda, sendo atualizada constantemente. Quando o processamento de uma fatia de tempo demora demais, acontece o efeito de “Lagging”, que é quando o jogador percebe a lentidão do jogo em determinados momentos. O “Lag” pode ter diversas causas, como a latência da rede, em caso de jogos multiusuário, ou mesmo a lentidão da renderização de frames. O “Lag” pode causar grande insatisfação no usuário, compromen- tendo o sucesso do Game. Devido a esta característica de sensibilidade ao tempo, jogos de ação exi- gem muito do programador. É necessário racionalizar os gráficos, utilizando ao máximo o poder de processamento de �PU (�raphics Processing Unit), e também empregar recursos de multiprogramação, de modo a aproveitar o pa- ralelismo, afinal, muitos dispositivos móveis s�o multicore (dotados de mais de uma CPU – ou núcleo).

macro funçõeS de um game

Se pensarmos nas macrofunções de um game, veremos algo como o dia- grama seguinte.

nas macrofunções de um game, veremos algo como o dia - grama seguinte. Ilustraç�o 4: Macro

Ilustraç�o 4: Macro funções de um game

Capítulo 2 - Revis�o de conceitos � 9

Inventário Responsável pelos objetos e propriedades do Game. Os elementos ativos do jogo (personagens ou Player Objects e NPCs) e suas propriedades (quan- tidade de vidas etc).

Pontuação Responsável por acompanhar a pontuação do usuário, suas conquistas e o compartilhamento destas informações.

Estratégia Quando o jogo tem caracteres próprios, n�o manipulados pelo usuário (Non-Player Character ou NPC), é preciso dar alguma inteligência a eles, caso contrário, o jogo será fácil demais. Alguns tipos de jogos dispensam a estratégia, baseando-se apenas em cálculos aleatórios, como: labirintos, por exemplo. Jogos do tipo “Shooting” (2D, 3D, TPS, FPS), quando n�o est�o em modo multiusuário, necessitam de estratégias avançadas, para dar a sensação de realidade ao usuário.

Configuração Responsável pela persistência e recuperaç�o de todas as informações de configuraç�o do jogo, como: níveis oferecidos, nível do jogador, conquistas, opções etc.

Game loop

É o conjunto de comandos repetidos a cada fatia de tempo, responsáveis

por movimentar os objetos, atualizando o modelo de dados. Ele também pode, ao final do processamento, invalidar a apresentaç�o, ordenando o redesenho da tela. Em jogos de ação, geralmente existe um Game loop baseado em tem- porizador, que atualiza a tela em determinadas fatias de tempo (time frame). Alguns tipos de jogos dispensam este recurso.

Animação Os caracteres do jogo e até mesmo o cenário podem exibir animações. O personagem pode sorrir, chorar, gritar e o cenário pode mudar. Até mesmo a movimentação dos personagens é tratada por esta função. A animação também envolve a técnica utilizada para desenhar os objetos na tela a cada fatia de tempo passada.

Física

A macrofunção de física é muito importante em jogos de ação. Ela é res-

ponsável por dar realismo ao movimento dos caracteres. Coisas como: impul- so, gravidade, movimento e colisão são tratadas por esta função.

10 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Interação Controla a maneira pela qual o usuário interfere no jogo. É responsável por capturar o “input” do usuário e converter em ações no jogo.

Comunicação É responsável por comunicar ao usuário o “status” do jogo, e também o resultado de suas ações. Pode manter “energy bars”, contadores, emitir sons, acionar explosões etc.

Algumas destas macrofunções podem ser implementadas em parte por bi- bliotecas de terceiros, como: Box2D e Open�L ES. Porém, mesmo assim, é necessário um esforço do desenvolvedor para configurar e interagir com elas. Uma função muito importante é a de “Inventário”, que também abrange o modelo de dados do Game.

Model / View / Controller

Um �ame bem construído é sempre baseado no padr�o MVC – Model / View / Controller, no qual os três aspectos da aplicaç�o est�o separados:

• Model: responsável por manter o estado da aplicaç�o;

• View: responsável por ler o estado atual e apresentar ao usuário;

• Controller: responsável por alterar o estado da aplicaç�o atualizando o modelo e controlar a atualização da “View”; O modelo de um �ame é a sua representaç�o em memória. Normalmente, mantemos referências dos objetos ativos, como: caracteres e cenário. Mas po- demos ter variações, como camadas diferentes, para dar efeito de “paralaxe”

(http://en.wikipedia.org/wiki/Parallax_scrolling), que é quando os objetos distan-

tes se movem mais lentamente do que os objetos mais próximos, dando ilus�o de profundidade.

os objetos mais próximos, dando ilus�o de profundidade. Ilustraç�o 5: Efeito paralaxe - Wikipedia:

Ilustraç�o 5: Efeito paralaxe - Wikipedia: http://en.wikipedia.org/wiki/Parallax_scrolling

Capítulo 2 - Revis�o de conceitos � 11

Na figura, vemos três camadas de objetos (céu, celeiros e ch�o), que se movem em velocidades diferentes, dando ilusão de profundidade ao Game. A camada de apresentaç�o (ou View) de um �ame é responsável por cap-

turar o estado do modelo e desenhar os objetos em sua posição atual. Existem várias técnicas para desenhar objetos, desde utilizar os próprios “Widgets” nativos do aparelho (Android ImageView ou iOS UIView), ou desenhar di- namicamente os elementos (Android onDraw / iOS drawRect:(C�Rect)rect). Finalmente, a camada Controller tem a missão de atualizar o modelo e ordenar que a camada de apresentação atualize a tela. A camada Controller

é responsável por executar o “Game loop” e por obter o “input” do usuá-

rio. Também deve se comunicar com a macrofunção de “Estratégia” para ver como o jogo deve reagir.

objetoS e elementoS típicoS de um game

Temos alguns elementos comuns em vários tipos de games, especialmente nos jogos de ação. Por exemplo, sempre existe um objeto que representa o jo- gador ou que ele está controlando diretamente. Este tipo de objeto é chamado de “Player Object”. Existem casos em que mais de um PO (Player Object) existe ao mesmo tempo, e o jogador consegue mudar o controle de um para outro (Sonic & Tails, Jogos de Futebol etc). Porém, geralmente, o jogador está controlado apenas um único PO a cada momento. O Player Object pode ser uma nave, como no famoso jogo “Asteroids”

(Atari http://en.wikipedia.org/wiki/Asteroids_(video_game)), no qual o jogador

tinha uma nave e podia virar e atirar contra os asteroides. Também pode ser um objeto como uma bola, como no jogo para iPad “Labirynth HD” (Illusion Labs AB). No jogo que apresentei em meu último livro, “BueiroBall”, o joga- dor controlava a mesa, logo, todas as bolas eram POs. Outro tipo de objeto é o NPC – Non Player Character (Caractere ou per- sonagem n�o controlado pelo jogador). Ele representa o adversário, que pode (ou n�o) ser dotado de alguma inteligência. Nos jogos multiusuário, o NPC pode ser um PO controlado por outro Jogador, ou pode ser algo controlado pela inteligência do jogo em si. NPCs existem para complicar a vida do joga-

dor, tornando a partida mais divertida e interessante. Quem é que não se lem- bra das “tartarugas” do “Super Mario”? O ponto mais importante dos NPCs

é que eles possuem “movimento” e “comportamento”, ou seja, podem atirar,

perseguir, se esconder, explodir ou tomar atitudes, que são controladas pela macro função de “Estratégia” do jogo. Um NPC é sensível ao movimento e à colisão.

12 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Levando em conta a característica de sensibilidade ao tempo, típica dos

jogos de ação, um NPC ocupa fatia considerável do processamento e dos re- cursos. Quanto mais NPCs um jogo tem em determinado momento, maior

a quantidade de recursos para atualizá-los e movimentá-los. Balas também

podem ser consideradas como NPCs, pois se movimentam e são sensíveis a colisões. Também existem os objetos estáticos, que não são sensíveis a colisões. Objetos estáticos podem até se mover, mas sempre como parte de um cenário. Não são sensíveis a colisões e nem podem ser controlados pelo jogador. Al- guns exemplos: cenário, nuvens, árvores distantes, montanhas etc. Em certos

casos, os objetos estáticos nem existem, sendo parte da imagem de fundo. Em jogos mais modernos, objetos podem ser acrescentados ao fundo para dar a ilusão de paralaxe. O importante é que objetos estáticos não podem ser afeta- dos pelo PO ou pelos NPCs. Jogos mais modernos permitem que se deforme em algum grau o cenário, destruindo prédios, veículos de fundo etc. Nestes casos, os objetos estáticos estão se comportanto como NPCs, recebendo e se deformando em função de tiros, o que exige um alto poder de processamento da console ou do dispositivo móvel. Game Loop é o núcleo de atualização de um jogo de ação. É nele que ocorre a atualização do “Modelo” e pode também ocorrer a “renderização” da “View” (MVC). Os game loops mais simples podem fazer apenas isto:

1.

Verificar se o usuário entrou com algum estímulo;

2.

Executar a estratégia pra os NPCs;

3.

Mover o Player Object;

4.

Mover os NPCs;

5.

Verificar colisões;

6.

Atualizar inventário;

7.

Invalidar a “View”;

8.

Dar feedback sonoro.

Na verdade, o �ame loop constrói um “momento” do jogo, que é apresen- tado em sequência de modo a dar a ilus�o de movimento. Apesar de parecer simples, existem várias considerações importantes a respeito do Game loop.

Por exemplo, ele comanda a renderizaç�o? Ele é baseado em time-frame? Ele roda em um “Thread” separado? Como lidar com a concorrência? Em alguns casos, o Game loop é independente da fase de “renderização”,

e ocorrem em momentos (e até em CPUs) separados. O ideal é que o �ame

loop seja “enxuto” o suficiente para rodar a cada Time-frame, evitando “Lag”.

Capítulo 2 - Revis�o de conceitos � 13

Outro problema típico é a aceleração provocada pelo hardware. Por exemplo, ao jogar em um dispositivo mais veloz, o �ame loop fica mais rápido e os NPCs também. É preciso haver um controle de temporização, garantindo um “frame-rate” (taxa de atualizaç�o) constante por segundo. Normalmente os games atuam entre 30 e 60 FPS (frames por segundo). Game Level ou nível, pode ser entendido como duas coisas diferentes: o nível em que o jogador está e o cenário do nível atual. Na verdade, Game Le- vel é o conjunto de: cenário, miss�o e elementos que o jogador deve enfrentar em um jogo. Alguns jogos não possuem este conceito, por exemplo os “Never ending games” (jogos que n�o terminam), como o “Temple Run” (Imangi), por exemplo.

Jogabilidade

Jogabilidade, ou “Gameplay”, é uma característica ligada à usabilidade do

jogo, ou seja, o qu�o o jogo nos diverte. Eu diria que é o somatório das expe- riências do usuário durante o jogo, que envolve: facilidade de controle, boa visualizaç�o de informações, nível crescente e ajustado de desafios etc. Outros aspectos que influenciam a jogabilidade s�o:

Satisfação proporcionada ao jogador;

Facilidade de aprendizado do jogador;

• Eficiência de envolvimento. O qu�o eficientemente o jogo envolve o jogador. Jogos eficientes envolvem o jogador rapidamente;

Motivação para evolução, ou se o jogo motiva o usuário a cumprir atividades;

Cativação, se o jogo faz com que o usuário volte a jogar novamente ou se interesse em adquirir novas fases, armas etc; Um dos fatores importantes na jogabilidade pode ser a socialização, ou a

facilidade que o game dá para divulgar suas conquistas. Muita gente confunde “jogabilidade” com “facilidade de jogar”, que é um dos aspectos do conceito. Embora seja muito importante, a usabilidade (faci- lidade de jogar) sozinha n�o garante o sucesso de um game. Talvez seja melhor citar alguns exemplos de games com boa jogabilidade:

Angry Birds”: simples, fácil e rápido de aprender;

World of Goo”: fantástico! Embora seja um jogo de desafios, sua jogabilidade é ótima;

Fruit Ninja”: igualmente simples e fácil, com alta eficiência de envolvimento.

14 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

fatoreS de SuceSSo de um game

Um game bem projetado envolve várias atividades separadas:

Game design: é o processo de criar o conteúdo, as regras, os cená- rios, os personagens e a Jogabilidade. É um trabalho que envolve várias especialidades, não apenas programação. Durante o Game

design é muito produtivo criar protótipos do �ame, para avaliar se o conjunto está agradando;

Mecânica do Jogo: estuda-se a interaç�o do usuário com o �ame, como serão os movimentos, controles e como serão implementadas as regras. A mecânica também se preocupa com o “desacoplamento” entre os níveis e o código-fonte, procurando parametrizar a seleç�o

e montagem de níveis. Também pode envolver prototipação para

estudo e seleção de alternativas, além de seleção de “engines”, mo- dalidades e recursos para dar ao usuário a melhor experiência com

o game;

Game construction: é a programaç�o do jogo propriamente dita, que engloba a criaç�o de artefatos (imagens, sons, música), níveis (cenários, dificuldade, etc) e código-fonte para a implementaç�o da mecânica do jogo de acordo com o “Game design”; São aspectos diferentes entre si e que não devem ser tratados apenas como problemas de programaç�o. Em equipes independentes (“indie gamers”) é co- mum termos esses conceitos misturados, porém, os games mais bem sucedidos são aqueles em que existem especialistas de várias dessas áreas envolvidos. Outro fator de sucesso, sem dúvida é o visual do Game, que deve ser atra- tivo e coerente com o �ame design, ou com a história e ambientaç�o. Um dos exemplos mais interessantes é o do “World of �oo” (2D Boy), que tem um visual meio dark e nojento, bem apropriado para as bolas de “Goo” do jogo (gosma ou coisa nojenta). Outros exemplos de visual interessante s�o: “Angry Birds” (Rovio), “Fruit Ninja” e “Jetpack joyride” (Halfbrick), “Where’s my water” (Disney) e vários outros. Quando falamos em jogos móveis (este trabalho é voltado para eles), a jogabilidade tem outros critérios de avaliação. Quando estamos em casa, com um Xbox / Kinect, da Microsoft, ou um PS3, temos vários recursos para con- trolar o �ame, porém, quando estamos com um Smartphone (um iPhone ou um Android qualquer) ou mesmo um Tablet, os recursos s�o mais limitados. Embora contemos com acelerômetro e multitoque, não temos o mesmo con- trole que um Joystick ou um dispositivo ótico proporcionam. A tela é menor e, geralmente, n�o estamos em um ambiente ótimo para jogar (penumbra,

Capítulo 2 - Revis�o de conceitos � 15

silêncio e uma tela de LED enorme). A jogabilidade para jogos móveis deve ser estudada levando-se em conta estas características. Um erro muito comum dos desenvolvedores de games móveis é criar as mesmas versões para smartphones e tablets. Não são a mesma coisa, embora, com o Samsung �alaxy S III e o iPhone 5, os smartphones estejam crescen- do, ainda s�o bem diferentes de um tablet de 8 ou 10 polegadas. É necessário adaptar a jogabilidade ao tamanho do dispositivo. A originalidade também tem um papel importante no sucesso de um Game, especialmente se for do tipo “casual”. Games muito parecidos com outros, de maior sucesso, n�o s�o bem vistos e a tendência do público é considerar como uma imitaç�o, mesmo que seja apenas uma coincidência. Quanto mais origi- nal seu game for, mais poderá chamar a atenção deste público. Neste livro, não vou falar sobre este assunto, mas a forma de “monetiza- ção” também pode ter um impacto positivo ou negativo no Game. Em meu livro anterior “Mobile �ame Jam” (www.mobilegamejam.com), focamos muito nestes aspectos, porém, não podemos deixar de mencionar alguns problemas. Para começar, nem todos os usuários são fãs de jogos “Ads based” e podem se irritar com aquela faixa de tela utilizada para veicular anúncios. Eu tenho games publicados que são deste tipo, e a rentabilidade é muito baixa. Outra forma que deve ser evitada é cobrar licença de uso. Se você já cobra pelo uso sem deixar o usuário experimentar, é receita para o fracasso, a não ser que seu game seja realmente sensacional. O ideal é dar ao jogador uma maneira de experimentar o game antes de comprá-lo. Aí entra o processo de “in-app pur- chase” (compra por dentro da aplicaç�o), e os “bens virtuais”. É uma maneira de fazer o usuário se div ertir e recuperar gradativamente o seu investimento.

Capítulo 3 Kit de ferramentas para criação de games

Quando eu era garoto, passava aquele seriado antigo do Batman (DC Comics), no qual o Morcego tinha um “cinto de utilidades”, e eu achava aque- le cinto sensacional. Com Games, não é muito diferente, pois necessitamos ter a m�o (e saber usar) algumas ferramentas importantes, que nos poupar�o muito tempo na criação de um Game. Dependendo do tipo de �ame que você vai fazer, algumas ferramentas se tornam mais importantes e outras, desnecessárias, mas sempre existe um con- junto básico que você deve ter. Vamos mostrar algumas delas aqui.

ferramentaS gráficaS

Em �ames, as imagens s�o fundamentais e nós já discutimos isso, agora, é o momento de entrarmos mais um pouco a fundo no assunto, focando nas principais ferramentas para criação de imagens.

Imagens

Vamos começar a estudar imagens em seu formato virtual e, depois, vamos ver como ela é renderizada (apresentada) na tela. Toda imagem na memória é um conjunto de pontos. Estes pontos s�o ar- mazenados na memória e, posteriormente, s�o exibidos para o usuário. Cada ponto tem as propriedades: coordenadas e cor. As coordenadas de um ponto indicam onde ele está em nosso “mapa” virtual (Bitmap – n�o confundir com o formato “BMP”). Dependendo do tipo de gráfico que estamos trabalhando, pode ser em um mapa tridimensional ou bidimensional. Como estamos falando de imagens, vamos supor que seja ape- nas bidimensional. Já a cor, normalmente é expressa em quantidade de vermelho (red), verde (green) e azul (blue), podendo também trazer a quantidade de transparência (Alfa). Vamos ver alguns exemplos simples de representações.

18 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

tranSparência e canal alpha

As imagens podem trazer informações sobre trasnparência, conhecidas como “Canal Alpha”. �eralmente, um valor zero no canal alfa de uma imagem significa que ela é totalmente transparente, e um valor 100% significa que é totalmente opaca, mas isto varia de acordo com a ferramenta que utilizamos. Por exemplo, o LibreOffice Draw considera uma imagem com zero no canal alfa como sendo totalmente opaca, e um valor 100% como totalmente transparente.

opaca, e um valor 100% como totalmente transparente. Ilustraç�o 6: Propriedades dos pontos gráficos no

Ilustraç�o 6: Propriedades dos pontos gráficos no LibreOffice Draw

Como podemos ver na figura anterior (LibreOffice Draw), temos dois “pontos” (é claro que s�o imaginários) com suas características. Note como formamos a cor em formato RGBA – Red, �reen, Blue e Alfa (http://www. w3schools.com/cssref/css_colors_legal.asp). No formato R�B – Red, �reen e Blue (http://www.w3schools.com/cssref/css_colors_legal.asp), temos um indicador da quantidade ou intensidade de cada cor, representado por um valor entre 0 e 255 (1 byte), assim, podemos representar as cores:

• Preto: R�B (0,0,0);

• Branco: R�B (255,255,255);

• Cinza: R�B (128,128,128);

Capítulo 3 - Kit de ferramentas para criaç�o de games � 19

• Vermelho: R�B (255,0,0);

• Verde: R�B (0,255,0);

• Azul: R�B (0,0,255);

• Amarelo: R�B (255,255,0);

• Azul ciano (azul bebê): R�B (0,255,255);

• Rosa bebê: R�B (250,200,200);

Se quiser ver as combinações de RGB, pode usar um programa como o “LibreOffice Draw” (http://pt-br.libreoffice.org/), ou o �imp (http://www. gimp.org/) e usar a ferramenta de Cores. Note que o diálogo de cores do LibreOffice Draw também tem uma aba de transparência, que permite ajustar a “opacidade” da cor. Como vimos na ilustraç�o 6 (Propriedades dos pontos gráficos), além do formato RGB, também temos o canal “Alfa”, que regula a “opacidade” ou “transparência” da cor. Este formato é conhecido como “R�BA”. Existe algu- ma confusão quanto ao fato do canal representar o nível de opacidade ou de transparência. Uma boa referência, o W3Schools (http://www.w3schools.com/ cssref/css_colors_legal.asp), diz que o canal alfa representa o nível de opaci- dade da cor, variando entre 0 (totalmente transparente) e 1 (totalmente opa- co). Já alguns softwares e literaturas tratam essa medida como percentual, variando entre 0% (totalmente transparente e 100% (totalmente opaco) (http://

en.wikipedia.org/wiki/R�BA_color_space). Vamos mostrar alguns exemplos de

transparência. Temos que prestar atenção na forma como as ferramentas se referem ao canal “alfa”. O LibreOffice Draw encara como “transparência”, logo, 0% sig- nifica “opaco” e 100% significa “transparente”. Já, para o �imp, uma camada 0% significa totalmente transparente, e 100% significa totalmente opaco.

significa totalmente transparente, e 100% significa totalmente opaco. Ilustraç�o 7: Vários níveis de transparência

Ilustraç�o 7: Vários níveis de transparência

20 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Na imagem anterior, usamos o LibreOffice Draw para desenhar. Os qua- drados, que possuem cor de fundo preta, estão com o canal alfa variando de 0 até 1, ou, na “linguagem” do LibreOffice, variando de 100% até 0% de transparência. Toda imagem é armazenada da mesma maneira. Porém, há alguns detalhes sobre imagens que precisamos conhecer.

Unidades de medida

Quando falamos em imagens, é muito comum ouvirmos “pontos” e “pi- xels”, conceitos que muitas vezes nos confundem. Um “ponto” (point) é uma medida de tipografia e equivale a 1/72 de polegada. Um “pixel” é uma unidade gráfica de um dispositivo. É a menor unidade utilizável de um dispositivo grá- fico, como uma tela de LCD. Temos que deixar claro que estamos estudando gráficos exibidos em telas, e n�o impressos, pois, caso contrário tudo mudaria.

Resolução e densidade Há muita confusão sobre estas duas métricas. O senso comum diz que re- solução é a quantidade de pixels, tanto na horizontal quanto na vertical, que um dispositivo pode exibir. Também serve para determinar o “tamanho” de uma imagem. Por exemplo, uma imagem de 5 Megapixels tem 5 milhões de pixels, o que n�o está relacionado ao tamanho físico. Uma tela WX�A, com 1280 x 800 pixels, tem 1,024 Megapixels.

Já o tamanho que uma imagem ou tela terão depende muito da densidade, que é a quantidade de pixels por polegada (PPI) que a tela pode exibir (ou que a imagem espera ser reproduzida). Isto determina qual tamanho a imagem terá na tela real. Cada dispositivo tem sua densidade específica, por exemplo (fonte: gsmarena.com) :

• Samsung �alaxy S III: 306 PPI;

• Apple iPhone 5: 326 PPI;

• Apple iPad 4: 264 PPI;

• Apple iPad 2: 132 PPI;

• Motorola Xoom 2 Media Edition: 184 PPI.

Profundidade de cor A profundidade de cor (Color depth) é o número de bits necessários para representar cada cor de um pixel. Temos dois grandes sistemas para repre- sentar a cor: indexado e direto. O sistema indexado é utilizado quando temos

Capítulo 3 - Kit de ferramentas para criaç�o de games � 21

baixa profundidade de cor, ou seja, temos poucos bits para representar cada cor. Ent�o, é criada uma “palheta” (tabela) com as cores utilizadas e o código é, na verdade, o índice nesta tabela. Sistemas com 8 ou 12 bits por cor geral- mente utilizam “palhetas” de cor. O sistema direto é quanto não usamos pa- lheta, mas representamos diretamente o valor de cada cor. Podemos ter várias profundidades neste sistema, como 8 bits, 16 bits ou “true color”, que s�o 24 bits de cor (8 para cada cor – R�B). Com este sistema, podemos representar mais de 16 milhões de cores. É claro que o sistema direto requer mais memó- ria (RAM ou arquivo) para representar as imagens, porém, fica mais fiel. Hoje em dia, o sistema indexado é utilizado para armazenamento de ima- gem, de modo a economizar espaço. Entre os tipos de arquivo que usam pa- lheta temos: BMP, �IF e PN�.

Arquivos de imagem

Existem vários padrões para armazenamento de imagem, cada um é me- lhor para determinada aplicação. Temos formatos que usam palheta, formatos que usam Color deph e formatos que podem utilizar os dois sistemas. Também podemos armazenar uma imagem de maneiras diferentes, como: “Raster” e “Vetorial”. Imagens em formato “Raster” são as mais comuns. São mais simples em termos de processamento, pois basicamente armazenam os pontos e suas cores. Só isso. É necessário apenas decodificar (ou descomprimir, caso necessário) o arquivo e acionar os pontos na tela com a cor necessária. Porém, o formato “Raster” tem a desvantagem de ser grande. É claro que podemos comprimir a imagem, perdendo ou não informação, mas, ainda assim, o arquivo é grande. Existem formatos de arquivo “Raster” que comprimem a imagem, com perda ou sem perda de informação. O JPEG, por exemplo, utiliza compressão com perda, que pode ser regulada através da qualidade do arquivo. Arquivos como PNG comprimem sem perda de informações, porém geram arquivos maiores. Já as imagens em formato vetorial não representam a imagem na forma de pixels, mas como vetores. Elas contêm as instruções para desenhar a imagem, permitindo mais suavidade na renderização. Os arquivos em formato vetorial são menores do que os em formato raster, porém, sua renderização exige mais recursos de processamento e pode gerar distorções quando utilizamos dispo- sitivos diferentes.

22 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Os principais formatos de arquivos de imagem s�o:

Formatos “Raster”:

GIF: usa compress�o sem perda e pode representar imagens com palheta de 256 cores. Suporta animaç�o e é mais indicado para ima- gens com grandes áreas de uma só cor, como: gráficos comerciais, desenhos simples etc;

BMP: é o formato nativo do Microsoft Windows. N�o usa compres- s�o e pode representar “true color” (24 bits). Os arquivos BMP s�o grandes, em comparação com outros formatos;

PNG: suporta “true color” com canal alfa (transparência). É mais indicado para imagens com grandes áreas de cor única. Também suporta imagens em sistema direto, sem palheta;

JPEG: comprime imagens de maneira extraordinária, podendo re- duzir absurdamente o tamanho do arquivo. Porém, usa compressão com perda de informação. Uma vez salvo, não é possível restaurar a imagem original. É mais indicado para arquivos de fotografias;

Formatos vetoriais:

SVG: “Scalable Vector �raphics”, um formato padr�o, criado pelo W3C, e utilizado no HTML 5;

CGM (Computer �raphics Metafile), CDR (Corel Draw), WMF (Windows Metafile Format);

Ferramenta para “Sketch”

É muito importante criar “Sketches” ou rascunhos das imagens de seus

�ames. Nada impede que você use papel e lápis para isto, mas um “Ske- tch” digital tem a vantagem de poder ser utilizado diretamente. Eu me lembro

quando criava �ames para Windows e desenhava a imagem em papel para depois passar por um “Scanner”.

O ideal é ter algum dispositivo para digitalização de desenho livre, como

uma mesa digitalizadora, que é um “tablet” (n�o confundir com Tablet Mo- bile), que tem uma caneta especial e permite capturar seu desenho manual. Outra opção é usar algum aplicativo de desenho em um Tablet mobile, como o iPad (ou algum dispositivo Android). Eu costumo usar o “Sketchbook Pro for iPad”, da AutoDesk. É um progra- ma barato e muito fácil de usar e que me permite criar imagens rapidamente, como a da figura a seguir.

Capítulo 3 - Kit de ferramentas para criaç�o de games � 23

3 - Kit de ferramentas para criaç�o de games � 23 Ilustraç�o 8: Rascunho de personagem

Ilustraç�o 8: Rascunho de personagem de �ame

Utilizando uma caneta para iPad, consigo desenhar rapidamente e até colorir a imagem, sem grande sacrifício, pois posso apagar partes e corrigir rapidamente.

Ferramentas para desenho Raster

Na minha opinião, a melhor ferramenta para edição de imagens raster é o PhotoShop, da Adobe. Não há dúvida alguma sobre isso. Porém, ele tem um custo de licença relativamente alto, com relação a outras alternativas. Na mi- nha opini�o, se você tiver condiç�o, compre logo a licença da Adobe Creative Suite 6, que já vem com tudo o que você pode necessitar para criar gráficos. Porém, se você é um “Indie �amer”, provavelmente n�o estará t�o moti- vado assim para investir uma alta soma, especialmente se estiver começando. Mas lembre-se: o investimento se pagará com a qualidade e facilidade de uso dos produtos da Adobe. A opção mais popular de editores “raster” gratuitos é o Gimp (http://www. gimp.org/) - �NU Image Manipulation Program. É um editor poderoso, com interface simples, porém dotado de muitos efeitos interessantes. Há versões para MS Windows, Mac OS X e Linux. Entre outras coisas, o �imp permite:

• Trabalhar com transparências; • Trabalhar com vários formatos diferentes de imagem, inclusive SVG;

24 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Criar imagens com múltiplas camadas, que podem ser superpostas;

Criar animações em GIF;

• Selecionar partes da imagem de várias formas: retangular, elíptica, livre, por cor etc;

Usar várias ferramentas nativas de transformação, cor e pintura;

• Usar vários filtros de efeitos, como: entalhar, esculpir, realçar, pin- tura a óleo, clarões etc;

esculpir, realçar, pin- tura a óleo, clarões etc; Ilustraç�o 9: Exemplo de uso de filtro de

Ilustraç�o 9: Exemplo de uso de filtro de clarões do �imp

Uma opç�o profissional de custo relativamente mais baixo é o Corel Painter

vers�o de avaliaç�o (30 dias) que dá uma boa ideia dos seus recursos, porém só está disponível para MS Windows e Apple Mac OS X. É melhor do que o Gimp em alguns aspectos, como os recursos de pintura digital.

Ferramentas para desenho vetorial

Você pode trabalhar com imagens vetoriais em seu game. Em meu livro an- terior “Mobile �ame Jam” (www.mobilegamejam.com) nós utilizamos imagens vetoriais, sendo desenhadas em um Canvas. Porém, isto pode demandar re- cursos de processador, caso seu game seja muito complexo. Outra maneira de trabalhar com imagens vetoriais é criá-las em um editor de imagens vetoriais e, posteriormente, converter os arquivos em algum formato raster. O Gimp faz isto com perfeição.

Capítulo 3 - Kit de ferramentas para criaç�o de games � 25

Comparação entre renderização raster e vetorial

A renderização raster é muito rápida e o trabalho pode ser dividido com a �PU (�raphics Processing Unit), evitando “lags” no game. Porém, é mais su- jeita às diferenças de densidade e resolução entre os equipamentos, exigindo versões diferentes ou então operações de “resizing”, que podem resultar em arquivos serrilhados (pixelados, uma consequência do processo de reduç�o / ampliaç�o). Já a renderização vetorial é uma operação de desenho completa e, geral- mente, é executada na CPU. Existem alguns artigos interessantes sobre téc- nicas para utilizara a GPU na renderização de desenhos vetoriais, entre eles

este,

html, porém, não é a forma comum de se trabalhar. A vantagem da renderi- zação vetorial é a suavidade do desenho, que pode ter sua escala facilmente aumentada ou diminuída. Além disto, os arquivos vetoriais são menores e não é necessária mais de uma versão de cada imagem. De qualquer forma, eu sempre crio a imagem dos meus games em formato raster (usando o “Sketchbook pro”) e depois converto para formato vetorial. No final, eu converto as imagens vetoriais finalizadas em formato raster, com um arquivo para cada tamanho (resoluç�o / densidade) de dispositivo.

da

NVidia:

http://http.developer.nvidia.com/�PU�ems3/gpugems3_ch25. Ilustraç�o 10: Um ensaio de personagem Na figura

Ilustraç�o 10: Um ensaio de personagem

Na figura anterior, vemos dois ensaios de uma personagem de game que eu estou criando. O da esquerda (raster) foi criado rapidamente no “Sketchbook pro”. Note como ainda mantive as linhas de construção que usei. A imagem da direita é feita em formato vetorial (no aplicativo “iDesign”, para iPad). Eu tenho a tendência de criar personagens em estilo “mangá”, porém, resolvi dar

26 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

uma “ocidentalizada” no rosto (arredondando e diminuindo a inclinaç�o dos olhos). Mas ficou do jeito que eu queria: uma personagem meio rebelde e misteriosa. Eu n�o vou trabalhar com a imagem vetorial, mas vou utilizá-la para criar imagens raster. O desenho vetorial me ajuda a criar imagens mais perfeitas, já que eu não tenho muito talento para desenho manual. A ferramenta que eu gosto de usar para criar desenhos vetoriais é o

iDesignpara iPad, da Touchware (https://itunes.apple.com/us/app/idesign/

id342790226?mt=8). Ele é barato (cerca de US$ 5,00), possui os recursos bá- sicos de ediç�o vetorial, como: curvas de Bèzier, auto fechamento, pintura, rotação, combinação com imagens de fundo e até gradientes. Outra boa ferramenta, na minha opinião é o Fireworks, da Adobe (http:// www.adobe.com/br/products/fireworks.html), uma ferramenta voltada para web designers, que permite trabalhar imagens vetoriais e raster também. Em- bora seu uso seja mais voltado para criaç�o de Web designs (sua integraç�o com CSS é fantástica), também permite gerar temas para JQuery Mobile e tra- balhar imagens vetoriais. Seu preço é um pouco alto, assim como toda a suite da Adobe, mas acredite: o investimento se pagará em produtividade! É claro que n�o podemos sequer falar em gráficos vetoriais sem mencionar o Corel Draw (http://www.corel.com/corel/product/index. jsp?pid=prod4260069), cujo preço da licença é mais competitivo e os recur- sos são fantásticos. Como eu mencionei anteriormente, eu uso o iDesign, da TouchWare (), na versão iPad. Embora tenha menos recursos que os produtos mencionados, tem baixo custo e funciona muito bem no iPad. Sua licença custa cerca de US$ 5,00, e vem com um tutorial muito fácil de entender. Agora, se você quer uma opç�o gratuita, eu recomendaria o Inkscape (www.inkscape.org), que é Open Source e gratuito. Ele possui versões para MS Windows, Apple Mac OSX e Linux. É muito fácil de usar e permite gerar a

maioria das imagens que você necessita. Suas características importantes s�o:

Trabalha com camadas de desenhos;

Gera arquivos raster a partir dos desenhos vetoriais;

Consegue importar vários formatos de imagem, tanto vetoriais como raster;

• Possui vários filtros gráficos sensacionais.

Capítulo 3 - Kit de ferramentas para criaç�o de games � 27

3 - Kit de ferramentas para criaç�o de games � 27 Ilustraç�o 11: O ensaio de

Ilustraç�o 11: O ensaio de personagem no Inkscape

O Inkscape pode ser gratuito, mas é cheio de surpresas. Assim como o �imp, ele também tem filtros sensacionais, que permitem dar um efeito pro- fissional em seus trabalhos. Para dar um exemplo, eu transformei a imagem da minha personagem em um “android”, com efeito “Glowing Metal”.

imagem da minha personagem em um “android”, com efeito “Glowing Metal”. Ilustraç�o 12: Imagem “robotizada”

Ilustraç�o 12: Imagem “robotizada”

28 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

game engineS

Um Game engine é uma ferramenta para facilitar o desenvolvimento de ga- mes. Eles são compostos por editores, bibliotecas e interface de programação, que podemos utilizar para criar nossos próprios games. Existem game engines para várias plataformas, seja 2D ou 3D, com níveis diferentes de facilidade de uso. Adotar um Game engine pode aumentar sua produtividade, permitindo que você se concentre mais no �ame design (incluindo a jogabilidade), ao invés de se preocupar com detalhes de animação, game loop etc.

HTML 5 + Javascript

Existem vários �ame engines para HTML 5 + Javascript. Já que a Adobe

discontinuou o desenvolvimento do Flash player para dispositivos móveis, a galera que fazia jogos em Flash está migrando para HTML 5 e Javascript. Em meu último livro, “Mobile Game Jam”, eu mostrei como desenvolver games móveis usando HTML 5 e Javascript, e mostrei um engine multiplata- forma: o Phone�ap (Cordova). Mas n�o mostrei nenhum �ame engine desta plataforma.

O ImpactJS (impactjs.com) é uma boa opç�o. Ele permite criar games

em HTML 5 + Javascript para Desktops e dispositivos móveis. Vem com um editor de níveis (o Weltmeister), que facilita muito a criaç�o de cenários para diferentes níveis do jogo. Ele vem com ferramentas de depuração e empacota-

dores, que permitem colocar sua aplicação diretamente na AppStore iOS. Seu custo é relativamente barato (US$ 99,00). Existem vários outros game engines para HTML 5 + Javascript, porém o ImpactJS, na minha opini�o, é o mais profissional.

Nativos

Um Game engine nativo é aquele que possui bibliotecas nativas e executa fora do ambiente do Browser. Geralmente, apresentam melhor performance do que os �ame engines baseados em HTML 5 + Javascript.

O Cocos2D for iPhone (http://www.cocos2d-iphone.org/) é um port do

Game engine original “Cocos2D”, para Python. É bastante popular, com vá- rios games famosos no mercado. Ele vem com um ambiente de desenvolvi- mento (CocosBuilder), a biblioteca do �ame engine em si (cocos2D), e um engine de física (Chipmunk). Existem versões para HTML 5 (http://cocos2d-x.

Capítulo 3 - Kit de ferramentas para criaç�o de games � 29

googlecode.com/files/Cocos2d-html5-v2.1.zip) e Android (http://code.google.

com/p/cocos2d-android/). É gratuito.

O AndEngine (http://www.andengine.org/blog/) é um game engine para Android, similar ao Cocos2D. Também é gratuito e open source. Para quem quer um engine mais profissional, tem o Antiryad Gx (http://

www.arkham-development.com/antiryadgx.htm), que permite criar games 2D ou

3D para várias plataformas, entre elas: iOS e Android. Ele possui vários tipos de licenças, desde gratuita até “enterprise” (900 euros). Porém, se você quiser realmente “detonar” com um �ame 3D animal, use o UDK – Unreal Development Kit (www.udk.com) para iOS, Android, PS3, Xbox, Windows, Mac OSX etc. Com o UDK, você pode desenvolver seu game sem custo e, quando estiver pronto para publicar, pagará uma taxa de US$ 99,00 (única). Porém, há mais cobranças se você alcançar US$ 50.000,00 em vendas. Finalmente, temos o Unity (http://unity3d.com/), que é um engine para ga- mes 3D muito interessante. A versão básica é gratuita e permite criar games para MS Windows e Apple Mac OSX, e você pode criar games comerciais com ela. Se quiser criar games para dispositivos móveis, você deve adquirir os “add-ons” específicos, como: Unit iOS (US$ 400,00) e Unit Android (US$ 400,00). Também existem as licenças “pro” para estes ambientes. O Unity é sensacional e vem com um editor fantástico.

O Unity é sensacional e vem com um editor fantástico. Ilustraç�o 13: Jogo que estou criando

Ilustraç�o 13: Jogo que estou criando com o Unity

Se você vai criar um game 3D, é melhor considerar uma ferramenta de de- senho apropriada. Eu recomendo o AutoDesk Maya (http://usa.autodesk.com/ maya/), apropriado para criaç�o de personagens 3D com animaç�o. Agora, se

30 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

preferir um software gratuito, o Blender (http://www.blender.org/) é uma ex- celente opção. E os modelos 3D criados com o Blender podem ser importados em game engines 3D, como o Unity.

Usar a plataforma nativa

Embora um Game Engine possa acelerar o desenvolvimento do seu game, ele também tem algumas desvantagens, entre elas:

Ficar “preso” aos recursos disponíveis no Engine;

Complexidade de aprender a API;

Preço da licença;

• Dependência de suporte (ou comunidade) para Bugs;

Além destas possíveis desvantagens, é necessário considerar que as APIs das plataformas nativas, tanto do Android, como do iOS, permitem criar ga- mes com recursos avançados, como o OpenGL ES, por exemplo. Mesmo que você queira utilizar um �ame Engine, eu considero funda- mental que você saiba o que está acontecendo e, para isto, nada melhor do que criar um game “na mão”, sem engine algum. Depois, se considerar rele- vante para o seu projeto, poderá escolher um Game Engine apropriado, porém saberá avaliar e usar melhor as funcionalidades, pois já sabe os detalhes de programação de games.

ambienteS multiplataforma

Fora os Game engines, existem alguns ambientes multiplataforma para criaç�o de aplicações móveis, alguns deles com recursos para �ames. Para começar, vou vender o meu “peixe”. No nosso portal The Code Bakers (www. thecodebakers.org), criamos um framework de aplicações móveis multiplata- forma, o AAMO (www.aamoframework.org). Ele é baseado em Lua e pode ge- rar aplicações em iOS e Android. Futuramente, haverá versões para Desktop e também um game engine embutido: o AAMO Xtreme. O AAMO é totalmente gratuito e Open Source, mas ainda não contempla os recursos para criação de Games. Outro ambiente multiplataforma interessante é o CoronaSDK (http://www.

coronalabs.com/products/corona-sdk/). Ele também é baseado na linguagem Lua

e possui recursos muito interessantes para criação de games. Ele foi escolhido pela EA (famosa por vários games) para criar seu jogo móvel: World Smack

-for-word-smack/). O corona n�o é gratuito, mas tem licença de baixo custo, só necessária quando você for publicar o game.

Capítulo 3 - Kit de ferramentas para criaç�o de games � 31

prototipadoreS

Um grande recurso, geralmente ignorado pelos desenvolvedores de game,

é a prototipação. Este recurso nos permite capturar, de maneira simples e cla- ra, os requisitos de uma aplicação. Como games possuem requisitos muito subjetivos (jogabilidade é um deles), a prototipaç�o pode ser um excelente instrumento para acelerar o desenvolvimento, evitando retrabalho. Seja utilizando um Game engine ou não, o comprometimento do projeto de um game cresce rápida e exponencialmente. Em poucas semanas, já temos tanto código escrito que criamos um forte comprometimento com ele, deixan- do de ver coisas óbvias. Com um protótipo isto é evitado, pois podemos jogar tudo fora e começar novamente. Felizmente, existem alguns softwares excelentes para prototipação de ga- mes e aplicações em geral. Eu uso dois deles, que considero excelentes. Para começar, gostaria de falar do Codea (http://twolivesleft.com/Codea/), uma ferramenta que roda diretamente (e apenas) no iPad. Com ela, podemos programar diretamente no iPad, sem necessidade de um laptop ou desktop. Infelizmente, só existe vers�o para iPad. Podemos até baixar o Codea Runti- me (https://github.com/TwoLivesLeft/Codea-Runtime) e distribuir a aplica- ç�o na AppStore. A licença do Codea custa US$ 9,99 e acredite: ela se paga rapidamente! Vou mostrar o protótipo de um game que foi feito originalmente no Codea em menos de 4 horas! Eu aprendi a usar o Codea, aprendi a linguagem Lua e criei o Game enquanto estava hospitalizado, aguardando uma cirurgia renal. Quando fui para a sala de cirurgia, o Game estava pronto. É claro que era um protótipo, mas estava funcionando completamente. Eu sou f� do Codea, porém, fiquei completamente atônito e pasmo quando

conheci a oitava maravilha do mundo: O Processing (http://processing.org/)! É aquele tipo de coisa bombástica que nos faz gritar: “Para tudo!” O Processing

é um ambiente de simulação e prototipação, que já vem com tudo em cima

para criar Games. Ele usa uma linguagem “tipo” java, mas também permite exportar seu projeto para HTML 5 + Javascript e até mesmo Android, ou seja:

lava, passa, cozinha e, ainda por cima: é gratuito!

bibliotecaS auxiliareS

Como já discutimos, um Game é um projeto muito complexo, com várias macrofunções diferentes. Certamente, podemos utilizar Game engines para nos auxiliar, porém, ainda existem alguns motivos importantes para estudar- mos as bibliotecas em separado:

32 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

1.

Custo. Se criarmos diretamente o game, não necessitaremos adquirir licenças e, como já discuti, alguns Game engines possuem requisitos de licença meio complexos;

2.

Domínio. Se você souber o que está “por baixo do capô”, vai saber

tirar maior proveito dos componentes para seu Game; Uma ferramenta importante é um engine gráfico que permita utilizar os re- cursos de aceleraç�o de sua placa de vídeo (�PU – �raphics Processing Unit)

e esta ferramenta é a biblioteca OpenGL ES (http://www.khronos.org/opengles/),

que é uma versão da OpenGL (http://www.opengl.org/) para dispositivos mó- veis. A principal vantagem é renderizar imagens mais rapidamente, utilizando multiprocessamento compartilhado entre CPU e �PU, tanto para gráficos 2D como para 3D. Tanto no iOS como no Android, existem recursos para facilitar

o uso do OpenGL ES na criação de games. E, finalmente, temos a biblioteca Box2D (http://box2d.org/), que é um “phy- sics engine”, ou seja, uma biblioteca que fornece funções físicas, como: movi- mento, forças e colisões para nossos games parecerem mais realistas. Para ter uma ideia de quanto a Box2D é importante, o game “Angry birds” a usa como seu “physics engine”.

Capítulo 4 Prototipação do game

Bem, vamos começar realmente o nosso game. Imaginemos uma ideia

simples e vamos tentar criar um protótipo com ela, de modo a avaliar se está boa para virar um Game. Tudo começa com uma ideia. Que tal criarmos um “shooting” game? Afi- nal de contas, “shooting” games são fáceis de criar e, geralmente agradam a todos. Podemos começar com um rascunho (“Sketch”) do game. Eu pensei em um game de escapar de asteroides. Você está em uma nave e tem que manobrar em um campo de asteroides, evitando colidir com eles. Você ganha pontos de acordo com a distância percorrida, em anos-luz. Uma dica: se você começar a complicar, pensando coisas do tipo: “já tem

muita coisa assim, preciso criar algo diferente

seu projeto não vai andar.

Você vai criar um protótipo do jogo, logo, n�o é o momento de pensar nisso. Depois, você pode fazer as otimizações que desejar.

Um rascunho é tudo o que precisamos Eu peguei meu iPad e, usando o “Sketchbook”, criei vários desenhos. Eu fui desenhando o que me vinha à mente, sem me preocupar muito com estética ou funcionalidade. O desenho que mais gostei foi o da próxima figura. A nave se move para cima e para baixo, e os asteroides vêm em sua di- reç�o, pois ela está se movendo para a frente. Existem asteroides “bons” (os brilhantes), que repõem a energia da nave, e os asteroides ruins (opacos), que podem destruir a nave. Caso ela colida com um asteroide ruim, sua energia é drenada, pois ela usa os “escudos” para impedir sua colisão.

34 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS Ilustraç�o 14: Rascunho do jogo Se o seu jogo tiver mais

Ilustraç�o 14: Rascunho do jogo

Se o seu jogo tiver mais telas ou níveis, você pode ir criando rascunhos para cada um deles. O importante é colocar a idea no papel (digital), antes que você se esqueça.

uSando o codea

O Codea é um ambiente de programação sensacional. É simples e prático, permitindo criar rapidamente jogos e simulações gráficas. Ele é uma aplicaç�o para iPad, que está disponível na AppStore por cerca de US$ 10,00.

para iPad, que está disponível na AppStore por cerca de US$ 10,00. Ilustraç�o 15: A tela

Ilustraç�o 15: A tela inicial do Codea

Capítulo 4 - Prototipaç�o do game � 35

Os pontos positivos do Codea s�o:

1.

Tem recursos que facilitam o desenvolvimento rápido de games;

2.

Já vem integrado com o engine de física Box2D;

3.

Usa a linguagem Lua (www.lua.org), que é simples e pouco verbosa;

4.

Vem com Spritepacks (conjuntos de imagens) e outros recursos para

criação de games. Porém, o Codea carece desesperadamente de documentação decente. Não parece um produto comercial e, certamente, não tem o suporte necessário, em caso de problemas. O site da empresa, “Twolivesleft.com”, é muito minima- lista e n�o tem uma documentaç�o formal. Existem vários tutoriais (alguns criados por terceiros) que explicam rapidamente como ele funciona. É claro que podemos criar Games com o Codea e distribuir na AppStore, pois ele tem um “Codea Runtime” (https://github.com/TwoLivesLeft/Codea- -Runtime) que permite fazer isto. Porém, quando se trata de criar um produ- to comercial, eu sou muito conservador, pois, em caso de problemas, o meu cliente vai reclamar comigo e eu, como desenvolvedor do Game, não terei a quem recorrer. É por isso que eu não uso o Codea para desenvolvimento, mas apenas para prototipação. No Codea, podemos criar código-fonte para responder a eventos e para criar classes, que ser�o utilizadas no �ame. A linguagem é a Lua (www.lua. org), criada pela PUC-RJ. Lua é uma linguagem simples, intuitiva e pouco verbosa, cujo aprendizado é extremamente simples. Nós iremos ensinando Lua conforme o protótipo for se desenvolvendo. Aliás, foi assim que eu apren- di a usar Lua. Só para começar, Lua é “canse sensitive” e n�o precisa de ponto e vírgula no final da linha. Os comentários s�o iniciados por “--”.

Um tutorial rápido em Codea

Vamos fazer uma “porcaria” em Codea para você “pegar o jeito”. Comece iniciando um novo projeto, na tela do Codea (Ahn, galera: só funciona no iPad, ok? Se você n�o tem um iPad, leia a prototipaç�o no “Processing”). Escreva um nome qualquer para o projeto, por exemplo: “bola”. Ele vai criar todo o código do projeto, que apenas escreve “Hello world” na saída.

36 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS Ilustraç�o 16: O código gerado pelo Codea Ele gerou um

Ilustraç�o 16: O código gerado pelo Codea

Ele gerou um código-fonte muito simples, como podemos ver na figura. O arquivo “Main” é o arquivo principal de sua aplicação Codea, ele contém algumas funções de “Callback”, ou seja, são invocadas pelo engine do Co- dea em determinadas situações. A primeira função é a “setup”, que é chama- da na inicialização. Neste caso, estamos usando a função “print” para gerar uma mensagem na saída da execução. A outra, é a função “draw”, invocada a cada novo frame gerado. Neste caso, ela apenas limpa a tela, com a função “background (<red>, <green>, <blue>)”, e ajusta a grossura da “caneta” para desenhos em 5 pixels, com a funç�o “strokeWidth(5)”. Se você quiser ver uma referência rápida (algo semelhante a um “Help”), toque no símbolo do Codea na tela principal (É um quadrado verde com dois “C”, um grande e um pequeno).

Como eu rodo o programa? Vamos ver uma referência rápida dos comandos do editor:

• Seta para a esquerda, no canto superior esquerdo: volta ao início;

• Bot�o “+”, no canto superior direito: cria uma nova classe ou um arquivo vazio;

• Tabs na parte superior da tela: alternam entre os arquivos;

• “X” no canto inferior esquerdo: fecha o arquivo;

• Bot�o play, no canto inferior direito: executa o programa;

Capítulo 4 - Prototipaç�o do game � 37

Clique no bot�o “play”, no canto inferior direito da tela do editor e você irá para o ambiente de execução.

tela do editor e você irá para o ambiente de execução. Ilustraç�o 17: O ambiente de

Ilustraç�o 17: O ambiente de execuç�o

O ambiente de execução é bem simples. Ele tem um painel de proprieda-

des, um de output (para saída de comandos “print”), e uma barra de controle. A barra de controle está sempre no canto inferior esquerdo, e tem alguns botões:

• Seta para a esquerda: termina o programa;

• Pausa / Play: para ou continua a execuç�o do programa;

• Seta curva: reseta o programa, executando do início;

• Máquina fotográfica: tira uma foto instantânea do programa;

• Filmadora: filma a execuç�o do programa;

Agora, vamos fazer uma coisa mais legal. Vamos criar um foguete que se move. Altere o arquivo “Main” para acrescentar as linhas em negrito abaixo:

-- bola

-- Use this function to perform your initial setup function setup() print(“Hello World!”)

x = 0

y = HEIGHT / 2

supportedOrientations(PORTRAIT_ANY)

displayMode(FULLSCREEN)

end

38 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

-- This function gets called once every frame function draw() -- This sets a dark background color background(40, 40, 50)

-- This sets the line thickness

strokeWidth(5)

end

-- Do your drawing here

x if x > WIDTH then x = 0

end

sprite(“SpaceCute:Rocketship”,x,y)

= x + 1

O resultado da execução é um foguete que sai do canto esquerdo da tela e vai até o canto direito, recomeçando quando atinge o fim.

vai até o canto direito, recomeçando quando atinge o fim. Ilustraç�o 18: O foguete se move

Ilustraç�o 18: O foguete se move pela tela

Vamos ver o que mudamos. Para começar, criamos duas variáveis, “x” para posição horizontal e “y” para vertical. Note que o valor de “y” é a metade da tela (HEIGHT / 2) fixamos a orientaç�o em “portrait”, pois queremos que

Capítulo 4 - Prototipaç�o do game � 39

o iPad seja segurado “em pé”. Faz sentido, pois os asteroides ficar�o mais

próximos. Depois, retiramos os painéis que aparecem do lado esquerdo com a funç�o “displayMode(FULLSCREEN)”. Sempre que for necessário criar um novo frame, a função “draw” será in- vocada. E, neste momento, ela vai apagar a tela e desenhar um “sprite” (uma imagem) de uma das coleções de sprites que já vem com o Codea. É um pe-

queno foguete com um tripulante. Ele vai desenhar sempre na posição indica- da pelas variáveis “x” e “y”. O Codea usa a orientação cartesiana correta, com

o ponto inicial (0,0) no canto inferior esquerdo. A cada chamada da função “draw”, vamos incrementando o valor de “x”. Quando ele se torna maior que a largura da tela (WIDTH), nós voltamos ao valor zero.

Criando o protótipo do “AsteroidNuts” no Codea

Agora, que já entendemos um pouco do Codea, vamos tentar criar nosso protótipo. Para começar, temos dois tipos de �ame Objects: Nave e Asteroide. A nave é um Player Object, ou seja, controlado pelo usuário, e o asteroide é um NPC. Todo o código-fonte pode ser baixado, logo, não é necessário digitar os comandos. Veja na “Introduç�o”. Tem um arquivo “Asteroid.txt” (“ \Codigo\ AsteroidNuts_Codea\Asteroid.txt”) com a classe toda. N�o importa se temos dois tipos de asteroides (bom e ruim), pois s�o ape- nas variações de propriedades de um asteroide. Nossa classe tem que armazenar os atributos de posição do Asteroide, além do sei tipo (“bom” ou “ruim”). O Codea usa a API Nspire (http://www.inspired- -lua.org/2011/05/5-object-classes/), que facilita a criaç�o de classes. Para criar uma nova classe, abra o editor do projeto e clique no bot�o “+”, que fica no canto superior direito. Escolha “Create new class” e dê o nome “Asteroid”. Você vai notar que já tem alguns comandos:

Asteroid = class()

function Asteroid:init(x) -- you can accept and set parameters here self.x = x

end

40 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

function Asteroid:draw() -- Codea does not automatically call this method

end

function Asteroid:touched(touch) -- Codea does not automatically call this method

end

A linguagem Lua não suporta a criação de classes diretamente, porém como sendo uma linguagem baseada em protótipos, permite modificar o com- portamento e característica de objetos dinamicamente, imitando o conceito de classes. A API Nspire tem a funç�o “class()” que facilita a criaç�o de classes. Neste caso, criamos um objeto “Asteroid” e acrescentamos a ele uma proprie- dade (“x”) e três métodos (“init”, “draw” e “touch”). O método “init” será invocado sempre que quisermos pegar um novo obje- to da nossa classe, por exemplo:

ast1 = Asteroid(10)

Os métodos “draw” e “touched” são dicas que deveríamos implementar estes métodos e invocá-los, quando necessário. O Codea inseriu comentários indicando que estes dois métodos não serão invocados automaticamente. Para começar, vamos trabalhar nosso construtor (o método “init”). Primei- ramente, temos que pensar em como iniciar o Asteroide. Cada Asteroide deve- rá surgir no canto direito da tela, em uma altura variável. Haverá uma faixa de valores no eixo das ordenadas (Y), onde os asteroides poder�o surgir. Eu n�o quero usar a tela toda, pelo menos neste protótipo. Ent�o, faz sentido passar- mos em passar os limites para o construtor da classe, de modo que este possa gerar um asteroide dentro da faixa esperada.

function Asteroid:init(upper,lower) -- you can accept and set parameters here local tipo =math.random(1,100) self.position = vec2(100,50) self.dimension = vec2(50,50) self.position.x = WIDTH - 100 self.position.y = math.random(upper,lower) if tipo > 80 then self.type = 2

else

self.type = 1

end

end

Capítulo 4 - Prototipaç�o do game � 41

O prefixo “Asteroid:” indica que este é um método a ser atribuído aos objetos do tipo “Asteroid”, e o sufixo “init” é o nome do método. O prefi-

xo “self.”, em alguns comandos de atribuição, se refere ao objeto da classe “Asteroid”, logo, “self.type = 2” significa que estamos atribuindo “2” à pro- priedade “type”, do objeto. Se ela não existir, será criada automaticamente. Lua é uma linguagem de tipagem dinâmica, ou seja, cada variável tem seu tipo atribuído dinamicamente (e pode mudar). Passamos dois parâmetros para

o construtor: “upper” – limite superior no eixo das ordenadas, e “lower” – li- mite inferior. Nós criamos três propriedades no construtor:

position”: do tipo “vec2” (do Codea), que retorna um vetor com coordenadas bidimensionais (“x” e “y”). Armazena a posiç�o atual do asteroide;

dimension”: igualmente vec2, armazena a largura e altura da caixa que contém a figura do asteroide;

type”: do tipo “number” (Lua), que armazena o tipo do asteroide, se ele é “bom” (type = 2) ou “ruim” (type = 1). É claro que isto po- deria ser resolvido melhor por hierarquia ou composição, mas é um protótipo, logo, é descartável; Nossa estratégia para decidir se vamos criar um asteroide “bom” ou “ruim”

é apenas aleatória. Poderíamos levar alguns fatores em consideraç�o, como o

nível de energia do jogador e a quantidade de acertos que ele tem, mas, para efeito de protótipo, vamos deixar assim. �eramos um número aleatório entre 1 e 100 (math.random(1,100)) se ele for maior que 80, nós o transformamos em “bom”. Inicialmente, calculamos a posiç�o horizontal (abscissas) em WIDTH – 100. Depois vou explicar o motivo, mas está relacionado com o tamanho do asteroide, que é 50. E calculamos a posiç�o vertical (ordenadas) com um nú- mero aleatório entre o limite inferior e o superior (math.random(upper,lower)). Agora, demos que desenhar um asteroide. O melhor local para fazer isto é no método “draw”. Nós invocaremos o método “draw” sempre que desejar- mos redesenhar um objeto Asteroid específico.

function Asteroid:draw()

-- Codea does not automatically call this method spriteMode(CORNERS)

if

self.type == 2 then sprite(“Tyrian Remastered:Energy Orb 1”, self.position.x, self.position.y, self.position.x+self.dimension.x,

42 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

self.position.y+self.dimension.y)

else

sprite(“Tyrian Remastered:Eggstroid”, self.position.x, self.position.y, self.position.x+self.dimension.x, self.position.y+self.dimension.y)

end

end

A primeira coisa que fizemos foi mudar o modo de desenhar um “sprite”, que é uma imagem carregada na tela. Por default, o Codea sempre considera a posiç�o de um sprite (coordenadas “x” e “y”) como o centro da imagem. Eu prefiro trabalhar com os cantos e especificar o tamanho da imagem, ent�o eu mudei o modo de desenho para CORNERS (spriteMode(CORNERS)), que significa: “x” e “y” ser�o o canto inferior esquerdo da “caixa” que contém o sprite, e os parâmetros “w” e “h” serão, respectivamente, as coordenadas do canto superior direito da mesma. Se for do tipo “2”, é um asteroide “bom”, logo, eu uso um sprite da biblio- teca do Codea, que representa uma esfera brilhante. Eu uso a função “sprite” para desenhar a figura do asteroide na tela, na posiç�o especificada (proprie- dade “position”) e do tamanho especificado (propriedade “dimension”). O pri- meiro parâmetro é o nome da figura, o segundo e o terceiro, as coordenadas do canto inferior esquerdo, e o quarto e o quinto, as coordenadas do canto superior direito. Finalmente, temos dois métodos “finalx” e “finaly”, que retornam as coor- denadas do canto superior direito do asteroide, para facilitar seu uso. Agora, precisamos representar a nave (arquivo “ship.txt”). Vamos criar uma classe da mesma maneira. Em seu método “init”, nós criamos as mesmas propriedades do asteroide, exceto o “type”. Mas colocamos o “lower” e o “upper” como propriedades da nave. Veja o método “init”:

function ship:init() -- you can accept and set parameters here self.position = vec2(100,80) self.dimension = vec2(100,50) self.position.y = (HEIGHT - self.dimension.y)/2 self.upper = self.position.y - 4* self.dimension.y self.lower = self.position.y + 5 * self.dimension.y

end

Capítulo 4 - Prototipaç�o do game � 43

O método “draw” é mais simples:

function ship:draw() -- Codea does not automatically call this spriteMode(CORNERS) sprite(“SpaceCute:Rocketship”,self.position.x, self.position.y, self.position.x+self.dimension.x, self.position.y+self.dimension.y) end

Desenhamos da mesma maneira que o asteroide. E a nave também tem os métodos “finalx” e “finaly”. Na verdade, ambos (Asteroid e ship) poderiam ser derivadas de uma classe ancestral comum “GameObject”, mas eu não quis

complicar as coisas, pois é um protótipo. Um método “callback” importante é

o “touched”, que será invocado quando o usuário tocar na tela.

function ship:touched(touch) -- Codea does not automatically call this method if touch.y >= self.upper and touch.y <= self.lower then self.position.y = touch.y

end

end

Eu simplesmente pego a altura do toque do jogador e posiciono a nave nela. Note que não é necessariamente o toque na nave, mas na tela toda. Eu poderia sofisticar este controle, mas, como é um protótipo, eu preferi deixar tudo mais simples. Na verdade, quem invoca este método é o meu arquivo “Main”, já que ele n�o será invocado automaticamente pelo Codea (veja o comentário no início do método “touched”. Agora, chegou o momento de criar a mecânica do jogo. Eu poderia ter usado os recursos de física cinética do Codea (fornecidos pela biblioteca Bo- x2D), com o objeto “body”. Assim, toda a parte de movimento e colis�o seria automática. Porém, considerei que o protótipo ficaria complexo demais e, na verdade o jogo é muito simples na parte de física. Então, eu mesmo criei a física necessária para movimentar e verificar colisões. No arquivo “Main”, eu crio algumas variáveis globais para controle do jogo, as quais nem vou mencionar diretamente, exceto duas:

“asters = {}”; “nave = nil”;

A variável “asters” é do tipo “table”, que é um array dinâmico e associativo

em Lua. E a variável “nave” é um objeto, inicializado com valor nulo (“nil”).

A table “asters” vai armazenar os asteroides ativos em determinado momento

(aqueles que n�o chegaram ao fim do caminho: o canto esquerdo da tela), e a variável “nave” vai representar o objeto “ship”.

44 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

A função “setup” será invocada automaticamente pelo Codea, e inicializa

as variáveis do game.

function setup() displayMode(FULLSCREEN) upperlimit = (HEIGHT - 50) / 2 - 200 lowerlimit = (HEIGHT - 50) / 2 + 250 nave = ship()

lightyears=0

energy=200

contador=0

fimjogo=0

posdec=1

limrandom=60

inirandom=1

gatilho= 53

interval=12

lastaster=0

maxasters=10

limitdec=60

end

Veja na linha em negrito como eu crio uma instância de uma classe, neste

caso, a nave. O método “init” da classe “ship” será invocado e vai devolver uma instância já inicializada, que pode ser referida através da variável “nave”.

A função “touched” será invocada sempre que o jogador tocar na tela. O

parâmetro que ela recebe (“touch”) contém, entre outras coisas, as coordena- das de onde o jogador tocou na tela. Eu repasso isso para o método “touch” da nave.

A função “draw” é um pouco extensa (e poderia ser refatorada), mas eu

tenho que comentar algumas coisas sobre ela, afinal é o “�ame loop”.

-- This function gets called once every frame function draw() -- This sets a dark background color background(40, 40, 50)

-- This sets the line thickness

strokeWidth(5)

-- Do your drawing here font(“MarkerFelt-Wide”)

Capítulo 4 - Prototipaç�o do game � 45

fill(121, 249, 16, 255)

fontSize(60)

textMode(CORNER) text(“AsteroidNuts”, 10, HEIGHT-65) fill(91, 137, 229, 255) text(string.format(“Light years: %d”,

lightyears),10,HEIGHT-120)

text(string.format(“Energy: %d”,energy), 10, HEIGHT-185)

if fimjogo==1 then fim()

else

contador = contador + 1 if contador >= limitdec then lightyears = lightyears + 10 energy = energy - 1 if energy <= 0 then fim()

end

contador=0

end

newaster()

nave:draw()

if lightyears > 200 then posdec = 2 elseif lightyears > 500 then

interval=6

posdec=10

maxasters=20

elseif lightyears > 1000 then

limrandom=3

gatilho=1

interval=1

posdec=40

maxasters=30

limitdec=40

end for i,v in ipairs(asters) do if v.position.x < 0 then table.remove(asters,i)

46 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

currentasters = currentasters - 1

else

v.position.x = v.position.x - posdec v:draw() if asteroidhit(v) == 1 then

spriteMode(CORNERS) sprite(“Tyrian Remastered:Bullet Fire A”, v.position.x,v.position.y,v:finalx

(),v:finaly())

if v.type == 2 then sound(SOUND_JUMP, 16037) energy = energy + 20 table.remove(asters,i) currentasters = currentasters - 1 else

end

end

end

end

sound(SOUND_EXPLODE, 35632) energy = energy - 2

end if energy <= 0 then fim()

end

end

A funç�o “draw” será chamada automaticamente pelo Codea a cada 60 hertz (1/60 de segundo). Eu tenho que verificar se acrescento mais asteroides e movimentar os que já existem, além de verificar se a nave colidiu com algum deles. Também verifico se os asteroides chegaram ao fim do seu caminho. A primeira coisa é incrementar o contador de “anos-luz” (lightyears) e de- crementar o de energia, afinal, a nave se movimentou. Eu uso uma funç�o “newaster()” para verificar se tenho que criar mais um asteroide (“newas- ter()”), e depois eu redesenho a nave, invocando seu método “draw”.

function newaster() if math.random(1,limrandom) > gatilho then if currentasters < maxasters then

Capítulo 4 - Prototipaç�o do game � 47

if lastaster >= interval then ast = Asteroid(upperlimit,lowerlimit) table.insert(asters,ast) currentasters = currentasters + 1

lastaster=0

else

lastaster = lastaster + 1

end

end

end

end

Esta funç�o “newaster” cria e insere um novo asteroide (“table. insert(aster,ast)”) se as seguintes condições forem atingidas:

• �atilho aleatório maior que 53, para dar um toque de imprevis�o ao jogo;

• O número de asteroides ativos for menor que 10;

O intervalo entre os asteroides for maior ou igual ao intervalo esta- belecido (só pode lançar um novo depois de x asteroides); Na verdade, esta função faz parte da macro função de Estratégia do jogo, e deve ser bem elaborada para aumentar a jogabilidade. Mas, como é um protó- tipo, eu deixei assim mesmo. Depois, eu criei um “loop” para movimentar os asteroides, verificando se houve colis�o de algum deles com a nave:

for i,v in ipairs(asters)

end

A tabela “asters” armazena os asteroides como um vetor dinâmico comum. Para percorrer esta tabela, usamos a forma de comando “for” com a função “ipairs(tabela)”. A cada iteraç�o, o valor de “i” e “v” apontar�o, respectiva- mente, para a posição do asteroide e para o objeto asteroide e eu posso refe- renciá-lo diretamente:

v.position.x = v.position.x - posdec

A primeira coisa que eu faço no loop é verificar se o asteroide chegou ao fim do caminho, removendo-o da tabela:

if v.position.x < 0 then table.remove(asters,i)

48 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

currentasters = currentasters – 1

Não dá problema algum remover um elemento durante a iteração. Se o asteroide ainda n�o chegou ao fim, eu decremento sua posiç�o no eixo das abscissas, e verifico se houve colis�o com a nave (funç�o “asteroidhit”). Se houve, eu verifico se era um asteroide “bom” ou “ruim”, tomando a atitude correta (incrementar ou decrementar energia). Note que eu toco sons diferen- tes, dependendo do tipo de asteroide com o qual a nave colidiu. Para tocar um som, o Codea tem a funç�o:

sound (nome, raiz)

O parâmetro “nome” indica o nome do som a ser tocado, e a “raiz” o modi- fica aleatoriamente. Você deve experimentar com este segundo parâmetro até chegar ao som que deseja mostrar. O jogo chega ao fim sempre que a energia acaba. Durante o jogo, eu exibo algumas mensagens na tela. Eu uso a sequência de comandos abaixo:

• font(nome da fonte): troca a família tipográfica (a fonte) dos caracteres;

• fill(red, green, blue, alfa): estabelece a cor para a escrita;

• fontSize(tamanho da letra): estabelece o tamanho da letra, em pon- tos (1/72 de polegada);

• textMode(origem da posiç�o do texto): especifica o tipo de coor- denadas que vamos fornecer. CENTER significa que é o centro do texto e CORNER que é o canto inferior esquerdo do texto;

• text(“texto a ser escrito”, x, y): os parâmetros “x” e “y” s�o as coor- denadas do texto (veja “textMode”); Com este protótipo, eu posso “brincar” com o game, repensando a jogabi- lidade, as regras etc. A codificaç�o em Lua é de baixa verbosidade e a API do Codea facilita tudo. Eu tenho um jogo quase completo que foi desenvolvido rapidamente.

Capítulo 4 - Prototipaç�o do game � 49

Capítulo 4 - Prototipaç�o do game � 49 Ilustraç�o 19: O jogo funcionando Esta é uma

Ilustraç�o 19: O jogo funcionando

Esta é uma limitaç�o mui-

to séria. Para começar, temos que ter um iPad para desenvolver o protótipo. Não podemos sequer rodar em um iPhone, quanto mais em um dispositivo Android. Neste caso, temos outra ferramenta excelente para prototipaç�o: “Processing”.

Infelizmente, o Codea só existe para iPad

uSando o “proceSSing

Como definir o “Processing”? Bem, para começar, podemos dizer que ele é um ambiente de programaç�o, voltado para criaç�o de gráficos e simulações. Na verdade, ele é mais do que isso, pois é também um game engine e um si- mulador de gráficos 3D. A primeira reaç�o de quem vê os “demos” do processing pela primeira vez

é surpresa. Sim, você também vai ficar de boca aberta, babando, ao ver como

é possível criar simulações fantáticas, com t�o pouco código. Vamos fazer

isso agora. Para começar, baixe o “Processing” do seu site “processing.org”, e descompacte para a pasta que julgar conveniente. Abra a pasta onde instalou o “Processing” e execute o programa (no Windows é “Processing.exe”). Você verá a tela do PDE (Processing Development Editor), cuja simplicidade se assemelha muito ao Codea. Na verdade, o Codea foi inspirado pelo “Processing”.

50 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS Ilustraç�o 20: A tela inicial do PDE e um diálogo com

Ilustraç�o 20: A tela inicial do PDE

e um diálogo com uma lista (“Java

examples”) vai abrir ao lado. Expanda o nó “Demos” e depois o nó “�raphics” e selecione o item “planets” com um duplo clique. A aplicação “Planets” vai abrir no PDE. Você verá um bot�o com símbolo play na barra de botões do PDE, clique nele e observe a janela que vai se abrir.

Selecione o menu “File / Examples

janela que vai se abrir. Selecione o menu “File / Examples ” Ilustraç�o 21: O programa

Ilustraç�o 21: O programa “Planets” em execuç�o

Capítulo 4 - Prototipaç�o do game � 51

Caro leitor, cara leitora, n�o é impressionante? Se analisarmos o código-

-fonte da aplicaç�o (que tem dois arquivos), veremos que s�o poucos coman- dos para gerar um efeito sensacional.

O “Processing” foi criado para ser uma ferramenta de prototipação de apli-

cações gráficas, como games e simulações. Só que, hoje em dia, é utilizado em aplicações profissionais mesmo. Com ele, podemos criar efeitos e animações com gráficos 2D e 3D, utilizando Open�L.

Ele permite desenvolvermos aplicações rapidamente, utilizando uma lin-

guagem parecida com Java®, da Oracle. Na verdade, o “Processing” converte

o

código digitado em Java e o executa utilizando a JVM.

O

“Processing” possui alguns modos de execução, que permitem migrar

o

“executável” da sua aplicaç�o para as plataformas que ele suporta: “Java”,

“Javascript” e “Android”. Para mudar de plataforma, basta clicar no botão “JAVA” que está na barra superior e selecionar a nova plataforma. Porém, antes que você fique muito animado com o “Android”, quero esclarecer que esta característica ainda não funciona corretamente. Eu tentei muito tempo rodar uma aplicação “Processing” no Android e até consegui, porém, foi tão complicado que resolvi não recomendar no livro. Apesar do Emulador Android suportar Open�L ES 2.0 (a partir da API 15), não consegui fazer funcionar. Somente com o dispositivo real conectado e, mesmo assim, tive diversos problemas. Mas estes problemas não invalidam o uso do “Processing” como ferramen- ta de prototipaç�o de games, pois é só rodar no modo Java e tudo vai funcio- nar, inclusive o OpenGL.

Um tutorial rápido no “Processing”

Bem, abra o PDE e verá uma aba com conteúdo em branco. É um “Sketch”, pronto para que você digite os comandos. Digite a linha abaixo:

println(“Hello World”);

Ou então qualquer texto que considere interessante. Agora, clique no botão play na barra superior. Você verá uma pequena janela cinzenta, vazia, e na outra (a do PDE), o seu texto aparecerá na parte inferior (console). Agora, vamos fazer algo mais “bacana” no Processing. Vamos fazer uma nave andar pela tela. Para começar, crie um novo “Sketch” no PDE e salve. O “Processing” salva seus sketches dentro da pasta “Documents/Processing” (no Windows), criando uma pasta com o nome do primeiro sketch que você salvar. Os arquivos possuem a extensão “PDE”.

52 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Agora, dentro da pasta do seu sketch, crie uma pasta chamada “data” e copie o arquivo da nave, que fica em: “ \Codigo\AsteroidNuts_Processing\

Main\data\nave.png”. Para saber como baixar os arquivos-fonte do livro, veja na “Introduç�o”. A imagem deve ficar em uma subpasta “data”, dentro da pas- ta onde você salvou o seu sketch, certo? Agora, vamos digitar alguma coisa no PDE. Uma aplicação “Processing” tem estrutura bastante simples. Podemos digitar comandos imediatos (seme- lhante ao Javascript) ou podemos criar funções. Existem duas funções espe- ciais, que são “callbacks”, ou seja, o “runtime” do “Processing” as invoca quando necessário: “setup()” e “draw()”. A funç�o “setup()” é chamada no início do programa e apenas uma única vez. Nela, colocamos todo o código de inicializaç�o. A funç�o “draw()” é invocada quando é necessário criar um novo frame.

O “Processing” serve para criarmos simulações “framed-based”, ou seja,

aquelas semelhantes a desenhos animados. A cada intervalo de tempo, atua- lizamos o modelo, apagamos e redesenhamos a tela. Este intervalo é o “fra- me rate”, que é medido em FPS – Frames por Segundo. Podemos ajustar o intervalo com a funç�o “frameRate()”. O FPS default é 60, ou seja, a funç�o “draw()” será invocada 60 vezes por segundo. Vamos criar duas variáveis: uma para armazenar a imagem da nave e a ou- tra para armazenar a posição dela. Antes de mais nada, o “Processing” utiliza o sistema cartesiano com a origem no canto superior esquerdo, ao contrário do Codea. Eis o código inicial:

PImage nave; PVector posicao;

A classe PImage serve para armazenar uma imagem (um “sprite”) em

memória e a classe PVector armazena um vetor. Estes s�o dois exemplos de comandos imediatos. Os comandos que ficam dentro de funções só ser�o exe- cutados quando ela for invocada. Agora, vamos criar nossa funç�o “setup()”:

void setup() { size(480, 320); nave = loadImage(“nave.png”); posicao = new PVector(10,80);

}

que estamos fazendo? Definimos o tamanho da nossa janela gráfica em

480 pixels de largura e 320 pixels de comprimento, depois carregamos na

O

Capítulo 4 - Prototipaç�o do game � 53

nossa variável “nave” o “sprite” da nave, que está na subpasta “data”. Final- mente, iniciamos o vetor “posicao” indicando x = 10 e y = 80. Agora, vamos fazer com que a nave “ande” até o final da tela, um pixel a cada 1/60 de segundo. Para isto, temos que apagar a tela, desenhar a nave e incrementar a posição no eixo das abscissas. Se o valor for maior que a largu- ra da tela (“width”) ent�o temos que voltar à posiç�o inicial. Eis o código da funç�o “draw()”:

void draw() { background(40, 40, 50); imageMode(CORNERS); image(nave, posicao.x, posicao.y, posicao.x + 100, posicao.y + 50); posicao.x++; if (posicao.x > width) { posicao.x = 10;

}

}

A funç�o “background(R,�,B)” limpa a tela e a funç�o “image” desenha a imagem, informando as suas coordenadas (canto superior esquerdo e canto inferior direito). Ok, tem uma coisa estranha aí: “imageMode(CORNERS)”. Estou forçan- do a função “image” a carregar a imagem usando as coordenadas do canto superior esquerdo e do canto inferior direito da imagem. Se você viu o tutorial em Codea, é semelhante à funç�o “spriteMode()”.

viu o tutorial em Codea, é semelhante à funç�o “spriteMode()”. Ilustraç�o 22: O resultado do primeiro

Ilustraç�o 22: O resultado do primeiro tutorial

54 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Criando o protótipo do “AsteroidNuts” com o “Processing”

Agora, que já conhecemos um pouco do “Processing”, vamos criar o pro- tótipo do jogo nele. O código-fonte está junto com os exemplos do livro (n�o precisa digitar nada, veja na “Introduç�o”). E é muito semelhante ao que fize- mos para o “Codea”. Todo o código-fonte pode ser baixado, logo, não é necessário digitar os comandos. Veja na “Introduç�o”. Tem um arquivo “Asteroid.pde” (“ \Codi- go\AsteroidNuts_Processing\Main\Asteroid.pde”) com a classe toda. N�o importa se temos dois tipos de asteroides (bom e ruim), pois s�o ape- nas variações de propriedades de um asteroide. Nossa classe tem que armazenar os atributos de posição do Asteroide, além do seu tipo (“bom” ou “ruim”). No “Processing”, criamos classes de forma se- melhante ao Java. Para começar, crie um sketch chamado “Main” e salve (file / new e file / save). Para criar uma nova classe, escolha o menu “File/new”, depois, save com o nome “Asteroid”, na mesma pasta do sketch “Main”.

O “Processing” não tem gabarito algum para criarmos uma classe, então,

escreva o seguinte texto:

class Asteroid {

Asteroid() {

}

void draw() {

}

}

É como uma classe Java comum, só que n�o usamos modificadores de acesso. Note que este “esqueleto” tem um construtor (“Asteroid()”) e tem um método (“draw()”). O construtor é chamado quando criamos uma instância (um novo objeto) da classe, e o método “draw()” só é chamado quando nós o invocamos (n�o confunda com a funç�o “draw()”, do arquivo principal).

O construtor será invocado sempre que quisermos pegar um novo objeto

da nossa classe, por exemplo:

Asteroid ast1 = new Asteroid();

Para começar, vamos trabalhar nosso construtor. Primeiramente, temos que pensar em como iniciar o Asteroide. Cada Asteroide deverá surgir no canto

Capítulo 4 - Prototipaç�o do game � 55

direito da tela, em uma altura variável. Haverá uma faixa de valores no eixo das ordenadas (Y), onde os asteroides poder�o surgir. Eu n�o quero usar a tela toda, pelo menos neste protótipo. Ent�o, faz sentido passarmos em passar os limites para o construtor da classe, de modo que este possa gerar um asteroide dentro da faixa esperada.

class Asteroid { PVector position; PVector dimension; PImage imagem; int type; Asteroid(int upper, int lower) { int tipo = int(random(1,101)); position = new PVector(100,50); dimension = new PVector(50,50); position.x = width - 100; float rPos = random(upper, lower); position.y = int(rPos); if (tipo > 80) { // asteroide bom type = 2; imagem = loadImage(“bom.png”);

}

else { type = 1; imagem = loadImage(“ruim.png”);

}

}

Todo o código colocado entre o “{“ e o “}” da classe, pertence a ela. Pode ser uma propriedade ou um método.

Processing é uma linguagem de tipagem forte, ou seja, cada variável tem seu tipo atribuído estaticamente (e n�o pode mudar). Passamos dois parâme- tros para o construtor: “upper” – limite superior no eixo das ordenadas, e “lower” – limite inferior. Nós criamos três propriedades:

position”: do tipo “PVector”, que armazena um vetor com coor- denadas bidimensionais (“x” e “y”). Armazena a posiç�o atual do asteroide;

dimension”: igualmente “PVector”, armazena a largura e altura da caixa que contém a figura do asteroide;

56 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

type”: do tipo “int” (Java), que armazena o tipo do asteroide, se ele é “bom” (type = 2) ou “ruim” (type = 1). É claro que isto poderia ser resolvido melhor por hierarquia ou composiç�o, mas é um protótipo, logo, é descartável; imagem”: do tipo “PImage”, que armazena uma imagem (um “Sprite”). Nossa estratégia para decidir se vamos criar um asteroide “bom” ou “ruim”

é apenas aleatória. Poderíamos levar alguns fatores em consideraç�o, como o

nível de energia do jogador e a quantidade de acertos que ele tem, mas, para

efeito de protótipo, vamos deixar assim. �eramos um número aleatório entre 1 e 101 (“int(random(1,101))” se ele for maior que 80, nós o transformamos

em “bom”. Inicialmente, calculamos a posiç�o horizontal (abiscissas) em “width – 100” (a variável global “width” retorna a largura da tela, e “height”, a altura).

E calculamos a posiç�o vertical (ordenadas) com um número aleatório entre o

limite inferior e o superior (“random(upper, lower)”). Agora, demos que desenhar um asteroide. O melhor local para fazer isto é no método “draw”. Nós invocaremos o método “draw” sempre que desejar- mos redesenhar um objeto Asteroid específico.

void draw() { imageMode(CORNERS); image(imagem, position.x, position.y, position.x + dimension.x, position.y + dimension.y);

}

A primeira coisa que fizemos foi mudar o modo de desenhar um “sprite”, que é uma imagem carregada na tela. Eu prefiro trabalhar com as coordenadas dos cantos (superior esquerdo e inferior direito), ent�o eu mudei o modo de desenho para CORNERS (“imageMode(CORNERS)”), que significa: “x” e “y” serão o canto superior esquerdo da “caixa” que contém o sprite e os pa- râmetros “w” e “h” serão, respectivamente, as coordenadas do canto inferior direito da mesma. Lembre-se: O “Processing” possui um sistema de coordenadas diferente do “Codea”! Se for do tipo “2”, é um asteroide “bom”, logo, eu uso uma imagem do “OpenClippart.org”, que representa uma esfera brilhante (com uma estrela dentro). Eu uso a funç�o “image” para desenhar a figura do asteroide na tela, na posiç�o especificada (propriedade “position”) e do tamanho especificado

Capítulo 4 - Prototipaç�o do game � 57

(propriedade “dimension”). O primeiro parâmetro é o nome da figura, o se- gundo e o terceiro, as coordenadas do canto superior esquerdo, e o quarto e o quinto, as coordenadas do canto inferior direito. Finalmente, temos dois métodos “finalx” e “finaly”, que retornam as coor- denadas do canto superior direito do asteroide, para facilitar seu uso. Agora, precisamos representar a nave (arquivo “ship.pde”). Vamos criar uma classe da mesma maneira. Em seu construtor, nós criamos as mesmas propriedades do asteroide, exceto o “type”. Mas colocamos o “lower” e o “upper” como propriedades da nave. Veja o método “init”:

class ship {

PVector position; PVector dimension; PImage imagem; int upper; int lower;

ship() { position = new PVector(10,80); dimension = new PVector(100,50); position.y = (height - dimension.y)/2; upper = int(position.y - 4 * dimension.y); lower = int(position.y + 5 * dimension.y); imagem = loadImage(“nave.png”);

}

O método “draw” é igualmente simples:

void draw() { imageMode(CORNERS); image(imagem, position.x, position.y, position.x + dimension.x, position.y + dimension.y);

}

Desenhamos da mesma maneira que o asteroide. E a nave também tem os métodos “finalx” e “finaly”. Na verdade, ambos (Asteroid e ship) poderiam ser derivadas de uma classe ancestral comum “GameObject”, mas eu não quis complicar as coisas, pois é um protótipo. Um método “callback” importante é o “clicked”, que será invocado quando o usuário clicar com o mouse.

void clicked(int x, int y) {

if (y >= upper

&&

y <= lower) {

58 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

position.y = y;

}

}

Eu simplesmente pego a altura do clique do jogador e posiciono a nave nela. Note que não é necessariamente o clique na nave, mas na tela toda. Eu poderia sofisticar este controle, mas, como é um protótipo, eu preferi deixar tudo mais simples. Na verdade, quem invoca este método é o meu arquivo “Main”, já que ele não será invocado automaticamente pelo “Processing”. Agora, chegou o momento de criar a mecânica do jogo. Eu poderia ter usado os recursos de física cinética do Codea (fornecidos pela biblioteca Bo- x2D), com o objeto “body”. Assim, toda a parte de movimento e colis�o seria automática. Porém, considerei que o protótipo ficaria complexo demais e, na verdade o jogo é muito simples na parte de física. Então, eu mesmo criei a física necessária para movimentar e verificar colisões. No arquivo “Main”, eu crio algumas variáveis globais para controle do jogo, as quais nem vou mencionar diretamente, exceto quatro:

“ship nave;”;

“ArrayList asters;”;

PFont letraTitulo;”;

PImage explosao;”;

A variável “asters” é do tipo “ArrayList”, que é um array dinâmico em Java. E a variável “nave” é um objeto, que representará um objeto real da classe “ship”. A variável “letraTitulo” representa uma “fonte” ou definiç�o tipográfica de caractere. A variável “explosao” representa a imagem de uma explosão, que vai aparecer quando a nave tocar em um asteroide “ruim”. A tabela “asters” vai armazenar os asteroides ativos em determinado momento (aqueles que n�o chegaram ao fim do caminho: o canto esquerdo da tela). A função “setup” será invocada automaticamente pelo “Processing”, e ini- cializa as variáveis do game.

void setup() { size(320, 480); upperlimit = (height) / 2 - 100; lowerlimit = (height) / 2 + 100; nave = new ship ();

// Init vars

lightyears=0;

Capítulo 4 - Prototipaç�o do game � 59

energy=200;

contador=0;

fimjogo=0;

posdec=1;

limrandom=60;

inirandom=1;

gatilho= 53;

interval=12;

lastaster=0;

maxasters=10;

limitdec=60;

asters = new ArrayList(); explosao = loadImage(“explosao.png”); letraTitulo = loadFont(“Andy-Bold-14.vlw”);

}

Aqui valem algumas notas importantes sobre arquivos de recursos (ima- gens e fontes). Todos os recursos em uma aplicaç�o “Processing” devem ficar dentro da subpasta “data”, dentro da pasta onde est�o os “sketches” que você

vai rodar. Logo, todas as imagens devem estar dentro dela. Esta estrutura já está desta forma no zip do código-fonte do livro. Outra coisa importante é a fonte. Se você for escrever alguma coisa, deve criar um arquivo de fonte no formato “vlw”, que o “Processing” usa. Existe um arquivo “vlw” para cada combinação de tipo e tamanho de letra. Para criar um arquivo “vlw”:

1.

Abra o menu “tools / create font”;

2.

Selecione o tipo de letra e o tamanho;

3.

Clique em “Ok”;

4.

Copie o arquivo “vlw” gerado (fica na pasta do próprio “Sketch”

para a subpasta “data”). A função “mouseClicked” será invocada sempre que o jogador clicar na tela. Quando isto acontece, eu repasso as coordenadas do clique para o método “clicked” da nave. A função “draw” é um pouco extensa (e poderia ser refatorada), mas eu tenho que comentar algumas coisas sobre ela, afinal é o “�ame loop”.

void draw() { background(40, 40, 50);

strokeWeight(5);

textFont(letraTitulo); fill(121, 249, 16, 255);

60 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

textSize(24);

text(“AsteroidNuts”, 10, 25); fill(91, 137, 229, 255); text(“Light years: “ + lightyears,10,50); text(“Energy: “ + energy,10, 75);

if (fimjogo == 1) { fim();

}

else { contador = contador + 1; if (contador >= limitdec) {

}

lightyears = lightyears + 10; energy = energy - 1;

if (energy <= 0) fim();

{

}

contador=0;

newaster();

nave.draw();

if (lightyears > 200) { posdec = 2;

}

else if (lightyears > 500) { interval = 6; posdec = 10; maxasters = 20;

}

else if (lightyears > 1000) {

limrandom = 3; gatilho = 1; interval = 1; posdec = 40; maxasters = 30; limitdec = 40;

}

for (int i = asters.size()-1; i > 0; i--) { Asteroid v = (Asteroid) asters.get(i);

Capítulo 4 - Prototipaç�o do game � 61

if (v.position.x < 0) { asters.remove(i); currentasters = currentasters - 1;

}

else {

v.position.x = v.position.x - posdec; v.draw(); if (asteroidhit(v) == 1) { imageMode(CORNERS); image(explosao, v.position.x,v.position.y,v.

finalx(),v.finaly());

if (v.type == 2) { energy = energy + 20; asters.remove(i); currentasters = currentasters

- 1; } else { energy = energy - 2; } if (energy <= 0)
- 1;
}
else {
energy = energy - 2;
}
if (energy <= 0) {
fim();
}
}
}
}
}
}

A função “draw” será chamada automaticamente pelo “Processing” a cada 60 hertz (1/60 de segundo). Eu tenho que verificar se acrescento mais aste- roides e movimentar os que já existem, além de verificar se a nave colidiu com algum deles. Também verifico se os asteroides chegaram ao fim do seu caminho. A primeira coisa é incrementar o contador de “anos-luz” (lightyears) e de- crementar o de energia, afinal, a nave se movimentou. Eu uso uma funç�o “newaster()” para verificar se tenho que criar mais um asteroide (“newas- ter()”), e depois eu redesenho a nave, invocando seu método “draw”.

void newaster() { if (random(1,limrandom) > gatilho) {

62 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

if (currentasters < maxasters) { if (lastaster >= interval) { ast = new Asteroid(upperlimit,lowerli

mit);

asters.add(ast); currentasters = currentasters + 1;

lastaster=0;

}

else { lastaster = lastaster + 1;

}

}

}

}

Esta funç�o “newaster” cria e insere um novo asteroide (“table. insert(aster,ast)”) se as seguintes condições forem atingidas:

• �atilho aleatório maior que 53, para dar um toque de imprevis�o ao jogo;

• O número de asteroides ativos for menor que 10;

O intervalo entre os asteroides for maior ou igual ao intervalo esta- belecido (só pode lançar um novo depois de x asteroides); Na verdade, esta função faz parte da macro função de Estratégia do jogo, e deve ser bem elaborada para aumentar a jogabilidade. Mas, como é um protó- tipo, eu deixei assim mesmo. Depois, eu criei um “loop” para movimentar os asteroides, verificando se houve colis�o de algum deles com a nave:

for (int i = asters.size()-1; i > 0; i--) {

}

A tabela “asters” armazena os asteroides como um vetor dinâmico comum. A cada iteração, o valor de “i” apontará, para a posição do asteroide atual. A primeira coisa que eu faço no loop é verificar se o asteroide chegou ao fim do caminho, removendo-o da tabela:

if (v.position.x < 0) { asters.remove(i); currentasters = currentasters - 1;

}

Capítulo 4 - Prototipaç�o do game � 63

Não dá problema algum remover um elemento durante a iteração.

Se o asteroide ainda n�o chegou ao fim, eu decremento sua posiç�o no eixo das abscissas e verifico se houve colis�o com a nave (funç�o “asteroidhit”). Se houve, eu verifico se era um asteroide “bom” ou “ruim”, tomando a atitude correta (incrementar ou decrementar energia). O jogo chega ao fim sempre que a energia acaba. Durante o jogo, eu exibo algumas mensagens na tela. Eu uso a sequência de comandos abaixo:

• textFont(<fonte>): estabeleço qual é o objeto PFont a ser utilizado para a próxima escrita;

• fill(R, �, B, A): determino a cor do texto;

• textSize(<tamanho>): limito o tamanho do texto (em pontos);

• text(“<texto>”, x, y): escrevo o texto nas coordenadas indicadas;

Com este protótipo, eu posso “brincar” com o game, repensando a jogabi- lidade, as regras etc. A codificaç�o é de baixa verbosidade, e a API do “Pro- cessing” facilita tudo. Eu tenho um jogo quase completo que foi desenvolvido rapidamente.

um jogo quase completo que foi desenvolvido rapidamente. Ilustraç�o 23: O protótipo do “Asteroid Nuts” no

Ilustraç�o 23: O protótipo do “Asteroid Nuts” no Processing

64 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

crie várioS protótipoS

Eu sugiro que você crie vários protótipos e evite apagar os anteriores. Mantenha várias versões, testando novas maneiras de jogar e novos cenários e elementos. Depois, você pode fazer um “corte”, eliminando as ideias que n�o gostou. A facilidade de criar protótipos torna o projeto do game mais objetivo, pois, uma vez que você tenha testado todos eles, poderá escolher as ideias mais interessantes e se concentrar apenas nelas.

Capítulo 5 Física de games

Física é uma macro função muito importante em games de ação, pois serve para aumentar a jogabilidade, aumentando a percepção de realidade e o en- volvimento do jogador. A física de um game deve lidar com problemas como:

força, aceleração, movimento e colisão, tentando fazer com que os Game Ob- jects se comportem aproximadamente como os modelos reais.

Os exemplos são incrementais Eu vou mostrar vários exemplos neste capítulo e todo o código-fonte está disponível para você, logo, n�o necessitará digitar coisa alguma. Porém, eu quero fazer uma observaç�o sobre os exemplos: o objetivo é mostrar como aplicar cálculos de física aos games. Neste momento, eu não estou preocupado com a precisão do Game Loop ou com quaisquer outros detalhes. Logo, antes de usar os exemplos como base para o seu game, tenha em mente que existem mais aspectos a serem analisados, então, eu sugiro que você leia até o final ANTES de sair criando seu jogo definitivo.

Rode todos os exemplos Este capítulo é muito grande, mas é extremamente importante para que você conheça bem a física de jogos. Todos os exemplos est�o junto com o código-fonte que acompanha o livro. Eu recomendo que você baixe todos e rode em seu computador.

66 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

oS primórdioS

AndroidAndroidAndroid eee iOSiOSiOS o S primórdioS Ilustraç�o 24: O jogo “�orilla.bas”, que vinha com

Ilustraç�o 24: O jogo “�orilla.bas”, que vinha com o Microsoft QBasic

Um dos exemplos mais antigos de física que eu me lembro é o do jogo “Gorilla.bas”, que vinha com o Microsoft QBasic. Na verdade, eu já o conhe- cia de um produto mais antigo: o Microsoft QuickBasic, que eu utilizava para desenvolver sistemas na década de 80. A física era bem simples e basicamente lidava com o movimento de um projétil (uma banana), levando em conta a força da gravidade. Se pararmos para pensar, não é muito diferente do que o “Angry Birds” (Rovio - www.rovio.com/index.php?page=angry-birds) original fazia: atirar um pássaro, que viaja em trajetória influenciada pela gravidade. Quanto mais força, mais larga a parábola. E você tinha que acertar ou derrubar os porcos. A mecânica é parecida com a do “Gorilla.bas”, talvez um pouco mais precisa.

conceitoS báSicoS

Nem todo game é tão exigente na física quanto os jogos de ação. Existem games que sequer possuem qualquer tipo de física. É o caso do game que es- tou desenvolvendo para Facebook: o RandoSystem, que é um quebra-cabeças baseado em labirinto.

Capítulo 5 - Física de games � 67

Capítulo 5 - Física de games � 67 Ilustraç�o 25: Um jogo que dispensa a física

Ilustraç�o 25: Um jogo que dispensa a física

Porém, se você quer criar um jogo onde os �ame Objects se movam e colidam, deve prestar atenção à física, de modo a aumentar o envolvimento do jogador. O jogo que eu descrevi no meu livro anterior, “Mobile �ame Jam” (www. mobilegamejam.com) era muito mais dependente de física.

mobilegamejam.com ) era muito mais dependente de física. Ilustraç�o 26: O jogo “BueiroBall”, do livro

Ilustraç�o 26: O jogo “BueiroBall”, do livro “Mobile �ame Jam”

No “BueiroBall” (eu sei, o nome poderia ser melhor) você tem que “enca- çapar” as bolas em determinada ordem, sen�o perde pontos (neste caso, as pre- tas só podem entrar depois das coloridas) e você joga usando o acelerômetro,

68 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

ou seja, inclinando o seu dispositivo. Neste jogo, a física é fundamental, pois temos que acrescentar realismo ao movimento e às colisões. As bolas devem se movimentar de acordo com a inclinação, acelerando ou diminuindo confor- me a posição do dispositivo. E também tive que tratar a colisão, ou seja, o que acontece quando duas ou mais bolas colidem. Qual é o vetor de movimento resultante etc.

Aceleração e movimento

A parte que estuda isso na física é a cinemática. Eu não vou desperdiçar seu tempo explicando conceitos de física, mas, se quiser saber, recomendo a série “física de video game”, do portal “The Code Bakers” (http://www.theco-

O grande problema de jogos de movimento dinâmico é calcular onde você

deve desenhar a figura no próximo frame. Se você utiliza uma física simples,

como a que vimos no protótipo do “AsteroidNuts” (capítulo anterior), isto não é problema. Basta decrementar ou incrementar o valor da coordenada correspondente à direção do movimento e pronto. No caso do “AsteroidNuts”, estamos no espaço, e consideramos a aceleração constante. Mas poderíamos criar efeitos interessantes, como o puxão da gravidade, por exemplo. Para calcular a posição de um objeto com relação a um plano de coordena-

das cartesianas, podemos usar o método de Verlet (http://pt.wikipedia.org/wiki/

html). A fórmula básica é:

ou

x(t + Δt) = (2 – f)x(t) – (1 – f)x(t - Δt) + a(t)( Δt) 2

Podemos calcular a posição em cada eixo, informando as forças que foram aplicadas a eles (impulso e gravidade, por exemplo).

É isso o que fiz no game “Ataque das formigas marcianas”, publicado

no “The Code Bakers”

ogame-3-finalmente-um.html). O código-fonte do �ame está no �oogle Code

2.0 (Open Source).

Capítulo 5 - Física de games � 69

Capítulo 5 - Física de games � 69 Ilustraç�o 27: O jogo “Ataque das formigas marcianas

Ilustraç�o 27: O jogo “Ataque das formigas marcianas

No jogo das “formigas”, o código que controla o movimento e aceleraç�o é calculado na classe que representa a “Bola”:

/*

* Esta classe representa uma bola

* Podemos criar mais de uma

*/ class Bola { double altura; double alturaAnterior; double alturaLimite; double limiteSuperior; double aceleracao; double velocidade; double dt; double forcaGrav; double massa; boolean parada = true; boolean descendo = true; double e = 0.50; // Coeficiente de restitui ‹o (pode

variar)

float x;

float y;

70 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Bola() {

}

reset();

void reset() { limiteSuperior altura

= PISO; = limiteSuperior;

alturaAnterior

= altura;

alturaLimite

= 0;

aceleracao

= 0.0d;

velocidade

= 0.0d;

dt

= 01.d;

forcaGrav

= -9.8d;

massa

= 1.0d;

descendo

= true;

}

void atualizar() { altura = altura + velocidade * dt + (aceleracao * Math.pow(dt, 2)) / 2.0d; double vel2 = velocidade + (aceleracao * dt) /2.0d; double aceleracao = forcaGrav / massa ; velocidade = vel2 + (aceleracao * dt) / 2.0d;

}

}

E, quando chegamos ao “chão”, nossa velocidade vai inverter, com uma aceleração proporcional à deformação causada pela colisão.

Colisão

Em física, temos dois tipos básicos de colis�o: elástica e inelástica (http://

artigo sobre isso no portal “The Code Bakers” (http://www.thecodebakers.

org/2011/06/fisica-de-videogame-2-colisoes.html). O tipo de material dos dois ob-

jetos pode determinar o tipo de colis�o que teremos:

Colisão elástica: ambos os corpos se deformam e se expandem após o choque, resultando na mesma energia cinética;

Colisão parcialmente elástica: os corpos perdem parte da energia cinética, que é transferida para trabalho (barulho, calor, deformaç�o permantente - plástica);

Capítulo 5 - Física de games � 71

Colisão inelástica: toda a energia cinética é transferida para trabalho;

O que significa isso? Bem, quando dois �ame Objects colidem, dependen-

do do tipo de material, parte da energia cinética é transferida e um deles (ou ambos) podem perder velocidade. É o que acontece no jogo “Ataque das for- migas marcianas” quando a bola atinge o solo, “quicando” e subindo até uma altura menor que a inicial. Ela vai “quicar” algumas vezes até parar. Em outros tipos de game (como o “BueiroBall”) nós n�o precisamos pen- sar nisso, pois é irrelevante. Mas, em games onde o “quique” e a deformação provocados pela colisão são importantes, é necessário calcular o que acontece depois da colisão. Cada tipo de material tem um CR - “Coeficiente de retribuiç�o” (http:// www.thecodebakers.org/2011/06/fisica-de-videogame-2-colisoes.html), que influencia no cálculo do movimento de “quique” e da deformaç�o causados pela colisão. No caso do “Ataque das Formigas”, eu estou desprezando a de- formação e utilizando o CR apenas para calcular a força que será aplicada à bola para subir novamente.

if (bola.altura <= 0) { // A bola bateu no ch‹ão bola.altura = 0; bola.x = MEIO; bola.y = (float)(PISO - bola.altura); canvas.drawBitmap(bitmap, bola.x, bola.y, null); if (!bola.parada) { verificaColisao(canvas);

}

double novaAltura = Math.pow(bola.e, 2) * bola.alturaAnterior; bola.velocidade = Math.sqrt(2 * (-bola.forcaGrav) * novaAltura); bola.alturaAnterior = novaAltura;

O CR que estou usando (0,50) provoca um alto valor de restituiç�o, per-

mitindo que a bola “quique” alto. Se usarmos algo como bola murcha caindo em argila, teremos uma baixíssima restituição, já que os dois materiais usarão a maior parte da energia cinética no trabalho de deformação, absorvendo o impacto.

72 �� ManualManualManual dododo IndieIndieIndie ���ameameame DeveloperDeveloperDeveloper --- VersVersVers���ooo AndroidAndroidAndroid eee iOSiOSiOS

Há outro fator a ser considerado: a direç�o dos objetos após a colis�o. No caso do “BueiroBall”, estou simplesmente inverto a velocidade nos dois eixos, que não é exatamente o que aconteceria na vida real, mas dá um efeito aceitável para o jogador. No caso do “Ataque das formigas marcianas”, estou

desprezando isso e fazendo a bola simplesmente subir na mesma direção. Po- rém, em uma colis�o mais realista, a trajetória dos objetos seria afetada por:

• Ângulo da trajetória dos objetos;

Massa dos objetos;

Velocidade dos objetos;

CR dos objetos;

Ou seja, há muitas variáveis a s