universidade regional de blumenaucampeche.inf.furb.br/tccs/2011-ii/tcc2011-2-19-vf... ·...

76
UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE CIÊNCIA DA COMPUTAÇÃO BACHARELADO IMPLEMENTAÇÃO DE UM MOTOR DE JOGOS DE CARTA PARA A PLATAFORMA ANDROID MASSAMI WELINGTON KAMIGASHIMA BLUMENAU 2011 2011/2-19

Upload: others

Post on 16-Apr-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

UNIVERSIDADE REGIONAL DE BLUMENAU

CENTRO DE CIÊNCIAS EXATAS E NATURAIS

CURSO DE CIÊNCIA DA COMPUTAÇÃO – BACHARELADO

IMPLEMENTAÇÃO DE UM MOTOR DE JOGOS DE CARTA

PARA A PLATAFORMA ANDROID

MASSAMI WELINGTON KAMIGASHIMA

BLUMENAU

2011

2011/2-19

Page 2: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

MASSAMI WELINGTON KAMIGASHIMA

IMPLEMENTAÇÃO DE UM MOTOR DE JOGOS DE CARTA

PARA A PLATAFORMA ANDROID

Trabalho de Conclusão de Curso submetido à

Universidade Regional de Blumenau para a

obtenção dos créditos na disciplina Trabalho

de Conclusão de Curso II do curso de Ciência

da Computação — Bacharelado.

Prof. Paulo César Rodacki Gomes, Dr. - Orientador

BLUMENAU

2011

2011/2-19

Page 3: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

IMPLEMENTAÇÃO DE UM MOTOR DE JOGOS DE CARTA

PARA A PLATAFORMA ANDROID

Por

MASSAMI WELINGTON KAMIGASHIMA

Trabalho aprovado para obtenção dos créditos

na disciplina de Trabalho de Conclusão de

Curso II, pela banca examinadora formada

por:

______________________________________________________

Presidente: Prof. Paulo César Rodacki Gomes, Dr. – Orientador, FURB

______________________________________________________

Membro: Prof. Dalton Solano dos Reis, M. – FURB

______________________________________________________

Membro: Prof. Mauro Marcelo Mattos, Dr. – FURB

Blumenau, 12 de dezembro de 2011

Page 4: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

Dedico este trabalho a minha família, amigos e

principalmente a todos que me apoiaram direta

e indiretamente no desenvolvimento deste

trabalho.

Page 5: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

AGRADECIMENTOS

A Deus, pela vida que possuo.

À minha família, que está sempre ao meu lado em todos os momentos.

A todos os meus amigos, que me apoiaram e deram forças para continuar.

Ao meu orientador, Paulo César Rodacki Gomes, por ter me dado a idéia e todo apoio

para que este trabalho fosse possível.

Page 6: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

RESUMO

Este trabalho apresenta a elaboração de um motor de jogos para a plataforma Android em

forma de uma biblioteca e sua implementação um protótipo de jogo de pôquer. São

apresentados conceitos básicos sobre os principais recursos disponíveis para o

desenvolvimento de uma aplicação nesta plataforma. O motor disponibiliza ao desenvolvedor

a estrutura básica de um jogo de cartas, tais como a gerência das cartas do baralho,

posicionamento dos elementos na tela e a interação das cartas com o usuário.

Palavras-chave: Android. Jogos. Motor de jogos.

Page 7: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

ABSTRACT

This work describes the development of a game engine for Android platform in the form of a

library and the implementation of a poker game prototype. Basic concepts are also presented

on the main resources available to develop an application on this platform. The engine

provides the designer with the basic structure of a card game, such as management of the

cards in the deck, positioning of elements on the screen and interact of the user with the cards.

Key-words: Android. Games. Game engine.

Page 8: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

LISTA DE ILUSTRAÇÕES

Figura 1- Imagens de uma partida de pôquer (esq.) e uma partida de paciência (dir.) ............ 17

Figura 2 - Arquitetura da plataforma Android ...................................................................... 18

Figura 3 - Representação da pilha de atividades ................................................................... 21

Figura 4 - LinearLayout ....................................................................................................... 23

Figura 5 - TableLayout......................................................................................................... 24

Figura 6 – RelativeLayout .................................................................................................... 25

Figura 7 – Exemplo de aplicação do MJ3I ............................................................................ 35

Figura 8 - Interface do BGE ................................................................................................. 37

Figura 9 - Interface do Havok Physics .................................................................................. 38

Figura 10 – Diagrama de casos de uso .................................................................................. 40

Figura 11 – Diagrama de classes do motor de jogos ............................................................. 41

Figura 12 – Pacote engine.Model ................................................................................... 42

Figura 13 – Pacote engine.View ..................................................................................... 43

Figura 14 - Pacote engine.View (cont.)........................................................................... 43

Figura 15 – Tela principal .................................................................................................... 44

Figura 16 – Tela de seleção de jogo...................................................................................... 44

Figura 17 – Tela de seleção de jogadores ............................................................................. 44

Figura 18 – Menu de exibição .............................................................................................. 45

Figura 19 – engine.Control ......................................................................................... 45

Figura 20 – Pacote engine.GameMode ............................................................................ 47

Figura 21 – Diagrama de sequência do caso de uso UC01 .................................................... 48

Figura 22 – Tela de opções................................................................................................... 62

Figura 23 – Listagem de cores .............................................................................................. 62

Figura 24 – Tela de jogo ...................................................................................................... 63

Figura 25 – Opções de apostas ............................................................................................. 63

Figura 26 – Regulamentos do jogo ....................................................................................... 64

Figura 27 – Pontuação do jogo ............................................................................................. 64

Page 9: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

LISTA DE QUADROS

Quadro 1 - Estrutura XML de um TableLayout .................................................................... 24

Quadro 2 – Estrutura XML de um RelativeLayout ............................................................... 25

Quadro 3 - Exemplo de inserção de recursos ........................................................................ 27

Quadro 4 – AndroidManifest.xml ......................................................................................... 29

Quadro 5 – res/layout/gamevalues.xml ................................................................................. 31

Quadro 6 – res/values/strings.xml ........................................................................................ 32

Quadro 7 – res/values/attrs.xml ............................................................................................ 33

Quadro 8 – Múltipla tipagem de constantes .......................................................................... 33

Quadro 9 – Acessando constantes tipadas............................................................................. 33

Quadro 10 – res/menu/game_menu.xml ............................................................................... 34

Quadro 11 – Instância de menus e tratamento dos botões ..................................................... 34

Quadro 12 – XML parcial da tela de entrada ........................................................................ 44

Quadro 13 – Inicialização do GameDisplay ..................................................................... 50

Quadro 14 – Inicialização de variáveis do jogo .................................................................... 51

Quadro 15 – setGame() ................................................................................................... 51

Quadro 16 – Definindo as propriedades do jogo ................................................................... 52

Quadro 17 – Rotina de distribuição das cartas ...................................................................... 53

Quadro 18 – Ciclo de desenho .............................................................................................. 54

Quadro 19 – Atualização da posição das cartas .................................................................... 55

Quadro 20 – Verificação de posição ..................................................................................... 55

Quadro 21 – Ciclo de desenho de cartas em movimento ....................................................... 56

Quadro 22 – Função onBackPressed() ......................................................................... 57

Quadro 23 – Verificação do botão de apostas ....................................................................... 58

Quadro 24 – onPause() ................................................................................................... 60

Quadro 25 – MergeSort de cartas ..................................................................................... 61

Quadro 26 – Lista de pontuações do jogo de pôquer ............................................................. 61

Quadro 27 – Caso de uso UC01 ........................................................................................... 70

Quadro 28 – Caso de uso UC02 ........................................................................................... 71

Quadro 29 – Caso de uso UC03 ........................................................................................... 72

Quadro 30 – Caso de uso UC04 ........................................................................................... 73

Quadro 31 – Caso de uso UC05 ........................................................................................... 74

Page 10: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

Quadro 32 – Caso de uso UC06 ........................................................................................... 75

LISTA DE TABELAS

Tabela 1 – Média de quadros por segundo (fps) ................................................................... 65

Page 11: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

LISTA DE SIGLAS

AAPT - Android Asset Packaging Tool

ADT – Android Development Tools

AI - Artificial Intelligence

API – Application Programming Interface

ARGB - Alpha, Red, Green, Blue

BGE - Blender Game Engine

GB – Giga Bytes

GHz – Giga Hertz

GPU – Graphic Processing Unit

IDE - Integrated Development Environment

JIT – Just In Time

J2ME - Java 2 Micro Edition

M3GE - Mobile 3D Game Engine

MB – Mega Bytes

MJ3I - Motor de Jogos 3D para o IPhone OS

OpenGL ES - Open Graphic Library for Embedded Systems

RAM - Random Access Memory

SDK - Software Development Kit

UML - Unified Modeling Language

USB - Universal Serial Bus

XML - eXtensible Markup Language

Page 12: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

SUMÁRIO

1 INTRODUÇÃO ............................................................................................................. 13

1.1 OBJETIVOS DO TRABALHO..................................................................................... 14

1.2 ESTRUTURA DO TRABALHO .................................................................................. 14

2 FUNDAMENTAÇÃO TEÓRICA................................................................................. 15

2.1 MOTOR DE JOGOS..................................................................................................... 15

2.2 PADRÕES DE JOGOS DE CARTAS ........................................................................... 16

2.3 ANDROID .................................................................................................................... 17

2.4 PROGRAMAÇÃO JAVA PARA ANDROID ............................................................... 19

2.4.1 FrameLayout............................................................................................................... 22

2.4.2 LinearLayout .............................................................................................................. 22

2.4.3 TableLayout ................................................................................................................ 23

2.4.4 RelativeLayout............................................................................................................ 24

2.5 RECURSOS GRÁFICOS NO ANDROID .................................................................... 26

2.5.1 Bibliotecas 2D ............................................................................................................ 26

2.5.1.1 Views ....................................................................................................................... 26

2.5.1.2 Canvas ...................................................................................................................... 27

2.5.2 OpenGL ES ................................................................................................................ 27

2.5.2.1 GLSurfaceView ........................................................................................................ 28

2.5.2.2 Renderer ................................................................................................................... 28

2.6 RESOURCES E XMLS ................................................................................................ 28

2.6.1 AndroidManifest.xml .................................................................................................. 29

2.6.2 res.layout.............................................................................................................. 30

2.6.3 res.drawable ......................................................................................................... 31

2.6.4 res.values.............................................................................................................. 32

2.6.5 Personalizando menus do sistema ............................................................................... 33

2.7 TRABALHOS CORRELATOS .................................................................................... 35

2.7.1 MJ3I ........................................................................................................................... 35

2.7.2 M3GE ......................................................................................................................... 36

2.7.3 Blender Game Engine (BGE) ...................................................................................... 36

2.7.4 Havok ......................................................................................................................... 37

3 DESENVOLVIMENTO ................................................................................................ 39

Page 13: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO ..................... 39

3.2 ESPECIFICAÇÃO ........................................................................................................ 40

3.2.1 Casos de uso ............................................................................................................... 40

3.2.2 Diagramas de classe .................................................................................................... 40

3.2.2.1 Pacote engine.Model .......................................................................................... 41

3.2.2.2 Pacote View .............................................................................................................. 43

3.2.2.3 Pacote engine.Control ............................................................................ 45

3.2.2.4 Pacote engine.GameMode ................................................................................... 46

3.2.3 Diagrama de Sequência ............................................................................................... 48

3.3 IMPLEMENTAÇÃO .................................................................................................... 48

3.3.1 Técnicas e ferramentas utilizadas ................................................................................ 49

3.3.2 Inicialização da partida ............................................................................................... 49

3.3.3 Algoritmos gráficos .................................................................................................... 53

3.3.4 Algoritmos de controle................................................................................................ 57

3.3.4.1 onBackPressed() .............................................................................................. 57

3.3.4.2 onTouch() ............................................................................................................ 58

3.3.4.3 onPause() ............................................................................................................ 59

3.3.4.4 roundWinner() ................................................................................................... 60

3.3.5 Operacionalidade da implementação ........................................................................... 62

3.4 RESULTADOS E DISCUSSÃO ................................................................................... 64

4 CONCLUSÕES ............................................................................................................. 66

4.1 EXTENSÕES ............................................................................................................... 67

REFERÊNCIAS BIBLIOGRÁFICAS .............................................................................. 68

ANEXO A – UC01 - Iniciar a partida ............................................................................... 70

ANEXO B – UC02 - Alterar as configurações de jogo ..................................................... 71

ANEXO C – UC03 - Selecionar as opções de jogo ............................................................ 72

ANEXO D – UC04 - Distribuir as cartas .......................................................................... 73

ANEXO E – UC05 - Mover as cartas da mão ................................................................... 74

ANEXO F – UC06 - Modificar o valor da aposta ............................................................. 75

Page 14: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

13

1 INTRODUÇÃO

Para 2011, tem-se que a previsão de vendas dos smartphones será superior a dos

computadores desktop no Brasil (UOL TECNOLOGIA, 2011). Entre os smartphones mais

populares estão os que utilizam a plataforma Android. Com esta popularização, há uma

grande demanda por desenvolvimento de aplicativos para estes dispositivos, nas quais os

aplicativos direcionados para o entretenimento, especialmente jogos, e outros são bastante

visados. Porém, para se desenvolver jogos para smartphones, assim como para outras

plataformas, é necessário tempo e conhecimento. Neste ponto os motores de jogos1 são muito

utilizados para reduzir o tempo de produção dos jogos, pois são reaproveitados vários

recursos comuns a múltiplos jogos, de forma que o desenvolvedor possa se dedicar mais aos

detalhes específicos do jogo que está desenvolvendo do que com as necessidades padrões dos

jogos do gênero.

Diante disso, este trabalho tem como propósito facilitar o entendimento sobre o

desenvolvimento de aplicativos dentro da plataforma Android a partir da implementação de

um motor de jogos de cartas. Este motor tem como principal característica a gerência dos

componentes vitais de um jogo de cartas, tais como o baralho, a pilha de descartes, a

diferenciação de valores e naipes das cartas, entre outras características. Este motor atua em

três frentes principais: o gerenciamento da estrutura de cartas, a interface com o usuário e as

regras de jogo. A primeira frente visa a geração de cartas do baralho e sua sequência de

retirada das cartas. A segunda é encarregada de produzir o desenho dos objetos do aplicativo

na tela, a interação do toque do usuário com o aplicativo e efetuar as rotinas de movimento

das cartas dentro do espaço gráfico. A terceira deve ser responsável pela definição de regras

que um jogo deve seguir, tais como a determinação da ordem de prioridade das cartas, a

pontuação da partida, os critérios de desempate entre outros. Para validar o motor proposto,

foi implementado um protótipo de jogo de pôquer, o qual foi testado tanto em simuladores

quanto em um dispositivo Android.

1 Um motor de jogo é um software ou biblioteca responsável por implementar parcialmente ou integralmente as

funcionalidades de um jogo, podendo ser encontrada na forma de ferramentas ou bibliotecas.

Page 15: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

14

1.1 OBJETIVOS DO TRABALHO

O objetivo deste trabalho é desenvolver um motor de jogo para facilitar o

desenvolvimento de jogos de cartas para a plataforma Android.

Os objetivos específicos do trabalho são:

a) disponibilizar um gerador de cartas de um baralho que permita armazenar uma

sequência fixa ou aleatória do baralho durante a partida;

b) disponibilizar funções para a distribuição das cartas entre o(s) jogador(es);

c) disponibilizar recursos gráficos para a manipulação de cartas pelo cenário;

d) determinar um conjunto limitado de constantes para auxiliar na implementação do

protótipo de jogo, sendo algumas delas: a quantidade de cartas que cada jogador

poderá segurar, a sequência das cartas disponíveis no jogo e o valor de cada carta

entre outros valores pré-definidos;

e) disponibilizar um motor para jogos de cartas e validá-lo através de um estudo de

caso;

f) implementar um protótipo de jogo utilizando o motor desenvolvido;

g) disponibilizar os conjunto de cartas do baralho padrão francês2 e suas variantes.

1.2 ESTRUTURA DO TRABALHO

A estrutura deste trabalho é dividido em quatro capítulos, sendo que o segundo

capítulo contém a fundamentação teórica necessária para o entendimento do trabalho.

O terceiro capítulo apresenta o desenvolvimento do trabalho utilizando diagramas de

casos de uso, de classes e de sequência que definem o motor e o protótipo. Neste capítulo

também é apresentado as principais rotinas utilizadas na aplicação além de resultados e

discussões que ocorreram durante o desenvolvimento deste trabalho.

Por fim, o quarto capítulo apresenta as conclusões do trabalho e sugestões para

trabalhos futuros.

2 O baralho padrão francês é o mais utilizado atualmente e é composto por 52 cartas divididas em quatro naipes

(espadas, ouros, copas e paus). Em alguns países, foi inserido ao baralho um conjunto de cartas denominadas

curingas, ou jokers, que são cartas independentes de valor ou naipe.

Page 16: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

15

2 FUNDAMENTAÇÃO TEÓRICA

A seção 2.1 aborda o conceito de motores de jogos. A seção 2.2 trata da definição dos

jogos de cartas. A seção 2.3 apresenta um conceito geral sobre a plataforma Android. A seção

2.4 descreve as peculiaridades da programação Java dentro da plataforma. A seção 2.5 traz

conceitos sobre os recursos gráficos disponíveis na plataforma. A seção 2.6 descreve a forma

como os arquivos XML são utilizados no aplicativo. Por fim, a seção 2.7 apresenta trabalhos

correlatos ao projeto.

2.1 MOTOR DE JOGOS

Segundo Ward (2008), um motor de jogos, também conhecido como game engine, é

uma abstração de detalhes como as tarefas comuns a jogos, como renderização, física, entrada

de dados, interface gráfica com o usuário e até inteligência artificial. Porém, o conteúdo, a

modelagem gráfica e texturas, o significado atrás das entradas, colisões e a interação dos

objetos no ambiente são os componentes que definem o jogo.

O termo game engine originou-se durante a década de 90 com a popularização de

jogos 3D de tiro em primeira pessoa (First Person Shooter) tais como Doom e Quake. Devido

ao fato de suas arquiteturas consistirem em componentes bem definidos e separados do núcleo

do jogo (renderização, tratamento de colisões ou áudio) da arte, regras de jogo e experiência

de jogo, permitiram que seus desenvolvedores criassem novos produtos alterando elementos

do mundo e as regras de jogo com mínimas alterações no motor, marcando desta forma o

início da ―comunidade de mods‖. Esta comunidade é composta por grupos de jogadores e

pequenos estúdios que constroem novos módulos (mods) ou jogos utilizando ferramentas

disponibilizadas pelos desenvolvedores do jogo original (GREGORY; LANDER, 2009,

pg.11-12).

Um motor de jogos pode ser desenvolvido generalizando-se partes da implementação

para qualquer gênero de jogo, inclusive jogos multiplataforma. Porém, vários autores, como

Gregory e Lander (2009, pg.11-12), afirmam que para fins de otimização e melhor resultado,

deve ser definida uma plataforma e um gênero específico para o motor.

Page 17: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

16

Atualmente são encontrados na internet inúmeros motores de jogos disponíveis

gratuitamente ou licenciados por seus desenvolvedores para diversos fins. Não

necessariamente específicas para jogos, estes motores também podem ser encontrados na

produção de animações e filmes, além de simuladores para fins educativos, militares entre

outros. Na maior parte dos casos, costuma-se encontrá-las em forma de APIs ou SDKs, e

principalmente no caso das gratuitas, é comum encontrar comunidades de desenvolvimento

através de fóruns nas quais os desenvolvedores podem sugerir e compartilhar novos recursos,

melhorias ou corrigir problemas encontrados.

2.2 PADRÕES DE JOGOS DE CARTAS

Segundo Schuytema e Manyen (2005, p. 92), um jogo é uma atividade composta por

um conjunto de ações limitadas a um conjunto de regras, direcionadas para um determinado

fim. Estas regras servem para delimitar e contextualizar as ações do jogador, além de criar

situações de desafio e oposição ao jogador. Os jogos de cartas, muitas vezes associados como

―jogos de azar‖, também compartilham um conjunto de regras com o intuito de se alcançar

um fim. Atualmente são encontrados vários jogos de cartas com suas próprias regras e cartas

personalizadas, porém, este documento trata somente de jogos nas quais são utilizadas as

cartas existentes no baralho francês.

O baralho francês, assim como o espanhol, é composto por quatro conjuntos de cartas

denominados naipes: Paus (♣), Espadas (♠), Copas (♥) e Ouros (♦). Cada naipe é composto

por um conjunto de 13 cartas, contendo os valores de 2 a 10 e as cartas: Ás (A ou Ace), Valete

(J ou Jack), Dama (Q ou Queen) e Rei (K ou King), que representam os valores 1,11,12 e 13,

respectivamente. Em alguns jogos, utiliza-se um par de cartas especiais sem naipe chamados

―Coringas‖. Existem, porém, alguns jogos onde há uma sequência diferente de valores e

naipes que ainda podem conter variações dependendo da regionalidade dos jogadores, como

por exemplo, o jogo de truco, que possui regras diferentes em cada região do Brasil e em

outros países onde é jogado. Ainda há regras como as do jogo de canastra que permite o uso

do Ás como o décimo quarto valor (após o K), porém se esta carta for utilizada para este fim,

não poderá ser utilizada para iniciar uma nova sequência.

A origem dos jogos de cartas é desconhecida, mas acredita-se que originou na China

Page 18: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

17

por volta do século X sendo trazido por árabes para a Europa durante o século XIV

(JOGATINA, 2009). Acredita-se que o baralho francês foi inventado por um pintor chamado

Jacquemin Gringonneur, sob encomenda do rei Carlos VI de França. Gringonneur elaborou

um baralho de forma que cada naipe representasse um grupo social da França: copas para o

clero, ouro para a burguesia, espadas para os militares e paus para os camponeses (JOGOS

DE CARTAS, 2007). A Figura 1, ilustra alguns jogos populares na atualidade.

Fonte: Genkistar (2011).

Figura 1- Imagens de uma partida de pôquer (esq.) e uma partida de paciência (dir.)

2.3 ANDROID

O Android é uma plataforma de software para dispositivos móveis que inclui um

sistema operacional, uma camada intermediária (middleware) e aplicativos chave (ANDROID

DEVELOPERS, 2011). A Figura 2 demonstra a estrutura do sistema operacional do Android

dividida em grandes componentes.

Page 19: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

18

Fonte: Android Developers (2011).

Figura 2 - Arquitetura da plataforma Android

O desenvolvimento de aplicações para Android é feito utilizando a linguagem Java na

máquina virtual Dalvik, que se trata de uma máquina virtual otimizada para dispositivos

móveis. Esta máquina virtual utiliza um baixo consumo de memória, para que seja possível

instanciá-la múltiplas vezes, auxiliando no gerenciamento do sistema operacional através de

threads3. Para controlar o gerenciamento de memória e de threads, esta máquina virtual

utiliza o kernel Linux. Cada aplicação utiliza um ID próprio e é executado em uma máquina

virtual distinta. Uma ferramenta chamada DX que está inserida junto ao Android SDK trata de

comprimir e converter arquivos .class Java em arquivos .dex utilizados pela máquina

virtual Dalvik.

Todas aplicações do Android devem conter um arquivo chamado

AndroidManifest.xml que é responsável por informar ao sistema operacional os

componentes utilizados pela aplicação. O manifest também é responsável por fornecer a

ordem de prioridade dos componentes, mapear as Application Programming Interface (API)

utilizadas pela aplicação, definir a versão do sistema operacional a ser utilizada, recursos de

software e hardware que a aplicação irá utilizar e definir parâmetros de comportamento de

cada componente (ANDROID DEVELOPERS, 2011).

Aplicações desenvolvidas para o Android podem ser distribuídas gratuitamente ou

vendidas utilizando o serviço Android Market, mantido pela Google, que permite a

3 Thread é um processo ou tarefa concorrente utilizado em sistemas multitarefas que dependente de um criador.

Page 20: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

19

divulgação, distribuição e licenciamento dos aplicativos registrados no site (ANDROID

DEVELOPERS, 2011).

O Android disponibiliza várias classes relacionadas ao hardware dos dispositivos que o

comportam, dentre elas está a classe de câmera e sensores de toque, acelerômetro e bússola.

Também está disponível classes de entrada USB, mídia, banco de dados, entre outros

(ANDROID DEVELOPERS, 2011). A seção 2.4 irá detalhar um pouco mais sobre algumas

dessas classes.

2.4 PROGRAMAÇÃO JAVA PARA ANDROID

Como anteriormente citado, as aplicações desenvolvidas para a plataforma Android

são escritas na linguagem Java. Entretanto, para se desenvolver estes aplicativos, é necessária

a utilização do Android SDK, responsável por compilar o código e arquivos do projeto e

armazená-los em um único ―pacote‖, um arquivo com extensão .apk que será responsável pela

instalação da aplicação no dispositivo (ANDROID DEVELOPERS, 2011).

Pela preocupação na utilização de recursos nos dispositivos móveis, ao se tratar de

desempenho nas aplicações para o Android, no qual pode implicar diretamente no consumo

de bateria que a aplicação utilizará, segundo os desenvolvedores do Android, duas regras

básicas devem ser seguidas: ―Não faça trabalho desnecessário‖ e ―Evite alocar memória se

possível‖ (ANDROID DEVELOPERS, 2011).

Com base nas regras citadas acima, os desenvolvedores do Android consideram

algumas formas de reduzir a utilização de recursos do aplicativo (ANDROID DEVELOPERS,

2011), sendo elas:

a) evitar criar objetos desnecessários: variáveis temporárias de curta utilização devem

ser evitadas, pois uma menor quantidade de objetos significa chamadas menos

frequentes do Garbage Collector, reduzindo assim consideravelmente o consumo

de memória;

b) preferir o uso de métodos estáticos a virtuais: o uso de métodos estáticos tornam-

nos de 15% a 20% mais rápidos;

c) evitar o uso de getters e setters: a utilização destas funções são bastante difundidas

na programação orientada a objetos, porém as chamadas destas funções são de um

Page 21: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

20

alto custo, muito maiores que as chamadas diretas de suas respectivas variáveis. É

aceitável o uso das funções ao utilizar chamadas entre classes. Porém dentro de

uma mesma classe, a variável deve ser sempre acessada diretamente, pois além do

consumo de memória, o acesso a variáveis diretamente é três vezes mais rápida, ou

até 7 vezes em sistemas com Just-In-Time4 (JIT);

d) utilizar static final para constantes: a utilização do parâmetro final facilita o

acesso ao valor da constante, pois ao invés de consultar uma tabela de constantes, o

valor é diretamente acessado. Esta regra aplica-se somente para tipos primitivos

como int e String;

e) utilizar o loop For otimizado: aconselha-se o uso de for-each na interação de

vetores, pois ele pode tornar o loop até três vezes mais rápido;

f) conhecer e usar as bibliotecas: métodos da biblioteca do sistema podem ser

melhores que o melhor método produzido pelo JIT para um equivalente escrito

manualmente em Java.

Os aplicativos desenvolvidos para o Android contêm quatro principais componentes

(ANDROID DEVELOPERS, 2011):

a) atividades (activities): representa uma tela única de interface com o usuário. Cada

atividade é independente das outras e outra aplicação pode chamá-la se a atividade

permitir;

b) serviços (services): representa um componente sem interface com o usuário que

roda ocultamente para executar processos de longa duração ou remotos;

c) provedores de conteúdo (content providers): gerenciador de dados da aplicação,

controlando seu acesso ao banco de dados e se necessário, alterar dados do usuário;

d) receptores de transmissão (broadcast receivers): este componente gerencia as

notificações e alertas da aplicação, sendo utilizado para comunicar-se com outros

aplicativos quando uma requisição for concluída.

Dos quatro componentes citados acima, o mais utilizado é a atividade pelo fato desta

ser o componente responsável por exibir uma interface que permita ao usuário interagir. Uma

aplicação pode conter apenas uma tela ou múltiplas, contidas em suas respectivas atividades.

Cada atividade permite que seja chamada uma nova atividade que é colocada à frente da atual,

4 JIT é um compilador desenvolvido para a máquina virtual Dalvik, disponível a partir do Android 2.2, que

analisa o código da aplicação e o converte para uma forma mais eficiente enquanto o aplicativo está rodando

(ANDROID DEVELOPERS, 2010).

Page 22: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

21

sendo armazenado numa pilha de atividades, também conhecido como back-stack, conforme

ilustra a Figura 3.

Fonte: Android Developers (2011).

Figura 3 - Representação da pilha de atividades

Cada atividade chamada antes da atual é armazenada na pilha guardando as variáveis

disponíveis no momento e quando pressionado o botão back, a atividade atual é destruída e o

conteúdo da atividade anterior é recuperado. Ao chamar uma nova atividade, a anterior é

parada, eventos de mudança de estado são disparados, como o onPause(), e recomenda-se

que ao mudar o estado da atividade os dados utilizados nesta atividade sejam gravados pois

não há garantias que o usuário retorne a esta atividade. Sugere-se também que ao parar uma

atividade, objetos grandes como conexões de rede ou bancos de dados, devem ser liberados e

recuperados no momento que a atividade for restituída (ANDROID DEVELOPERS, 2011).

Um conjunto de atividades pode ser agrupado em tarefas, permitindo que esse

conjunto possa ser movido para o plano de fundo quando pressionado o botão home sem que

as atividades sejam destruídas. Ao mover a tarefa para o plano de fundo, os dados das

atividades são armazenados e serão recuperados assim que o usuário retornar à aplicação.

Porém, caso o desenvolvedor desejar que as informações da atividade atual sejam preservadas

quando o usuário pressionar o botão back, será necessário armazená-las de alguma forma, nas

quais os meios mais utilizados são armazenando na classe SharedPreferences, que permite

armazenar dados de tipos primitivos como int, String, long entre outros, salvando no banco de

dados sqllite, nativo do Android ou armazenando-os em um arquivo (ANDROID

DEVELOPERS, 2011).

Os serviços são componentes que não necessitam de uma interface com usuário e

podem rodar operações de longo prazo em plano de fundo. Um serviço iniciado pela aplicação

Page 23: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

22

continuará rodando mesmo após a aplicação perder o foco. Este componente costuma ser

utilizado para gerenciar conexões, tocar músicas e comunicar com bancos e dados. Cada

serviço, como os outros componentes, deve ser declarado no manifest e caso ele necessite

utilizar um grande consumo de recursos, ele deverá ser criado em um thread separada para

reduzir o risco de travar a aplicação (ANDROID DEVELOPERS, 2011).

Os provedores de conteúdo são os componentes responsáveis por efetuar a

comunicação entre aplicações, permitindo integrar vários tipos de dados comuns, tais quais

arquivos de áudio, vídeo, imagens, dados pessoais entre outros. Há duas formas de utilizar os

provedores: criando um nova instância da classe ContentResolver, ou utilizando um

provedor já existente desde que este seja de mesmo tipo e haja permissão de escrita

(ANDROID DEVELOPERS, 2011).

Para se implementar uma Graphic User Interface (GUI) para a aplicação, utiliza-se

derivados da classe View e ViewGroup. Cada View é responsável por uma região retangular na

atividade e permite que o usuário interaja nesta região. A classe View contém subgrupos

chamados widgets, objetos de interface como botões e campos de texto, enquanto o

ViewGroup contém as subclasses de layouts, responsáveis por estruturar os componentes na

tela (ANDROID DEVELOPERS, 2011).

Há quatro tipos principais de layouts: FrameLayout, LinearLayout, TableLayout e

RelativeLayout.

2.4.1 FrameLayout

O tipo mais simples de layout. É composto por um elemento que ocupa todo o espaço

da tela e pode ser ocupado total ou parcialmente por somente um elemento, como uma

imagem por exemplo. O objeto inserido neste layout sempre será fixo no canto superior

esquerdo da tela, e novos objetos inseridos neste layout irão sobrepor os objetos anteriores.

2.4.2 LinearLayout

Este layout alinha os componentes associados a ele na direção horizontal ou vertical

Page 24: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

23

dependendo de qual for o parâmetro definido na propriedade orientation. Cada elemento

filho do layout é empilhado abaixo do elemento anterior. Este layout permite também que

seus elementos tenham pesos diferenciados, permitindo assim que elementos com maior peso

preencham um espaço maior na tela, como pode ser visto na Figura 4. A imagem da esquerda

ilustra elementos sem peso definido, que por padrão o valor é zero, enquanto na imagem da

direita, o campo de comentários tem um peso igual a 1 dando maior prioridade a ele. Caso o

campo de nome também tivesse peso 1, os dois campos teriam o mesmo tamanho.

Fonte: Android Developers (2011).

Figura 4 - LinearLayout

2.4.3 TableLayout

Este layout utiliza uma estrutura de tabela, dividido em linhas e colunas. Cada tabela

irá possuir a quantidade de colunas igual à linha com o maior número de células dentro dela.

Cada linha deste layout é definido pelo objeto TableRow, que pode conter zero ou mais

células e cada célula é definida por qualquer componente da classe View. O Quadro 1

demonstra o eXtensible Model Language (XML) que estrutura uma tabela simples contendo

duas linhas e duas colunas, como pode ser visualizado na Figura 5.

Page 25: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

24

<?xml version="1.0" encoding="utf-8"?>

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:stretchColumns="1">

<TableRow>

<TextView

android:text="@string/table_layout_4_open"

android:padding="3dip" />

<TextView

android:text="@string/table_layout_4_open_shortcut"

android:gravity="right"

android:padding="3dip" />

</TableRow>

<TableRow>

<TextView

android:text="@string/table_layout_4_save"

android:padding="3dip" />

<TextView

android:text="@string/table_layout_4_save_shortcut"

android:gravity="right"

android:padding="3dip" />

</TableRow>

</TableLayout>

Fonte: Android Developers (2011).

Quadro 1 - Estrutura XML de um TableLayout

Fonte: Android Developers (2011).

Figura 5 - TableLayout

2.4.4 RelativeLayout

O RelativeLayout permite que os componentes dispostos nele sejam posicionados em

relação ao container ou a algum outro elemento pelo seu id. Caso seja utilizado um arquivo

XML para determinar os elementos do layout, deve-se criar o elemento base antes do

elemento que irá referenciá-lo. O Quadro 2 exemplifica uma estrutura simples de um layout

relativo com quatro componentes básicos, como pode ser visto na Figura 6.

Page 26: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

25

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@drawable/blue"

android:padding="10px" >

<TextView android:id="@+id/label"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Type here:" />

<EditText android:id="@+id/entry"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@android:drawable/editbox_background"

android:layout_below="@id/label" />

<Button android:id="@+id/ok"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@id/entry"

android:layout_alignParentRight="true"

android:layout_marginLeft="10px"

android:text="OK" />

<Button android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toLeftOf="@id/ok"

android:layout_alignTop="@id/ok"

android:text="Cancel" />

</RelativeLayout>

Fonte: Android Developers (2011).

Quadro 2 – Estrutura XML de um RelativeLayout

Fonte: Android Developers (2011).

Figura 6 – RelativeLayout

Page 27: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

26

2.5 RECURSOS GRÁFICOS NO ANDROID

Android Developers (2011), comenta que há três principais recursos gráficos

disponíveis na plataforma, sendo eles as bibliotecas gráficas 2D do pacote drawable, as APIs

de Open Graphic Library for Embedded Systems (OpenGL ES) e as APIs do RenderScript.

Essas bibliotecas devem ser utilizadas com consciência da necessidade que a aplicação irá

utilizar, pois cada uma possui características que permitem facilitar o desenvolvimento em

determinados casos, conforme comentado a seguir.

2.5.1 Bibliotecas 2D

Há duas formas principais de se desenhar gráficos em 2D, sendo elas a utilização de

Views ou desenhando diretamente em um Canvas (ANDROID DEVELOPERS,2011).

2.5.1.1 Views

Para o desenvolvimento de gráficos e animações em 2D, existem duas bibliotecas

disponíveis no Android para desenhar imagens e formas, sendo elas a

android.graphics.drawable e a android.view.animation.

Segundo Android Developers (2011), um objeto da classe Drawable é ―algo que pode

ser desenhado‖. Há três formas de se instanciar um objeto Drawable: utilizando uma imagem

existente dentro do projeto, utilizando um arquivo XML para definir as propriedades do

objeto ou utilizando construtores da classe.

Utilizar imagens salvas dentro do projeto são recomendadas para a utilização em

ícones, logos ou outros gráficos como os utilizados em um jogo. As imagens suportadas pela

classe Drawable são: Portable Network Graphics (PNG) que é preferível,

Joint Photographic Experts Group (JPG) que é considerado aceitável e

Graphics Interchange Format (GIF) é desencorajado pela plataforma. Para utilizar uma

imagem, ela deve estar inserida na pasta res/drawable/ ou na pasta res/raw/. Caso ela

esteja na pasta res/drawable/, na construção do projeto, uma ferramenta chamada Android

Page 28: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

27

Asset Packaging Tool (AAPT), responsável por criar a classe R.java, que automaticamente

efetua a compressão otimizada de imagens sem perda de qualidade, reduzindo assim o

consumo de memória ao utilizar esta imagem. Por exemplo, uma imagem PNG que utiliza

menos que 256 cores, é convertido para um PNG 8 bits. Porém, caso a imagem deva ser

utilizada em seu estado original na forma de bitmap, a imagem deve ser inserida na pasta

res/raw/. O Quadro 3 demonstra um exemplo de implementação de uma imagem chamada

card_background_blue.png existente dentro da pasta drawable/nodpi/ no projeto

(ANDROID DEVELOPERS, 2011).

Resources res = getContext().getResources();

Drawable img = res.getDrawable(R.drawable.card_background_blue);

Quadro 3 - Exemplo de inserção de recursos

2.5.1.2 Canvas

Segundo Android Developers (2011), desenhar utilizando o Canvas é melhor em casos

onde é necessário que a tela seja redesenhada regularmente. O Canvas atua como um

intermediador armazenando as chamadas de desenho do aplicativo e convertendo-os em um

Bitmap que será inserido na tela. É possível criar um novo Canvas passando como parâmetro

um Bitmap que define a área de desenho, porém recomenda-se que seja utilizado o Canvas

disponível pela função View.onDraw() ou SurfaceHolder.lockCanvas(). A classe

disponibiliza várias funções de desenho como o drawRect() e o drawBitmap(), permitindo

também utilizar recursos da classe Drawable.

2.5.2 OpenGL ES

A biblioteca OpenGL para a plataforma Android disponibiliza gráficos de alta

performance tanto para 2D como 3D utilizando a API OpenGL ES. No Android, há duas

classes fundamentais que permitem a criação e manipulação de gráficos pelo OpenGL ES.

Page 29: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

28

2.5.2.1 GLSurfaceView

Esta classe derivada da classe View, é muito semelhante à classe SurfaceView, que é

uma View que permite ser alterado seu formato e tamanho utilizando ordenação por

profundidade para organizar seus objetos. Esta classe é responsável por gerenciar superfícies

que são componentes especiais na visualização no Android, renderização utilizando threads

dedicadas para melhorar o desempenho e suporta renderização sob demanda ou contínuo.

Toda GLSurfaceView necessita de um Renderer, que é registrado pela função

setRenderer(Renderer). Após definido o Renderer, é possível alterar seu modo padrão de

renderização contínua para sob demanda.

2.5.2.2 Renderer

A interface genérica Renderer deriva do pacote GLSurfaceView e é responsável por

fazer o OpenGL desenhar os quadros na tela. Cada Renderer gera uma nova thread, para que

o desempenho da aplicação não seja prejudicada.

2.6 RESOURCES E XMLS

Os aplicativos do Android têm forte vínculo com arquivos XML, desde o mapeamento

dos componentes do sistema até os layouts e atributos das classes. A partir do arquivo

AndroidManifest.xml (Quadro 4), ao compilar o projeto são mapeados os recursos e

propriedades utilizados pelo aplicativo que deseja-se aplicar a todas as atividades ou a um

algumas em específico.

Ao criar um novo projeto Android no Eclipse, é criada uma pasta chamada res que

possui por padrão as pastas drawable, layout e values. Os arquivos inseridos dentro da

pasta res devem utilizar somente letras minúsculas, números e sublinhado, sendo que o

primeiro caractere deve ser uma letra.

Page 30: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

29

2.6.1 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="(...)/apk/res/android" package="engine.View">

<uses-sdk android:targetSdkVersion="10" android:minSdkVersion="10" />

<application android:icon="@drawable/card_background_blue"

android:debuggable="true"

android:label="Card Engine"

android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

<activity android:name="Home">

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER"/>

</intent-filter>

</activity>

<activity android:name="GameDisplay"

android:screenOrientation="landscape" />

<activity android:name="Option" />

<activity android:name="ScoreBoard" />

<activity android:name="GameRules" />

</application>

</manifest>

Quadro 4 – AndroidManifest.xml

No Manifest descrito no quadro acima, dentro do nó raiz <manifest> é necessário

utilizar o atributo package, pois este define o caminho onde a classe R se localiza. Em geral a

maioria das propriedades que se dizem respeito ao às configurações do aplicativo iniciam-se

com o prefixo ―android:‖.

Dentro do nó raiz, o primeiro nó <uses-sdk> define a versão alvo do aplicativo. O

valor 10 dentro desses parâmetros se refere à versão 2.3.3 do Android.

O segundo nó detalha as informações necessárias para a aplicação em si, onde o

primeiro parâmetro android:icon se refere ao caminho do ícone que será exibido no

dispositivo. O parâmetro android:debuggable com valor true permite que o desenvolvedor

possa utilizar o modo debug da ferramenta no aplicativo. O parâmetro android:label define

o título do aplicativo que o usuário verá no dispositivo e na barra de título caso esta esteja

disponível. O valor Theme.NoTitleBar.Fullscreen do ultimo parâmetro define que em

todos os momentos dessa aplicação não haverá nem a barra de título do aplicativo nem a barra

de status do sistema.

Dentro do segundo nó estão contidos os nodos que definem as atividades (telas) que

compõem a aplicação. Cada atividade deve conter o nome da classe estendida de Activity

que será utilizada na aplicação, caso contrário, ao instanciar esta classe, será disparado um

erro de atividade não encontrada.

Page 31: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

30

O nó Home possui um sub-nó <intent-filter> onde é definido que esta atividade

inicia a aplicação.

No nó GameDisplay, a propriedade android:screenOrientation, força que esta

atividade seja somente exibida em modo paisagem. Contudo, pode ser definido também para

somente modo retrato (portrait) e por padrão o sistema adapta os elementos da tela em relação

a orientação do dispositivo.

2.6.2 res.layout

A pasta layout contém as estruturas das atividades que são utilizadas no projeto,

podendo cada XML utilizar tanto Views pré-definidas pelo ambiente, como botões, campos

de texto e rótulo, como mapear novas Views personalizadas que serão criadas pelo

desenvolvedor.

Ao definir o layout de uma atividade, todas as Views inseridas dentro do XML devem

conter os atributos android:layout_height e android:layout_width que podem receber

os valores wrap_content, match_parent e fill_parent ou valores numéricos fixos nos

seguintes formatos de medidas: px (pixels), dp (pixels independentes de densidade), sp (pixels

escalados, baseados no tamanho preferencial de fonte), in (polegadas) e mm (milímetros)

(ANDROID DEVELOPERS, 2011). O valor fill_parent a partir da versão 8 da API do

Android foi depreciado em favor do valor match_parent e ambos tem a função de

dimensionar a View de forma a preencher todo o espaço ocupado pela View que a contém, ou

preencher toda a tela caso esta seja a View raiz. No Quadro 5 é possível visualizar o layout da

tela de regras da atividade GameRules descrito no arquivo gamerules.xml.

Page 32: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

31

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/bghome">

<ScrollView

android:padding="15px"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:fillViewport="true">

<RelativeLayout

android:padding="10px"

android:layout_width="match_parent"

android:layout_height="wrap_content">

<TextView

android:id="@+id/PokerRules"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@string/poker_rules" />

<Button android:id="@+id/RulesReturn"

android:background="@drawable/btreturn"

android:layout_below="@id/PokerRules"

android:layout_centerHorizontal="true"

android:layout_margin="15px"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

</RelativeLayout>

</ScrollView>

</LinearLayout>

Quadro 5 – res/layout/gamevalues.xml

Cada View pode possuir uma imagem ou cor de fundo sendo o arquivo buscado através

do caminho ―@drawable/nome_do_arquivo‖ ou utilizando os valores hexadecimais Alpha,

Red, Green, Blue (ARGB). As Views também podem possuir um id que é utilizado

posteriormente para ser referenciado por outros elementos ou funções. A sintaxe para a

definição de um id é ―@+id/nome_var‖ onde nome_var deve ser um id único no pacote. Para

acessar o id criado anteriormente, utiliza-se ―@id/nome_var‖ como pode ser visto nas

propriedades da View Button do quadro acima.

2.6.3 res.drawable

Por padrão, ao criar um novo projeto Android no Eclipse, são gerados três pastas

dentro da pasta res: drawable-hdpi, drawable-mdpi e drawable-ldpi. Estas três pastas

são geradas a fim de armazenar os componentes gráficos e exibi-los para o usuário

dependendo da resolução disponível no dispositivo, porém caso não se deseje trabalhar desta

Page 33: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

32

forma, existe a opção de armazenar arquivos numa única pasta chamada drawable-nodpi

onde para todas as resoluções, será utilizada a mesma proporção para as imagens. Além das

proporções citadas antes, também estão disponíveis os valores xhdpi e tvdpi (ANDROID

DEVELOPERS, 2011).

2.6.4 res.values

A pasta values criada por padrão na geração do projeto contém o arquivo

strings.xml que por padrão armazena os valores literais que são utilizados na aplicação. O

Quadro 6 ilustra o conjunto de strings que são utilizadas na aplicação. Estas strings podem

ser acessadas a qualquer momento pelo desenvolvedor utilizando a referência

―R.string.string_name‖.

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="showRules">Rules</string>

<string name="showScore">Scoreboard</string>

<string name="exitGame">Quit Game</string>

<string name="colorChooser">Select a color:</string>

<string-array name="colors">

<item>black</item>

<item>blue</item>

<item>red</item>

<item>green</item>

<item>yellow</item>

<item>silver</item>

</string-array>

<string name="poker_rules">(…)</string>

</resources>

Quadro 6 – res/values/strings.xml

Dentro desta pasta também é permitido criar outros arquivos de propriedades como o

attrs.xml descrito no Quadro 7 que possui as propriedades do protótipo de pôquer.

Page 34: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

33

<?xml version="1.0" encoding="utf-8"?>

<resources>

<!-- deck type 0 = default, type 1 = spanish style -->

<item type="PokerVars" format="integer" name="deck_type">0</item>

<item type="PokerVars" format="integer" name="player_money">50</item>

<item type="PokerVars" format="integer" name="hand_limit">5</item>

<item type="PokerVars" format="integer" name="initialBet">5</item>

<item type="PokerVars" format="boolean" name="bet">true</item>

<item type="PokerVars" format="boolean" name="joker">false</item>

<item type="PokerVars" format="boolean" name="auto_draw">true</item>

<item type="PokerVars" format="boolean" name="upcard">false</item>

<!-- Multiplayer setup -->

<item type="PokerVars" format="integer" name="min_players">2</item>

<item type="PokerVars" format="integer" name="max_players">4</item>

<item type="PokerVars" format="boolean" name="discard">false</item>

<!-- Allows to shuffle the discard pile back to the deck -->

<item type="PokerVars" format="boolean"

name="restart_on_end">false</item>

</resources>

Quadro 7 – res/values/attrs.xml

Os itens do quadro anterior possuem uma variável type que permite que o

desenvolvedor insira um tipo qualquer, nativo ou mesmo inexistente, que auxilia ao mesmo

que encontre com maior facilidade para acessar as variáveis desejadas. Definir tipos diferentes

permite inserir outros nós com o mesmo nome, como pode ser visto no Quadro 8.

<item type="PokerVars" format="boolean" name="joker">false</item>

<item type="CanastraVars" format="boolean" name="joker">true</item>

Quadro 8 – Múltipla tipagem de constantes

Para o desenvolvedor acessar esta variável, deve-se buscar o tipo definido no

parâmetro format através dos Resources da aplicação passando como parâmetro o caminho

através da classe R (Quadro 9).

Resources res = getResources(); this.joker = res.getBoolean(R.PokerVars.joker);

Quadro 9 – Acessando constantes tipadas

2.6.5 Personalizando menus do sistema

Para criar um menu de opções do Android são necessários três procedimentos:

elaborar um layout, sobrescrever a função onCreateOptionsMenu() e atribuir as ações

quando um dos botões for selecionado utilizando a função onOptionsItemSelected().

Page 35: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

34

O menu foi gerado a partir do arquivo res/menu/game_menu.xml (Quadro 10) onde

cada item possui um id para permitir mapear seu evento posteriormente, o ícone que deve ser

exibido na tela e o nome do botão para auxiliar o usuário a entender a utilidade dele.

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/showRules"

android:icon="@drawable/icocards"

android:title="@string/showRules" />

<item android:id="@+id/showScore"

android:icon="@drawable/icocoins"

android:title="@string/showScore" />

<item android:id="@+id/exitGame"

android:icon="@drawable/icoexit"

android:title="@string/exitGame" />

</menu>

Quadro 10 – res/menu/game_menu.xml

Após elaborado o layout, a View deve sobre-escrever as funções citadas

anteriormente (Quadro 11). Quando um item do menu é pressionado, a função

onOptionsItemSelected() é chamada recebendo como parâmetro o item selecionado

permitindo assim efetuar o tratamento do clique a partir do id definido no XML pela função

item.getItemId().

@Override

public boolean onCreateOptionsMenu(Menu menu){

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.game_menu, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

// Handle item selection

switch (item.getItemId()) {

case R.id.showRules:

showRules();

return true;

case R.id.showScore:

showScore();

return true;

case R.id.exitGame:

exitGame();

return true;

default: return super.onOptionsItemSelected(item);

}

}

Quadro 11 – Instância de menus e tratamento dos botões

Page 36: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

35

2.7 TRABALHOS CORRELATOS

Nesta seção são descritos quatro trabalhos correlatos relacionados ao desenvolvimento

de motores de jogos para Android, quais sejam: Motor de Jogos 3D para o iPhone OS (MJ3I)

apresentado por Takano (2009), Mobile 3D Game Engine (M3GE), desenvolvido por

Pamplona (2005), Blender Game Engine, disponibilizado pela Blender Foundation

(VELDHUIZEN, 2010a) e a Havok, criado pela empresa de mesmo nome (HAVOK INC,

2011a).

2.7.1 MJ3I

Este projeto desenvolvido por Takano (2009) teve como foco o desenvolvimento de

um motor de jogos para o iPhone com foco na construção de um ambiente 3D utilizando o

OpenGL ES (Figura 7), gerenciamento de grafos de cena, importação de arquivos 3D e

tratamento de colisões para abstrair a implementação de rotinas básicas necessárias para um

jogo em 3D. A linguagem de programação utilizada no projeto foi o Objective-C no ambiente

de desenvolvimento xCode.

Fonte: Takano ( 2009).

Figura 7 – Exemplo de aplicação do MJ3I

Page 37: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

36

2.7.2 M3GE

Pamplona (2005) descreve o protótipo de um motor de jogos 3D para dispositivos

móveis utilizando um algoritmo leitor de arquivos de modelo 3D e montagem visual do

cenário ao jogador, implementação de câmeras de visualização e movimentação do

personagem do cenário. Para o desenvolvimento do projeto foi utilizada a plataforma Java 2

Micro Edition (J2ME), uma das extensões do Java para sistemas embarcados, com o intuito

de além de criar uma ferramenta de desenvolvimento para jogos, testar a portabilidade e

velocidade de processamento onde o jogo gerado seria instalado.

2.7.3 Blender Game Engine (BGE)

O BGE, desenvolvido pela Blender Foundation, é uma ferramenta gratuita open

source, escrita na linguagem C++. Parte da ferramenta gráfica Blender sob a licença da GNU

GPL5, este motor contém ferramentas de produção gráfica em 2 e 3D, manipulação de grafos

de cena, entre outros recursos e permite a utilização da linguagem Python para a geração de

scripts (VELDHUIZEN, 2010a). Segundo Veldhuizen (2010a), o BGE utiliza um plugin de

um motor de física para jogos 3D chamado Bullet para gerenciar a detecção de colisão, a

dinâmica de corpos rígidos e maleáveis de objetos 3D criados na ferramenta. Este motor,

também utiliza a biblioteca Open Audio Library (OpenAL) para gerenciar os efeitos sonoros

do ambiente. A Figura 8 ilustra a interface do BGE.

5 GNU General Public Licence (GNU GPL), criada em 1989, foi a primeira licença para softwares livres e

atualmente a mais utilizada pelos desenvolvedores de softwares de código aberto.

Page 38: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

37

Fonte: Veldhuizen (2010b).

Figura 8 - Interface do BGE

2.7.4 Havok

Este motor proprietário é considerado pela sua utilização multiplataforma em títulos de

sucesso como Soul Callibur IV (PlayStation 3, Xbox 360), Spore (Personal Computer - PC) e

StarCraft II (PC) entre outros (HAVOK INC, 2011a).

O motor é composto por sete módulos de ferramentas (HAVOK INC, 2011b), sendo

eles a Havok Artificial Intelligence (AI), Animation, Behavior, Cloth, Destruction, Physics e

Script, sendo o Havok Animation e o Physics os mais utilizados pelos jogos. Cada módulo foi

projetado para atender a uma necessidade específica de um jogo 3D, abstraindo cálculos

complexos necessários para seu desenvolvimento. A Figura 9 ilustra uma das ferramentas da

empresa, o Havok Physics.

Page 39: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

38

Fonte: Havok Inc (2011c).

Figura 9 - Interface do Havok Physics

Embora esta ferramenta seja paga, ela também é distribuída gratuitamente com os

módulos Physics e Animation em parceria com a Intel, para desenvolvedores Windows sem

fins comerciais.

Page 40: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

39

3 DESENVOLVIMENTO

Neste capítulo são abordadas as etapas de desenvolvimento do trabalho. São ilustrados

os requisitos, a especificação, implementação e por fim são listados resultados e discussão.

3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO

O motor para o desenvolvimento de jogos para Android deve:

a) permitir alterar regras de jogo durante a implementação de cada jogo (Requisito

Funcional - RF);

b) permitir alterar a velocidade dos movimentos das cartas na cena (RF);

c) permitir configurar a pontuação do jogo (RF);

d) permitir definir o conjunto de cartas a ser utilizado no protótipo de jogo (RF);

e) permitir definir a ordem das cartas do protótipo (RF);

f) permitir definir o modo de distribuição inicial e durante a partida (RF);

g) permitir a movimentação e manipulação das cartas pelo jogador (RF);

h) utilizar a linguagem de programação Java para Android (Requisito Não-Funcional

– RNF);

i) utilizar o ambiente Eclipse Integrated Development Environment (IDE) como

ambiente de desenvolvimento (RNF);

j) utilizar um dispositivo Android e o Android SDK como ambiente de testes (RNF).

O protótipo de jogo de pôquer deve:

a) permitir ao jogador iniciar ou continuar uma partida (RF);

b) permitir ao jogador visualizar sua pontuação e de seus adversários (RF);

c) permitir reorganizar as cartas de sua mão (RF);

d) permitir ao jogador modificar o verso das cartas (RNF).

Page 41: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

40

3.2 ESPECIFICAÇÃO

A especificação deste trabalho foi elaborada utilizando a ferramenta Enterprise

Architect, utilizando conceitos de orientação a objetos baseando nos diagramas da Unified

Modeling Language (UML), produzindo os diagramas utilizados nas próximas seções.

3.2.1 Casos de uso

Nesta seção são descritos os casos de uso deste projeto. Um ator foi identificado: o

Usuário, que irá interagir com o jogo resultante do projeto. A Figura 10 ilustra o diagrama de

casos de uso deste ator.

uc Use Case Model

Usuário

UC01 - iniciar a

partida

UC02 - Alterar as

configurações do

jogo

UC04 -

Distribuir as

cartas

UC03 - Selecionar

opções do jogo

UC05 - Mov er

cartas da mão

UC06 - Modificar o

v alor da aposta

Figura 10 – Diagrama de casos de uso

O detalhamento de cada caso de uso do diagrama encontra-se nos anexos A até F.

3.2.2 Diagramas de classe

Nesta seção são apresentadas as classes que compõem a estrutura do motor e as classes

do protótipo, seus relacionamentos e propriedades. Para facilitar o entendimento da estrutura,

Page 42: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

41

foi adotado o modelo de padrões de projetos chamado Model-View-Controller (MVC) para

dividir cada grupo de classes baseado em suas funções. A Figura 11 representa a estrutura do

motor de jogos o pacote GameMode está contido no pacote Control, pois as classes derivadas

da classe Game determinam as rotinas de gerenciamento do jogo.

class Simple Model

engine.Model

engine.Control

engine.GameMode

engine.View

DeckFPS

PlayerCardConstants

Poker

GameDisplayGameView Home

OptionGameRules

ScoreBoard

Game

Figura 11 – Diagrama de classes do motor de jogos

3.2.2.1 Pacote engine.Model

O pacote engine.Model constitui as classes de base do projeto ilustradas na Figura 12.

Neste pacote estão incluídas as classes Card, Player e Constants que são utilizadas na

maioria das classes dos outros pacotes do projeto.

Page 43: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

42

class Class Model

engine.Model

Player

+ hand: ArrayList<Card>

+ name: String

+ points: int

+ tierBreaker: ArrayList<Card>

+ coins: int

+ betStatus: int

+ Player(String) : void

+ sortHand() : void

Card

+ angle: float

+ toX: float

+ id: int

+ suit: int

+ value: int

+ visible: boolean

+ toY: float

+ x: float

+ y: float

- toAngle: float

+ Card(int, int) : void

+ getImage() : String

+ getSuit() : String

+ getValue() : String

Constants

+ BGNONE: int = R.drawable.card_none {readOnly}

+ BOARDMARGIN: int = 20 {readOnly}

+ CARDMOVE: int = 5 {readOnly}

+ DEFAULT_SEQUENCE: int = 0 {readOnly}

+ DRAWTIME: int = 900 {readOnly}

+ SPANISH_DECK: int = 1 {readOnly}

+ CARD_HEIGHT: int = 113 {readOnly}

+ CARD_WIDTH: int = 78 {readOnly}

+ PREF_FILE: String = PreferencesFile {readOnly}

- TOP_LEFT: int = 0 {readOnly}

- TOP: int = 1 {readOnly}

- TOP_RIGHT: int = 2 {readOnly}

- LEFT: int = 3 {readOnly}

- CENTER: int = 4 {readOnly}

- RIGHT: int = 5 {readOnly}

- BOTTOM_LEFT: int = 6 {readOnly}

- BOTTOM: int = 7 {readOnly}

- BOTTOM_RIGHT: int = 8 {readOnly}

Figura 12 – Pacote engine.Model

A classe Card contém os atributos básicos de uma carta, seu valor e naipe, posição x e

y, margem e ângulo. O construtor da classe recebe como parâmetro o valor da carta e naipe,

que depois quando chamadas as funções getSuit e getValue retornam a versão literal destes

valores para se obter o nome do arquivo de imagem correto a ser retornado pela função

getImage. A classe possui também o atributo visible que define se será exibido a frente ou

o verso da carta e as variáveis de movimentação toX, toY e toAngle. Card é utilizada na

classe Player para compor as cartas da mão do jogador e armazenar as cartas para desempate

(tierBreaker). Na classe Deck, ela é utilizada para a composição das cartas do baralho que

são distribuídas para os jogadores e disponibilizadas na mesa caso necessário. As classes Game

e GameView também utilizam esta classe e serão abortados mais a diante.

A classe Player contém em seus atributos o nome do jogador, seus pontos da rodada,

dinheiro da partida e status da aposta na rodada, além de uma lista de cartas que possui na

mão e uma lista adicional para auxiliar no critério de desempate. Esta classe é utilizada na

classe Game e GameView para o gerenciamento do número de jogadores dentro do jogo, sua

manipulação e gerenciamento de suas cartas.

A classe estática Constants armazena valores e propriedades relacionadas ao desenho

da tela e utilizadas na maioria das classes do projeto, sendo mais utilizadas as variáveis de

posicionamento dos elementos, como TOP_LEFT, TOP_RIGHT e BOTTOM, definição do tamanho

da imagem das cartas e o espaço das margens da tela.

Page 44: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

43

3.2.2.2 Pacote View

O pacote engine.View (Figura 13 e Figura 14) é responsável pelo gerenciamento de

layouts do sistema sendo cada classe, excluindo a classe GameView, responsável por uma tela

do programa.

class Class Model

GameDisplay

- gameView: GameView

- settings: SharedPreferences

- game: Game

- rulesIntent: Intent

- scoreIntent: Intent

- requestCode: int

+ raise: Button

+ fold: Button

+ call: Button

+ back: Button

+ coin5: Button

+ coin10: Button

+ coin25: Button

+ coin50: Button

+ coin100: Button

+ onCreate(Bundle) : void

+ showRules() : void

+ exitGame() : void

+ onCreateOptionsMenu(Menu) : void

+ onOptionsItemSelected(MenuItem) : void

+ onPause() : void

+ showScore() : void

+ onBackPressed() : void

+ onActivityResult(int, int, Intent) : void

GameView

- mPaint: Paint

- card: Bitmap

- fps: FPS

- game: Game

- time: long

+ roundBet: int

+ drawMode: int

+ card_bg: int

- GAME_MODE: int = 0 {readOnly}

- BET_MODE: int = 1 {readOnly}

- status: String

- currentBet: String

- betView: RelativeLayout

- betText: TextView

+ setGame(Game) : void

- initDrawView() : void

+ saveState() : Bundle

+ restoreState(Bundle) : void

+ onDraw(Canvas) : void

+ onTouch(View, MotionEvent) : void

+ update() : void

+ onSizeChanged(int, int, int, int) : void

Figura 13 – Pacote engine.View

class Class Model

Home

- gameIntent: Intent

- optionsIntent: Intent

- settings: SharedPreferences

- gameName: String

+ onCreate(Bundle) : void

+ startGame(String, boolean, int) : void

Option

- settings: SharedPreferences

- spinner: Spinner

- playerName: EditText

+ onCreate(Bundle) : void

+ onSaveInstanceState(Bundle) : void

ScoreBoard

+ onBackPressed() : void

+ onCreate(Bundle) : void

GameRules

+ onCreate(Bundle) : void

+ onBackPressed() : void

Figura 14 - Pacote engine.View (cont.)

Page 45: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

44

A classe Home é responsável por exibir os menus iniciais do aplicativo como pode ser

visto nas figuras 15, 16 e 17. Home, assim como as outras classes que estendem da classe

Activity no projeto, possui uma View e utiliza um XML para definir seu layout, editado

parcialmente no Quadro 12 a partir do arquivo main.xml para corresponder à figura 15, que

descreve a estrutura de componentes e propriedades da tela.

Figura 15 – Tela principal Figura 16 – Tela de

seleção de jogo

Figura 17 – Tela de

seleção de jogadores

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@drawable/bghome">

<Button android:id="@+id/ButtonStart"

android:background="@drawable/btnewgame"

android:layout_centerHorizontal="true"

android:layout_marginTop="50px"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

(...)

<Button android:id="@+id/ButtonQuit"

android:background="@drawable/btquit"

android:layout_below="@id/ButtonOptions"

android:layout_centerHorizontal="true"

android:layout_marginTop="50px"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

</RelativeLayout>

Quadro 12 – XML parcial da tela de entrada

A partir da tela inicial, o jogador tem a opção de acessar as configurações do

aplicativo pelo botão de opções do menu, criando uma instância da classe Option que abre

uma nova View utilizando o layout definido em options.xml. Por outro lado, o jogador pode

Page 46: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

45

optar por iniciar uma nova partida selecionando o jogo desejado e o número de adversários ou

continuando uma partida já existente, criando assim uma nova instância de GameDisplay.

A classe GameDisplay utiliza o arquivo game.xml para definir seu layout e,

diferentemente das Views citadas anteriormente, possui uma View personalizada chamada

GameView. GameView é a principal responsável por desenhar e interagir com o usuário durante

o jogo através dos métodos onDraw e onTouch estendidos das classes View e

onTouchListener respectivamente.

As classes GameRules e ScoreBoard estão disponíveis durante a execução do jogo.

Ao abrir o menu (Figura 18) e o jogador selecionar o botão de regras ou de pontuação. Os

arquivos de layout relacionados a esses dois arquivos são o gamerules.xml e

scoreboard.xml respectivamente.

Figura 18 – Menu de exibição

3.2.2.3 Pacote engine.Control

O pacote engine.Control está dividido em dois grupos, o primeiro composto pelas

classes FPS e Deck (Figura 19), e a segunda composta pelas classes contidas no pacote

engine.GameMode (Figura 20).

Figura 19 – engine.Control

Page 47: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

46

A classe FPS é responsável pela visualização da taxa de quadros por segundo que a

aplicação está executando. Ela é criada e manipulada pela classe engine.View.GameView.

A classe Deck é a responsável por gerenciar todas as cartas que estão no baralho,

mesa, pilha de descartes ou em movimento no jogo, além de ser responsável por produzir o

conjunto de cartas do baralho e efetuar o embaralhamento das cartas.

3.2.2.4 Pacote engine.GameMode

Este pacote faz parte do pacote engine.Control no diagrama de classes por

compartilharem a função de controle e gerenciamento da aplicação, porém dentro do projeto

estão separados para fins de organização.

Neste pacote (Figura 20) estão as classes Game, e Poker que herda as propriedades de

Game. A classe Game é a principal gerenciadora da manipulação das cartas em função das

propriedades do jogo além de efetuar um tratamento específico dos eventos de toque da

aplicação, é a partir desta classe que o desenvolvedor deverá se focar em modificar, pois nela

que as variáveis de jogo são definidas e manipuladas.

A classe Poker herda as propriedades de Game, permitindo personalizar as

propriedades do jogo. Alguns métodos de Game necessitam ser sobrepostos, como o

setValues() que a partir dos valores definidos para o jogo no arquivo attrs.xml, define as

configurações de uso de curingas, quantidade de cartas na mão do jogador ou o uso da pilha

de descartes por exemplo.

Page 48: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

47

Figura 20 – Pacote engine.GameMode

Page 49: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

48

3.2.3 Diagrama de Sequência

O diagrama de sequência da Figura 21 ilustra a interação do Usuário com o protótipo

de pôquer na rotina de jogo descrito no caso de uso UC01.

sd Sequence Model

Usuário

Home GameDisplay GameView Game

onCreate()

startGame(Game,boolean,int)

findViewById(int)

setGame(Game)

onDraw()

onTouch()

betView.setVisibil ity()

initRound()

playerBet(int)

addBet(Player) :boolean

roundWinner()

tierBreaker()

endRound()

Figura 21 – Diagrama de sequência do caso de uso UC01

3.3 IMPLEMENTAÇÃO

A seguir são mostradas as técnicas, as principais rotinas e ferramentas utilizadas na

implementação do motor e no desenvolvimento do protótipo.

Page 50: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

49

3.3.1 Técnicas e ferramentas utilizadas

O desenvolvimento do projeto foi efetuado na linguagem Java utilizando a versão 2.3

da API do Android conhecida como Gingerbread. O ambiente utilizado para o

desenvolvimento da aplicação foi o IDE Eclipse versão Helios junto com o Android SDK e o

Android Development Tools (ADT) for Eclipse. Para efetuar os testes e depuração da

aplicação foi utilizado um simulador disponível no Android SDK em um computador

utilizando as configurações de versão 2.3.3 e também um dispositivo real da marca Samsung

modelo GT-I9100 conhecido como Galaxy S2, que também utiliza a versão 2.3.3 do Android.

O simulador foi testado em dois dispositivos, o primeiro, um desktop com processador

Intel Core 2 Quad Q8300 de 2.5 Giga Hertz (GHz) cada processador, Graphics Processing

Unit (GPU) de 1 Giga Byte (GB), memória Random Access Memory (RAM) de 4GB e

resolução de 1360x768 pixels. Enquanto o segundo foi um notebook Intel i5 M480 com 2

processadores de 2.66GHz, GPU de 1.1GB, 4GB de memória RAM e resolução de 1366x768

pixels.

O dispositivo Samsung GT-I9100 possui um processador modelo ARM Cortex-A9

Dual Core 1.2GHz, GPU Mali-400MP e 1GB de memória RAM e resolução de 480x800

pixels.

3.3.2 Inicialização da partida

As configurações do jogo se iniciam nos menus de seleção do tipo de jogo (Figura 16)

e quantidade de adversários (Figura 17) definidos na função onCreate() da atividade Home e

iniciando com a função startGame(). Esta última função (Quadro 13) recebe como

parâmetros o nome do jogo, se o jogo será continuado ou iniciado novamente e a quantidade

de jogadores que serão inseridos no jogo.

Ao iniciar uma nova partida, as informações do jogo anterior são excluídas da classe

SharedPreferences do aplicativo e grava-se o nome do jogo atual que será inicializado e a

quantidade de jogadores da partida durante a função commit().

Page 51: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

50

Antes de iniciar uma nova instância de jogo, verifica-se se uma instância anterior já

não foi criada, pois caso exista um Intent existente na memória, o aplicativo reaproveita o

espaço e cria uma nova instância por cima da antiga.

public void startGame(String gameName, boolean cont, int players){

if (!cont){

SharedPreferences.Editor editor = settings.edit();

editor.putInt("playerCount",players);

editor.putString("gameName", gameName);

editor.remove("continue");

editor.remove("gameScore");

editor.remove("playersHand");

editor.remove("roundBet");

editor.remove("currentPlayer");

// Commit the edits!

editor.commit();

}

if (gameIntent == null)

gameIntent = new Intent(getWindow().getContext(), GameDisplay.class);

startActivity(gameIntent);

}

Quadro 13 – Inicialização do GameDisplay

Durante a inicialização do GameDisplay, as informações do jogo são recuperados

utilizando a função getSharedPreferences(). A variável settings (Quadro 14) utilizada

na aplicação permite obter os dados armazenados na aplicação utilizando getters dos tipos dos

dados. Cada getter recebe dois valores como parâmetro, o nome da variável a ser recuperada e

o valor padrão caso a variável não exista.

Ainda no Quadro 14, após o nome do jogo ser obtido, através de reflexão cria-se uma

nova instância do jogo referenciado que será inserido dentro do contexto do GameView.

Page 52: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

51

@Override

public void onCreate(Bundle state) {

super.onCreate(state);

settings = getSharedPreferences(Constants.PREF_FILE, 0);

// Recovers the values defined by the user, or get default values

int color = settings.getInt("CardBg", 0);

String playerName = settings.getString("PlayerName","Player 1");

String gameName = settings.getString("gameName", "");

boolean isContinue = settings.getBoolean("continue", false);

int count = settings.getInt("playerCount",1);

(...)

if (gameName != ""){

try {

Class<?> c = Class.forName("engine.GameMode."+gameName);

game = (Game) c.newInstance();

} catch (Exception e){

e.printStackTrace();

}

}

setContentView(R.layout.game);

gameView = (GameView) findViewById(R.id.gameView);

if (count > 1) game.players.add(new Player("CPU"));

if (count > 2) game.players.add(new Player("CPU2"));

if (count > 3) game.players.add(new Player("CPU3"));

gameView.game = game;

gameView.setGame();

}

Quadro 14 – Inicialização de variáveis do jogo

Após a inicialização do GameView através da função findViewById(), esta nova View

recebe através da função setGame() (Quadro 15) o jogo criado pela atividade e a partir desta

função o jogo é inicializado. Nesta função primeiramente o jogo consulta as configurações

definidas no arquivo attrs.xml e inicializando a pontuação do jogador e criando um novo

baralho como pode ser visto no Quadro 16.

public void setGame(){

game.setValues(getResources());

// On creating view, the size is not set yet

Display display = ((WindowManager)

getContext().getSystemService(Context.WINDOW_SERVICE))

.getDefaultDisplay();

if (display.getWidth() > display.getHeight()){

game.HEIGHT = display.getHeight();

game.WIDTH = display.getWidth();

} else {

game.HEIGHT = display.getWidth();

game.WIDTH = display.getHeight();

}

if (game.autoDraw){

time = SystemClock.uptimeMillis();

}

game.initRound();

}

Quadro 15 – setGame()

Page 53: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

52

Após as configurações do jogo serem definidas, é necessário obter as dimensões da

tela do dispositivo para permitir que os elementos do jogo sejam posicionados corretamente

na tela. Neste momento ainda é necessário criar um objeto da classe Display para obter as

dimensões de tela, pois a View somente terá um tamanho após a chamada da função

onDraw(). Após esta chamada, as dimensões da tela podem ser obtidas através dos métodos

getHeight() e getWidth(), devido na especificação do layout, esta View está definida com

as propriedades layout_width=”match_parent” e layout_height=”match_parent” que

determinam que a View ocupe todo o espaço da tela.

Caso o jogo esteja configurado com o valor autoDraw igual a true, a variável time é

inicializado para começar a contagem de tempo entre a distribuição de cartas, este tempo

definido na constante DRAWTIME inserido na classe Constants.

Por fim, a View chama a função initRound(), responsável por efetuar a inicialização

das variáveis utilizadas em cada rodada do jogo, verificando a disponibilidade dos jogadores e

iniciar a distribuição de cartas caso a variável autoDraw estiver ativa.

@Override

public void setValues(Resources res){

// Obtain values from res/values/attrs.xml

super.deckType = res.getInteger(R.PokerVars.deck_type);

super.playerMoney= res.getInteger(R.PokerVars.player_money);

super.joker = res.getBoolean(R.PokerVars.joker);

super.bet = res.getBoolean(R.PokerVars.bet);

super.autoDraw = res.getBoolean(R.PokerVars.auto_draw);

super.upcard = res.getBoolean(R.PokerVars.upcard);

super.minPlayers = res.getInteger(R.PokerVars.min_players);

super.maxPlayers = res.getInteger(R.PokerVars.max_players);

super.handLimit = res.getInteger(R.PokerVars.hand_limit);

super.restart_on_end = res.getBoolean(R.PokerVars.restart_on_end);

for (Player p : players){

p.coins = super.playerMoney;

}

deck = new Deck(joker,deckType);

for(Card card : deck.deck){

card.id=res.getIdentifier(card.getImage(),"drawable","engine.View");

}

deck.sort();

}

Quadro 16 – Definindo as propriedades do jogo

A função setGame() descrita na classe Game, deve ser sobrescrita nas classes

específicas que herdam desta classe como efetuado na classe Poker exibida no Quadro 16.

Nesta função, atribui-se para suas variáveis os valores do tipo PokerVars, descrito na seção

anterior, inicializa-se o baralho, define-se o id da imagem que cada carta possui e por fim

embaralha-se o baralho.

Page 54: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

53

Ao distribuir as cartas para os jogadores, a rotina descrita no Quadro 17 se encarrega

de contar a quantidade de cartas que devem ser distribuídas para cada jogador e multiplicadas

pela quantidade de jogadores presentes. Com este valor, cada carta é retirada do baralho é

inserida em uma fila. Utilizando-se sua posição na fila, determina-se o destino para qual esta

carta deverá se movimentar e qual o ângulo final que a carta deverá rotacionar. Após

concluída a geração da fila, a primeira carta é retirada da fila e inserida no vetor de cartas em

movimento.

int limit = handLimit * players.size();

for (i = 0; i < limit; i++){

Card card = deck.push();

if (card == null)break;

setCardPosition(card);

toMove.add(card);

players.get(i%players.size()).hand.add(card);

}

deck.moving.add(toMove.remove(0));

Quadro 17 – Rotina de distribuição das cartas

3.3.3 Algoritmos gráficos

Devido à disponibilidade de se utilizar imagens pré-desenvolvidas para serem

desenhadas na aplicação, decidiu-se por utilizar os métodos de desenho na tela a partir de

Bitmaps.

Esta seção trata das classes Game e GameView que são as responsáveis pelo processo de

animação das cartas durante o jogo, sendo a primeira responsável pela alteração na transição e

rotação das cartas e a segunda efetua o desenho do Bitmap na tela a partir dos parâmetros

configurados no jogo.

Quando uma nova instância da classe GameView é chamada na atividade GameDisplay, a

partir das variáveis disponíveis no momento, a classe chama a função onDraw() (Quadro 18) para

desenhar os elementos na tela. Porém por padrão as Views somente redesenham a tela caso seja

necessário (ao recuperar o foco na aplicação por exemplo). Então para garantir que a tela se mantenha

sendo redesenhada constantemente, foi inserido a função update() no final do onDraw() que por

sua vez ao finalizar sua execução invoca a função invalidate() que informa ao sistema que a tela

precisa ser redesenhada, criando assim um ciclo de desenho e atualização constante enquanto a

atividade estiver em foco.

Page 55: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

54

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (drawMode == GAME_MODE){

game.update();

}

(...)

update();

}

public void update() {

if (game.toMove.size() > 0){

long now = SystemClock.uptimeMillis();

if (now - time > Constants.DRAWTIME){

time = SystemClock.uptimeMillis();

game.deck.moving.add(game.toMove.remove(0));

}

}

fps.update();

invalidate();

}

Quadro 18 – Ciclo de desenho

O valor drawMode por padrão inicia com o valor GAME_MODE que significa que o jogo

está em execução e as cartas precisam ser atualizadas caso necessário. Enquanto estiver em

execução, é chamada a função update() do jogo que é responsável por alterar a posição x e

y e ângulo das cartas em movimento. No Quadro 19, parte da rotina update() é exibida onde

inicialmente, as variáveis moveX e moveY calculam a distância entre o ponto de origem das

cartas, no caso o baralho, até o seu destino, valores toX e toY. Com base na maior distância,

os movimentos de rotação e translação serão escalados para proporcionar uma animação mais

suave, tendo como base o valor de movimento em pixels definido na constante

Constants.CARDMOVE. Ao movimentar a carta, caso o próximo movimento x,y ou angular for

menor que a distância até o destino, a posição da variável será substituída pelo valor de

destino, evitando assim que os valores passem do objetivo.

Page 56: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

55

for (Card current : deck.moving){

moveY = Math.abs(current.toY-startPos.top);

moveX = Math.abs(current.toX-startPos.left);

if (moveX < moveY){

move = (float) Math.floor(moveY/Constants.CARDMOVE);

} else {

move = (float) Math.floor(moveX/Constants.CARDMOVE);

}

if (current.toAngle != current.angle){

if (current.angle < current.toAngle){

current.angle += current.toAngle/move;

} else {

current.angle -= Math.abs(current.toAngle)/move;

}

if (Math.abs(current.toAngle-current.angle) <= Constants.CARDMOVE){

current.angle = current.toAngle;

}

}

if (moveX > moveY){

move = Constants.CARDMOVE/(moveX/moveY);

} else {

move = Constants.CARDMOVE;

}

if (current.y != current.toY){

if (current.toY < 0 && current.y - move > current.toY)

current.y -= move;

else if (current.toY > 0 && current.y + move< current.toY)

current.y += move;

if (Math.abs(current.toY-current.y) <= Constants.CARDMOVE)

current.y = current.toY;

}

(...)

Quadro 19 – Atualização da posição das cartas

Após cada carta em movimento ser reposicionada, é feita uma verificação (Quadro 20)

se a posição atual da carta é a posição de destino. Caso afirmativo, a carta é exibida se ela

veio do baralho, ou é escondida caso ela venha da mão do jogador. Ao chegar à posição final,

a carta é inserida num vetor de cartas a serem removidas da lista de movimentações que ao

final do ciclo de verificação de cartas a serem movimentadas, excluirá da lista as que já

chegaram a seu destino.

if ((current.y == current.toY) && (current.x == current.toX)){

current.visible = (!current.visible);

removed.add(current);

}

(...)

if (removed.size() > 0)

deck.moving.removeAll(removed);

Quadro 20 – Verificação de posição

Com as cartas devidamente posicionadas, cabe à View desenhá-las na tela na função

onDraw(). O trecho descrito no Quadro 21 descreve como cada carta em movimento é

Page 57: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

56

desenhada na tela durante a partida. Para cada carta, primeiramente é verificado se ela já

possui um id de desenho, caso negativo, busca-se nos recursos do sistema, o id relacionado ao

nome da imagem que a carta necessita6. Após essa verificação, caso o valor de i seja igual a

zero e a carta estiver visível, cria-se um Bitmap baseado no id da carta, caso contrário, o verso

da carta, que foi previamente definido, será exibido.

// Draw the moving cards

for(Card c : game.deck.moving){

if (c != game.selected && c != null){

if (c.id == 0){

c.id = getResources().getIdentifier(c.getImage(), "drawable",

"engine.View");

}

if (c.visible && i == 0){

card = BitmapFactory.decodeResource(getResources(),c.id);

} else {

card = bg;

}

if (c.angle != 0){

Matrix matrix = new Matrix();

matrix.preTranslate(c.x, c.y);

matrix.postRotate(c.angle, c.x + (Constants.CARD_WIDTH/2), c.y +

(Constants.CARD_HEIGHT/2));

canvas.drawBitmap(card, matrix, mPaint);

} else {

canvas.drawBitmap(card, c.x, c.y, mPaint);

}

}

i++;

}

Quadro 21 – Ciclo de desenho de cartas em movimento

Para desenhar a carta, após o Bitmap desta ser definido, primeiro é verificado se esta

carta está rotacionada ou não. Caso esteja, é necessário criar uma matriz definindo sua

posição x e y com a função preTranslate(), e rotacionando-a com a função postRotate()

que recebe como parâmetros o ângulo da imagem e sua posição x e y de centro da imagem.

Caso os valores de centro da imagem não forem informados, a imagem irá rotacionar em

relação ao ponto (0,0) da tela, proporcionando um resultado indesejável para a situação. Com

a matriz configurada, a função canvas.drawBitmap(), se encarregará de desenhar a imagem

baseado nas informações da matriz.

Se a carta não necessitar ser rotacionada, a função drawBitmap() receberá nos

parâmetros, o Bitmap a ser desenhado e sua posição na tela sem necessidade de mais

tratamentos.

6 c.getImage()

busca na classe Card o nome do arquivo a ser utilizado baseando no valor e

naipe desta carta.

Page 58: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

57

3.3.4 Algoritmos de controle

Além da inicialização e rotinas de desenho, algumas rotinas de controle são

fundamentais para o funcionamento do aplicativo sendo elas a função onBackPressed(), que

sobrescreve o comportamento do aplicativo ao pressionar o botão ―back” do dispositivo, a

função onTouch(), disparada quando o usuário interage com a tela, onPause(), disparado

quando a aplicação por algum motivo perde o foco, as rotinas de apostas e a verificação do

vencedor da rodada roundWinner(), definida na classe Poker.

3.3.4.1 onBackPressed()

O botão back, por padrão, permite ao usuário navegar entre atividades de forma rápida.

Porém, como explicado na seção 2.4, ao pressionar o botão back, a atividade atual é destruída

e a próxima atividade da pilha é carregada. Dependendo da forma que a atividade foi

construída, este comportamento não é desejado em algumas ocasiões, por exemplo, quando

em uma atividade múltiplas Views são utilizadas, ao exibir uma nova View por cima da inicial

é natural que o usuário deseje retornar à View anterior ao pressionar o botão back. Em

situações normais, isso não acontecerá e em vez disso, a atividade será destruída.

No projeto desenvolvido neste trabalho, a atividade GameDisplay possui duas camadas

de telas, sendo a primeira a tela de jogo, onde as cartas são distribuídas e desenhadas, e uma

segunda quando o botão de apostas é pressionado e uma nova camada é desenhada por cima

exibindo os botões de seleção de apostas. Para evitar que o jogo termine quando o usuário

pressiona o botão back durante a tela de apostas está sendo desenhada, a atividade sobrescreve

essa função (Quadro 22) permitindo que ao pressionar o botão, a tela de apostas seja

escondida e retorne ao jogo.

@Override

public void onBackPressed (){

if (gameView.drawMode == GameView.BET_MODE){

gameView.drawMode = GameView.GAME_MODE;

gameView.betView.setVisibility(View.GONE);

} else {

super.onBackPressed();

}

}

Quadro 22 – Função onBackPressed()

Page 59: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

58

3.3.4.2 onTouch()

Ao implementar a classe OnTouchListener na classe GameView, é necessário

sobrescrever a função onTouch() que responde pelos eventos de toque do usuário na tela. A

função recebe como parâmetro o evento MotionEvent que permite extrair os valores x e y da

tela onde o evento foi disparado e o tipo de ação efetuado, sendo as ações utilizadas na

implementação a ACTION_DOWN, ACTION_UP e ACTION_MOVE.

Quando a ação ACTION_DOWN é disparada (Quadro 23), uma área retangular relativa ao

ícone de apostas é criada, e utilizando a função contains() da classe Rect, é verificado se as

coordenadas x e y do evento de toque estão dentro da área do ícone. Esta função retorna true

caso as coordenadas estejam dentro da área ou acima da fronteira lateral esquerda ou superior,

enquanto retorna false caso estejam fora da área ou acima das fronteiras inferior e lateral

direito.

int actionCode = event.getAction() & MotionEvent.ACTION_MASK;

if (actionCode == MotionEvent.ACTION_DOWN) {

int posX = (int) event.getX();

int posY = (int) event.getY();

if (game.bet){

Bitmap icon =

BitmapFactory.decodeResource(getResources(),R.drawable.icocoins);

Rect betIcon = game.position(game.betPos, icon.getHeight(),

icon.getWidth());

if (betIcon.contains(posX, posY)){

this.drawMode = BET_MODE;

for (int i = game.current; i > 0; i = (i+1)%game.players.size()){

if (game.addBet(game.players.get(i))){

currentBet = game.result + currentBet;

}

}

}

betText.setText(currentBet);

betView.setVisibility(View.VISIBLE);

}

} (...)

Quadro 23 – Verificação do botão de apostas

Caso o botão de apostas for pressionado e não seja a vez do jogador, as apostas dos

jogadores anteriores a ele serão efetuadas e a tela de apostas se torna visível.

Ao disparar o evento de toque, as classes de jogo também são notificadas, sendo estas

responsáveis por verificar se a coordenada onde o usuário pressionou consta alguma de suas

cartas na mão permitindo assim que a carta seja selecionada e enquanto não for solta, o

usuário poderá movê-la na tela. Ao disparar a ação ACTION_UP, caso a classe de jogo tenha

Page 60: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

59

regiões definidas, o desenvolvedor poderá configurar para a carta ser inserida e posicionada

neste lugar, a mesa de jogo ou a pilha de descartes por exemplo.

3.3.4.3 onPause()

Quando a atividade ou aplicação é destruída, movida de posição na pilha de atividades

ou perca o foco por algum outro motivo como o dispositivo entrar em modo de repouso, antes

disso o sistema chama a função onPause() junto com uma série de outros comandos padrões

do sistema operacional. Neste momento é interessante que o aplicativo salve as informações

do jogo de forma que quando a atividade seja restaurada, seja possível continuar o jogo do

ponto onde ele foi interrompido.

O Quadro 24 demonstra como a aplicação armazena as variáveis do jogo na classe

SharedPreferences que serão carregadas novamente na inicialização da atividade. O editor

somente permite armazenar um conjunto limitado de tipos de dados (boolean, integer, String,

float e long), sendo assim necessário armazenar os dados de forma que seja possível recuperar

e tratar os dados posteriormente.

Page 61: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

60

@Override

public void onPause(){

// Save game status

SharedPreferences.Editor editor = settings.edit();

String score = "";

String hands = "";

String names = "";

String handCards = "";

for (Player p : game.players){

handCards = "";

score += (score != "") ? ",":"";

score += p.coins;

for (Card c : p.hand){

handCards += (handCards != "") ? ",":"";

handCards += c.value + "-" + c.suit;

}

hands += (hands != "") ? "@":"";

hands += handCards;

names += (names != "") ? ",":"";

names += p.name;

}

editor.putBoolean("continue",true);

editor.putString("gameScore", score);

editor.putString("playersName",names);

editor.putString("playersHand",hands);

editor.putString("gameName", game.getClass().getSimpleName());

editor.putInt("roundBet", game.currentBet);

editor.putInt("currentPlayer", game.current);

editor.commit();

super.onPause();

}

Quadro 24 – onPause()

3.3.4.4 roundWinner()

Na partida de pôquer desenvolvida no protótipo, foi elaborada uma rotina de avaliação

das cartas da mão de cada jogador permitindo assim estimar o peso que suas cartas têm na

rodada. Para se obter o resultado esperado, a função pode ser separada em várias etapas que

permitem filtrar as possíveis combinações de cartas do jogo.

Inicialmente as cartas do jogador são ordenadas pelo valor de suas cartas utilizando a

função sort() (Quadro 25) da classe Collections que segundo Android Developers (2011),

utiliza um algoritmo similar ao MergeSort obtendo assim no pior caso, um gasto proporcional

a n Log n interações.

Page 62: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

61

(...)

ArrayList<Card> cards = (ArrayList<Card>) p.hand.clone();

// Optimized ArrayList sorter using java MergeSort

Collections.sort(cards,new Comparator<Card>(){

public int compare(Card card, Card card2) {

return (card.value > card2.value) ? 1:-1;

}

}

);

(...)

Quadro 25 – MergeSort de cartas

Após as cartas estarem ordenadas utiliza-se um laço for para verificar se as cartas da

mão do jogador estão na sequência e se possuem o mesmo naipe. Com esta verificação, o jogo

identifica se o jogador possui a sequência Royal Flush, Straight ou Flush concluindo a

verificação nestes casos.

Caso o jogador não possua nenhuma das sequências anteriores, um vetor de 14

posições é criado para armazenar quantas cartas de cada valor foram encontradas. Após

armazenar os valores no vetor, é verificado se algum dos índices do vetor possui dois ou mais

valores armazenados nele, determinando assim caso o jogador possua uma quadra, trinca ou

dupla de cartas. Se a mão do jogador não se enquadrar em nenhuma das regras anteriores,

serão consideradas as cartas de maior valor que o jogador possui.

Os valores definidos na aplicação para distinguir o peso da sequência de cartas do

jogador podem ser visualizados no Quadro 26. Caso haja empate na pontuação de dois ou

mais jogadores, a função tierBreaker() analisa o valor das cartas dos jogadores empatados

e define o jogador baseado em quem tiver as cartas com maior valor. Em caso de empate

técnico, os jogadores tiverem as cartas de mesmo valor, o jogo considera empate e divide o

valor da aposta entre os empatados.

private static final int PAIR = 200;

private static final int TWO_PAIRS = 300;

private static final int THREE_OF_A_KIND = 400;

private static final int STRAIGHT = 500;

private static final int FLUSH = 600;

private static final int FULL_HOUSE = 700;

private static final int FOUR_OF_A_KIND = 800;

private static final int STRAIGHT_FLUSH = 900;

private static final int ROYAL_FLUSH = 1000;

Quadro 26 – Lista de pontuações do jogo de pôquer

Page 63: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

62

3.3.5 Operacionalidade da implementação

A operacionalidade da aplicação desenvolvida a partir do motor será apresentada

através de imagens na forma de funcionalidades e casos de uso. As imagens utilizadas foram

retiradas diretamente do dispositivo GT-I9100 através do aplicativo ddms.bat disponível

junto com o conjunto de ferramentas do Android SDK.

A aplicação possui uma tela inicial apresentada anteriormente na Figura 15 onde há

quatro opções disponíveis, sendo a primeira a de início de novo jogo que ao clicá-la, a tela é

alterada para a Figura 16 onde é possível selecionar um dos jogos disponíveis no aplicativo.

Ao selecionar um jogo da listagem, caso este jogo permita alterar a quantidade de jogadores,

será exibida a tela de seleção de jogadores como pode ser visto na Figura 17.

Na tela de entrada ainda há a opção de continuar um jogo já existente caso este não

tenha sido finalizado com sucesso (em caso de vitória ou derrota do jogador), a opção de

modificar as configurações do jogo como pode ser visto na Figura 22 onde o jogador poderá

alterar seu nome de jogo e a cor do verso das cartas (Figura 23). Por fim o último botão na

tela de entrada finaliza o aplicativo.

Figura 22 – Tela de opções Figura 23 – Listagem de cores

Ao iniciar uma nova partida ou continuar uma partida existente, uma tela parecida com

a da Figura 24 será apresentada (no caso do jogo de pôquer). Nesta tela o jogador poderá abrir

o menu do jogo utilizando o mesmo botão de menu do dispositivo (Figura 18), ou clicar nas

fichas no canto inferior direito da tela onde será exibida a tela de apostas do jogo (Figura 25).

Page 64: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

63

Figura 24 – Tela de jogo

Figura 25 – Opções de apostas

Na Figura 25 a opção ―Raise‖ aumenta o valor da aposta, levando para a tela ao lado

onde é possível selecionar os valores disponíveis para o aumento da aposta. Caso o jogador

não possua dinheiro suficiente para aumentar a aposta, este botão estará indisponível. A opção

―Call‖ cobre o valor do ultimo aumento da aposta e somente está disponível caso algum

jogador antes tenha aumentado a aposta. Já a opção ―Check‖ mantém o valor da aposta como

está desde que o valor da aposta não tenha sido modificado na rodada atual. A opção ―Fold‖

efetua a desistência do jogador da rodada, não permitindo assim que este participe da

avaliação do vencedor da rodada. O botão ―Back‖ tem dois comportamentos diferentes

dependendo de quais botões estão visíveis, caso os botões de valores da aposta estiverem

visíveis, retorna aos botões anteriores, caso contrário a tela de apostas será fechada.

Ao aumentar aposta serão verificadas as ações dos outros jogadores e caso não haja

mais aumentos, a rodada será finalizada, e o jogador com o melhor conjunto de cartas

receberá o valor das apostas na mesa.

A partir do menu (Figura 18), o jogador poderá selecionar uma das três opções

disponíveis, a primeira de regulamento, irá abrir a tela mostrada na Figura 26. A segunda

opção de pontuação irá exibir a tela da Figura 27, enquanto a terceira opção de sair do jogo

finalizará o jogo e retornará para a tela de seleção de jogadores (Figura 17).

Page 65: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

64

Figura 26 – Regulamentos do jogo

Figura 27 – Pontuação do jogo

3.4 RESULTADOS E DISCUSSÃO

Este trabalho trouxe como principal desafio, o entendimento das diferenças de

abordagem entre a linguagem Java tradicional para o desenvolvido na plataforma Android.

Devido à limitação de hardware e a preocupação com o desempenho da aplicação, por várias

vezes foram encontradas dificuldades em manter o funcionamento da aplicação a uma taxa de

atualização de quadros viável, sendo os conselhos sugeridos por Android Developers (2011),

muito úteis durante o desenvolvimento da aplicação.

Uma das dificuldades encontradas na elaboração do trabalho foi em relação à

explicação formal de parte dos desenvolvedores da plataforma em relação a alguns conceitos,

sendo eles mais focados em passar uma visão geral dos recursos e aprofundando na

documentação da linguagem. Ocorreram algumas dificuldades ao utilizar alguns métodos e

atributos devido à utilização de rotinas desaconselhadas pelos desenvolvedores, tais como o

problema de falta de memória utilizando o laço for utilizando uma variável de tamanho

sendo solucionado trocando estes for pelo laço for-each em todas situações disponíveis. Um

detalhe importante que durante a implementação não foi lembrado foi que ao utilizar a rotação

das cartas na tela, por padrão as matrizes são rotacionadas utilizando o ponto zero da View,

efetuando um efeito diferente do esperado quando inserido junto a um efeito de translação da

matriz. A especificação não é clara neste aspecto, mas é possível resolver este problema

passando parâmetros adicionais de x e y para definir o centro de rotação da matriz. Porém em

Page 66: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

65

contra partida, quando a documentação não parece clara o suficiente, é possível encontrar

através da internet a solução muitas vezes fornecida para outros desenvolvedores com a

mesma dificuldade, sendo assim possível resolver problemas com certa facilidade.

Mesmo que o simulador seja uma boa saída para testar o aplicativo, sua taxa de

desempenho gráfico é muito inferior a de um dispositivo real. A Tabela 1 ilustra a diferença

da taxa de quadros entre o dispositivo e os simuladores utilizados.

Tabela 1 – Média de quadros por segundo (fps)

2 Jogadores 3 Jogadores 4 Jogadores

GT-I9100 35 33 33

Desktop 6.5 6 5.5

Notebook 5 3.5 3.5

A utilização de arquivos XML permite ao desenvolvedor uma maior transparência no

desenvolvimento de um projeto, permitindo assim que seja possível alterar as configurações

do jogo sem a necessidade de se preocupar tanto com a programação em si.

Mesmo com o grande avanço na tecnologia para os dispositivos móveis, a mesma

preocupação devido à limitação de recursos do aparelho encontrada por Pamplona (2005)

ainda existe. Não há dúvidas que os avanços dos últimos anos permitiram ao desenvolvedor

uma maior liberdade para utilizar mais recursos computacionais devido às melhorias dos

dispositivos permitindo assim um melhor resultado para o usuário final.

Assim como o trabalho de Takano (2009), este trabalho se focou no resultado gráfico

da aplicação, não sendo utilizadas rotinas complexas para tratamentos de física dos objetos,

porém, assim como o trabalho dele, houve uma preocupação em relação à interação do

usuário com a interface do aplicativo através de toques.

Apesar de utilizar a linguagem Java assim como Pamplona (2005), há algumas

diferenças em relação ao Java para o Android, sendo este último otimizado para essa

plataforma de forma que haja um melhor resultado de desempenho dado os recursos

disponíveis em cada aparelho. Porém, a preocupação com o consumo de recursos, como a

memória e processamento, ainda existe e afeta diretamente na durabilidade da bateria do

dispositivo.

O protótipo ocupa aproximadamente 1.13 MB de memória sendo dessas sua maior

parte utilizada para armazenar arquivos de imagem e de mídia. Os dados armazenados na

memória através da classe SharedPreferences ocupam cerca de 4KB.

Page 67: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

66

4 CONCLUSÕES

Este trabalho apresentou a implementação de um motor de jogos de cartas na forma de

uma biblioteca de funções dividida em várias atividades com funções específicas. As classes

implementadas permitiram manipular os recursos gráficos da aplicação e a configuração do

jogo de forma mais simplificada utilizando recursos provenientes de arquivos XML. Desta

forma, foi possível concluir todos os objetivos propostos no trabalho.

Este trabalho disponibiliza um conjunto de funções e conceitos que permitem ao

desenvolvedor entender melhor o desenvolvimento de aplicativos na plataforma e a facilitar o

desenvolvimento de outros jogos de cartas reaproveitando a lógica das funções aqui

apresentadas.

O aplicativo desenvolvido apresentou algumas semelhanças com alguns dos trabalhos

correlatos em relação ao tratamento de controle de cena ao receber um evento de toque na

tela, no modelo de estrutura utilizado (MVC) e no conceito de auxiliar o desenvolvedor no

entendimento do ambiente e disponibilizando recursos para o desenvolvimento de um novo

aplicativo.

A plataforma Android disponibiliza através de sua API uma série de classes e funções

que permitem ao desenvolvedor interagir de muitas formas com os dispositivos onde suas

aplicações irão rodar, permitindo tanto a interação com hardware como com outros softwares

se estes permitirem o acesso para tal.

As ferramentas disponíveis pelo Android SDK facilitam muito para o desenvolvedor

efetuar seus testes utilizando um dispositivo virtual, utilizar o modo debug tanto no simulador

como no dispositivo ou salvar imagens da tela do dispositivo.

Page 68: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

67

4.1 EXTENSÕES

O protótipo desenvolvido foi projetado de forma que somente um usuário possa jogar o

jogo por vez. Explorando as técnicas de redes e protocolos, sugere-se que o aplicativo seja

estendido para o modo multiplayer, permitindo assim que vários jogadores com seus

dispositivos em rede local ou pela internet possam participar de uma mesma partida. Com esta

implementação, sugere-se que seja implementado também, uma pontuação online e ranking,

permitindo uma maior competição entre os jogadores.

Este trabalho poderia ter explorado ainda mais a fundo a utilização de XMLs para

tornar o aplicativo mais dinâmico, pois há muitos outros recursos disponíveis na plataforma

através deles, porém este estudo fica como sugestão para trabalhos futuros.

Page 69: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

68

REFERÊNCIAS BIBLIOGRÁFICAS

ANDROID DEVELOPERS. The developer’s guide, [S.l.], 2011. Disponível em:

<http://developer.android.com/guide/ >. Acesso em: 15 mar. 2011.

______. Dalvik JIT. [S.l.], 2010. Disponível em: <http://android-

developers.blogspot.com/2010/05/dalvik-jit.html>. Acesso em: 17 mar. 2011.

GENKISTAR. Poker gratuit, [S.l.], 2011. Disponível em: <http://www.genkistar.com/>.

Acesso em: 26 set. 2011.

GREGORY, Jason; LANDER, Jeff. Game engine architecture. Wellesley: A. K. Peters,

2009.

HAVOK INC. Available games. [S.l.], 2011a. Disponível em:

<http://www.havok.com/ndex.php?page=available-games>. Acesso em: 22 mar. 2011.

______. Havok product family. [S.l.], 2011b. Disponível em:

<http://www.havok.com/index.php?page=products>. Acesso em: 26 mar. 2011.

______. Product screenshots. [S.l.], 2011c. Disponível em:

<http://www.havok.com/índex.php?page=physics-screenshots>. Acesso em: 26 mar. 2011.

JOGATINA. A história do baralho – os dias de hoje. [S.l.], 2009. Disponível em:

<http://blog.jogatina.com/archives/a-historia-do-baralho-os-dias-de-hoje/>. Acesso em: 27

set. 2011.

JOGOS DE CARTAS. Jogos de cartas - o mundo das cartas em suas mãos. [S.l.], 2007.

Disponível em: <http://jogosdecartas.hut.com.br/>. Acesso em: 27 set. 2011.

PAMPLONA, Vitor F. Um protótipo de motor de jogos 3D para dispositivos móveis com

suporte a especificação móbile 3D Graphics API for J2ME. 2005. 83 f. Trabalho de

Conclusão de Curso (Bacharelado em Ciências da Computação) – Centro de Ciências Exatas

e Naturais, Universidade Regional de Blumenau, Blumenau.

SCHUYTEMA, Paul; MANYEN, Mark. Game development with LUA. Hingham: Charles

River Media, 2005.

TAKANO, Rafael H. MJ3I: um motor de jogos 3D para o iPhone OS. 2009. 52 f. Trabalho

de Conclusão de Curso (Bacharelado em Ciências da Computação) – Centro de Ciências

Exatas e Naturais, Universidade Regional de Blumenau, Blumenau.

Page 70: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

69

UOL TECNOLOGIA. Venda de smartphones deve superar a de computadores no Brasil

em 2011, diz IDC. [S.l.], 2011. Disponível em: <http://tecnologia.uol.com.br/ultimas-

noticias/redacao/2011/02/17/venda-de-smartphones-deve-superar-a-de-computadores-no-

brasil-em-2011-diz-idc.jhtm>. Acesso em: 11 mar. 2011.

VELDHUIZEN, Bart. Game engine. Amsterdam, [2010a?]. Disponível em:

<http://www.blender.org/education-help/tutorials/game-engine/>. Acesso em: 22 mar. 2011.

______. Features. Amsterdam, [2010b?]. Disponível em: <http://www.blender.org/features-

gallery/features/>. Acesso em: 26 mar. 2011.

WARD, Jeff. What is a game engine? [S.l.], abr. 2008. Disponível em:

<http://gamecareerguide.com/features/529/what_is_a_game_.php>. Acesso em: 20 mar. 2011.

Page 71: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

70

ANEXO A – UC01 - Iniciar a partida

O caso de uso ilustrado no Quadro 27 descreve como o Usuário interage com o jogo

selecionado no protótipo em seu dispositivo real.

UC01 – Iniciar a partida

Descrição Este caso de uso descreve os procedimentos que o Usuário

deve seguir para iniciar uma partida de pôquer e finalizar uma

rodada.

Pré-condição Possuir o aplicativo instalado no dispositivo.

Cenário principal 1. O Usuário seleciona a opção de novo jogo (Figura 15).

2. A aplicação lista os jogos disponíveis (Figura 16).

3. O Usuário seleciona um modo de jogo.

4. A aplicação exibe a quantidade de adversários disponíveis

(Figura 17).

5. O Usuário seleciona quantos adversários deseja enfrentar.

6. A partida é iniciada e as cartas são distribuídas para os

jogadores.

7. O Usuário seleciona o valor da aposta.

8. Os adversários selecionam manter o valor da aposta.

9. A aplicação avalia a maior pontuação da rodada.

10. O jogador que ganhar a rodada recebe o valor da aposta.

11. Nova rodada se inicia.

Cenário alternativo 1 No passo 4, caso a partida não permita adversários, pular para o

passo 6.

Cenário alternativo 2 No passo 7, caso o usuário selecione aumentar o valor da

aposta, os adversários podem manter o valor da aposta ou aumentar novamente.

2.1. Se todos os adversários selecionarem manter o valor da

aposta, pular para o passo 9.

2.2. Caso algum dos adversários selecione aumentar a aposta, a

rodada de apostas continua enquanto não chegar a quatro

aumentos nas apostas ou concluir a rodada de apostas. Voltar para o passo 7.

Cenário alternativo 3 No passo 10, caso haja empate entre dois ou mais jogadores, o

valor da aposta é dividido entre os vencedores.

Pós-condições O Usuário pode finalizar o jogo ganhando ou perdendo de seus

adversários, encerrando a partida ou saindo da aplicação e iniciando nova partida.

Quadro 27 – Caso de uso UC01

Page 72: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

71

ANEXO B – UC02 - Alterar as configurações de jogo

Este caso de uso ilustrado no Quadro 28 descreve como o Usuário pode interagir com

as opções disponíveis na aplicação, opções estas que não interferem no funcionamento do

jogo.

UC02 – Alterar as configurações do jogo

Descrição Algumas propriedades dos jogos podem ser alteradas, como o nome

do jogador ou o verso das cartas, este caso de uso descreve os passos desta alteração.

Pré-condição Possuir o aplicativo instalado no dispositivo.

Cenário principal 1. O Usuário seleciona a opção de opções (Figura 22).

2. A aplicação lista as opções disponíveis (Figura 23).

3. O Usuário altera seu nome de exibição.

4. O Usuário finaliza as alterações e pressiona o botão de retornar.

Cenário alternativo 1 O passo 3 é opcional, por padrão o aplicativo inicia com o nome

―Player 1‖.

Cenário alternativo 2 No passo 3 o Usuário pode optar por alterar a cor do verso das

cartas que será utilizada (Figura 23) que por padrão inicia-se com a

cor preta.

Pós-condições As configurações do aplicativo serão salvas e carregadas nas

partidas posteriores.

Quadro 28 – Caso de uso UC02

Page 73: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

72

ANEXO C – UC03 - Selecionar as opções de jogo

Neste caso de uso detalhado no Quadro 29, o Usuário interage com o menu do jogo

(Figura 24) ao pressionar o botão de menu do dispositivo durante a partida.

UC03 – Selecionar as opções do jogo

Descrição Este caso de uso descreve as opções padrões disponíveis no motor

que são acessadas quando o jogador pressiona o botão menu do dispositivo.

Pré-condição A tela de jogo estar visível e o menu do dispositivo ser pressionado.

Cenário principal 1. O jogador pressiona o botão de regras.

2. A aplicação exibe em nova tela os regulamentos do jogo (Figura

26).

3. O jogador pressiona o botão de retornar ou o botão back.

4. A aplicação retorna para a tela anterior e exibe novamente o

menu.

Cenário alternativo 1 No passo 1 o Usuário pode optar por pressionar o botão de

pontuação da partida.

1.1. A aplicação exibe nova tela contendo em ordem de pontos o

nome dos jogadores participantes e sua pontuação atual (Figura 27).

Cenário alternativo 2 No passo 6 o Usuário pode optar por pressionar o botão de sair da partida.

2.1. A partida se encerra e a aplicação retorna para a tela de seleção

de jogos.

Pós-condições Após a navegação no menu, o Usuário pode por pressionar o botão

back ou o botão menu para retornar à partida.

Quadro 29 – Caso de uso UC03

Page 74: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

73

ANEXO D – UC04 - Distribuir as cartas

Este caso de uso é necessário para os jogos onde a distribuição das cartas não é

automática sendo esta decisão dependente do desenvolvedor, e descreve a reação do sistema

quando a imagem do baralho é pressionada durante o jogo, como pode ser visto no Quadro

30.

UC04 – Distribuir as cartas

Descrição Este caso de uso descreve as possíveis reações do aplicativo quando

o baralho é pressionado. Este caso de uso é opcional dependendo da

definição das propriedades do jogo elaborado.

Pré-condição A tela de jogo estar visível, haver cartas disponíveis no baralho e a

imagem do baralho ser pressionado.

Cenário principal Caso as cartas ainda não foram distribuídas, o aplicativo verifica os

jogadores disponíveis e distribui as cartas para todos.

Cenário alternativo 1 Caso não haja mais cartas no baralho, as cartas do ―cemitério‖ são

embaralhadas novamente e recolocadas no baralho.

Cenário alternativo 2 Caso as cartas já tenham sido distribuídas, o jogo não será alterado.

Pós-condições As cartas são distribuídas conforme especificação do jogo.

Quadro 30 – Caso de uso UC04

Page 75: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

74

ANEXO E – UC05 - Mover as cartas da mão

Muitos jogos permitem uma maior ou menor interação do jogador com a partida, este

caso de uso detalhado no Quadro 31 descreve como o sistema interage quando o jogador

seleciona uma carta e movimenta-a na tela.

UC05 – Mover as cartas da mão

Descrição Este caso de uso descreve como as cartas do jogador podem ser

manipuladas durante a partida.

Pré-condição O jogo deve permitir cartas na mão do jogador e o jogador

selecionar uma das cartas em sua mão.

Cenário principal 1. O aplicativo verifica qual é a carta que deve ser selecionada

quando o jogador pressiona a tela.

2. Enquanto o jogador manter a tela pressionada, a carta poderá ser

movida por toda a tela. O sistema irá redesenhar a carta

acompanhando o movimento de toque do jogador.

3. Quando a tela parar de ser pressionada, o aplicativo verifica a

posição onde a carta será solta.

4. Caso a carta for posicionada em uma das áreas pré-definidas para

o jogo, a carta será retirada da mão do jogador e inserida no contexto atual.

Cenário alternativo 1 No passo 4, caso o jogador solte a carta fora de uma das áreas pré-

definidas, a carta irá retornar para a mão do jogador.

Pós-condições As cartas são reposicionadas conforme especificação do jogo.

Quadro 31 – Caso de uso UC05

Page 76: UNIVERSIDADE REGIONAL DE BLUMENAUcampeche.inf.furb.br/tccs/2011-II/TCC2011-2-19-VF... · diferenciação de valores e naipes das cartas, entre outras características. Este motor

75

ANEXO F – UC06 - Modificar o valor da aposta

Em vários jogos de cartas o sistema de apostas é utilizado para deixar a partida mais

interessante. Este caso de uso (Quadro 32) descreve os passos de como o Usuário interage

com as apostas no aplicativo.

UC06 – Modificar o valor da aposta

Descrição Este caso de uso estará disponível em partidas onde ocorrem apostas

entre os jogadores e descreve as opções de apostas possíveis.

Pré-condição O jogo deve conter mais de um jogador e permitir apostas entre si, e

após a distribuição das cartas, o botão de apostas ser pressionado.

Cenário principal 1. A aplicação exibe uma tela com as opções de apostas disponíveis

(Figura 25).

2. O jogador escolhe a melhor aposta para a rodada e aguarda a

decisão dos outros jogadores.

3. A janela de apostas se fecha e a partida continua.

Cenário alternativo 1 No passo 2, o jogador decide aumentar a aposta. Caso os outros

jogadores se mantiverem na rodada e se algum jogador aumentar a aposta, voltar para o passo 1.

1.1 Caso o valor da aposta for aumentado quatro vezes e a rodada de

apostas for finalizada, não será mais possível aumentar o valor da

aposta e os jogadores poderão optar por continuar na rodada ou desistir da mesma.

Cenário alternativo 2 No passo 2, o jogador opta por desistir da rodada. As cartas do

jogador serão retiradas e ele não poderá competir nesta rodada.

Pós-condições Ao finalizar a rodada do jogo, o jogador com a melhor pontuação

das cartas receberá o valor total da aposta. Em caso de empate, o valor será dividido igualmente entre os vencedores.

Quadro 32 – Caso de uso UC06