sexta-feira, 11 de maio de 2012

Alterações na Documentação



Olá!!!

Neste post, informarei a situação da documentação e as alterações recentes.

Tivemos várias alterações na Estimativa de Desenvolvimento, tanto na parte de implementação, quanto na documentação em si. Levando em conta que minha responsabilidade é atualizar e balancear essas mudanças, sendo estas decididas em equipe, precisei modificar o Documento de Arquitetura e, consequentemente, as tarefas no Pivotal Tracker.

As principais modificações foram realizadas em:

* Requisitos Funcionais: Adição de itens no tópico Menu.

* Estimativas de Desenvolvimento:

  - Estória: Programação intermediária da engine: foi adicionada a tarefa "Programação da classe de tratamentos de erros da engine".

 - Estória: Elaboração inicial do jogo Ticket To Ride: a produção da arte foi melhor dividida em tarefas. Assim, nesta estória foram adicionadas as tarefas "Produção dos principais elementos da arte do jogo - Menu." e "Produção dos principais elementos da arte do jogo - Sprite das cartas de construção (trens coloridas)."

- Estória: Desenvolvimento intermediário do jogo Ticket To Ride: seguindo a divisão de aspectos de arte, adicionei as tarefas. "Produção dos elementos da arte – HUD Padrão", "Produção dos elementos da arte – HUD (Personagens)", "Produção dos elementos da arte – Tela(s) de Regras" e "Produção dos elementos da arte – Telas do Jogo".

  - Estória: Documentação: nesta estória havíamos definido certas tarefas sem ter o conhecimento do Documento de Arquitetura, pois este foi passado a nós após a realização da Estimativa de Desenvolvimento. Com o documento divulgado, resolvi substituir as tarefas anteriores pelos tópicos (vistos anteriormente no post Escopo geral da documentação) do referido documento.  

  - Estória: Programação avançada da engine: a pedido do Ráfagan, fiz a substituição da tarefa "Inserção de recursos OpenGL para produção de jogos 3D." pelas tarefas "Implementar cálculo de iluminação.", "Implementar efeitos de Blend,", "Implementar carregamento de modelos 3D." e "Implementar colisão 3D."

* Além de recalcular a soma das complexidades de cada estória alterada e fazer a substituição ou inserção das tarefas na ferramenta Pivotal Tracker, aproveitei para colocar etiquetas(labels) referentes ao nome de cada estória do Documento de Arquitetura:

- Estória: Programação básica da engine. > programação básica

- Estória: Programação intermediária da engine. > programação intermediária

- Estória: Programação de um Gerador gráfico de mapas T.T.R. com leitura de arquivos XML. > programação gerador gráfico.

- Estória: Elaboração inicial do jogo Ticket To Ride. > elaboração inicial.

- Estória: Desenvolvimento intermediário do jogo Ticket To Ride. > desenvolvimento intermediário.

- Estória: Fase final de produção do jogo Ticket To Ride. > fase final.

- Estória: Documentação. > documentação.

- Estória: Programação avançada da engine. > programação avançada.

- Estória: Teste do game. > testes.

- e + etiquetas de divisões: programação, arte, som e extras para facilitar a pesquisa por tipo de tarefa além da estória a qual já pertencem.

* Diagrama de Casos de Uso: ao realizar a tarefa de Realização de Casos de Uso seguindo este diagrama, senti a necessidade de fazer algumas alterações, como adicionar o caso de uso "Visualizar Regras" diretamente como opção do menu, e não apenas na animação programada para aparecer em determinado tempo após não ocorrer nenhum evento no menu; E um novo caso de uso chamado "Iniciar Partida" entre o sorteio da ordem dos jogadores e receber cartas para ficar mais claro o inicio da partida.

Por enquanto são estas, mas podem aparecer mais alterações, pois ainda estou fazendo a Realização dos Casos de Uso referentes a este diagrama.

Assim que terminar esta tarefa poderei comentar se houveram novas alterações.

Refatoração Concluída

Olá!

Das refatorações que faltavam, nenhuma falta mais!

paSDLWindow deu origem à nova classe paSDLEvent como comentado no post anterior, paOpenGL se tornou paOpenGLWindow, dando origem às classes paOpenGLDraw, sendo esta responsável pela configuração do desenho na tela (iluminação, blend, configuração de texturas,...); e paOpenGLTransform, responsável por realizar as transformações básicas e inversões de matrizes.

Também trabalhei para melhorar o sistema de proteção das classes,  declarando construtores como explicitos, colocando os construtores de cópia padrão no escopo private, e implementando outros quando necessário.

Criar uma nova classe para o gerenciamento do desenho em OpenGL ainda necessita de alguns ajustes, mas está quase lá.

Pretendo daqui pra frente focar na finalização da classe paOpenGLDraw, criar um exemplo para teste das novas alterações na engine que ainda não foram testadas, e dar algumas modificações no modo de carregamento de texturas e controle da câmera, além de modificar a classe paSDLEvent para comportar um modelo de eventos mais simples para o usuário.

Terminadas essas alterações, estarei focando no desenvolvimento de um modelo de colisão por seleção usando OpenGL, e se eu conseguir, o próximo passo será desenvolver o gerador de mapas!

Até lá!

Nova funcionalidade: paSDLEvent

Olá pessoal!

Hoje eu consegui uma proeza que ha tempos estava querendo fazer. A captura de eventos da engine!!!

Quando inciei a programação da mesma, havia planejado três tópicos inciais: Desenho na tela, GameLoop e captura de eventos.

Os dois primeiros eu consegui, porém o terceiro tópico era sempre adiado, por motivos de importância maior, como, por exemplo, me atualizar na matéria de OpenGL. Essas obrigrações acabaram me obrigando a criar uma estrutura simples de captura de eventos.

Mas isso terminou hoje. Com a refatoração da engine, a próxima parte a ser refatorada da paSDLWindow seria os métodos com tratamento de eventos. Nesse momento, a necessidade de criar uma classe para tratamento de eventos formalizada se tornou iminente.

No meu planejamento inicial, o objetivo era basicamente programar uma estrutura do tipo Polling, onde todas as teclas seriam testadas quanto ao seu estado: ativo, pressionado ou liberado, muito semelhante ao o que acontece na Chien2D. Essa abordagem permite que multiplos eventos do teclado (como o pressionar de várias teclas ao mesmo tempo) seja efetuado mais facilmente, abordagem esta que a operação manual de captura de eventos usada pela SDL não comporta.

Para quebrar a dificuldade dessa implementação, a dividi em três dificuldades:

1- Capturar um evento qualquer;
2- Capturar um evento das teclas desejadas;
3- Capturar um evento de uma tecla desejada levando como consideração as estruturas ativo, pressionado e liberado.

Na primeira tarefa, implementei uma estrutura básica de captura de eventos, recebendo os casos de SDL_KEYDOW, SDL_KEYUP, SDL_QUIT, SDL_MOUSEMOUTION, SDL_MOUSEBUTTONDOWN e SDL_MOUSEBUTTONUP.

Para a segunda tarefa, implementei uma estrutura de enumeração, contendo os nomes das constantes das teclas que a engine irá suportar. estas constantes são:


K_UP, K_DOWN, K_RIGHT, K_LEFT, K_ESC, K_F1, K_F2, K_F3, K_F4, 
K_A, K_B, K_C, K_D, K_E, K_F, K_G, K_H, K_I, K_J, K_K, K_L, K_M,
K_N, K_O, K_P, K_Q, K_R, K_S, K_T, K_U, K_V, K_W, K_X, K_Y, K_Z, 
K_0, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9,
K_ENTER, K_SPACE, K_LALT, K_RALT, K_LCTRL, K_RCTRL, K_LSHIFT, K_RSHIFT, K_ENDBUTTON

M_LEFT, M_RIGHT, M_MIDDLE



Por fim, a captura levando como consideração as tags mencionadas. Para tal, precisei implementar structs que contivessem as três tags como variáveis boleanas, e atualizá-las a cada pressionar de teclas, sendo que cada tecla possui sua própria struct. no caso das teclas liberadas é fácil, mas como identificar se uma tecla está pressionada ou ativa?

A solução que implementei foi inicializar a cada gameloop os estados das teclas pressionado e ativo para falso, ou seja, para que o estado pressionado voltasse a ser verdadeiro, o usuário se obrigaria a apertar diversas vezes o evento da tecla para alterar seu valor boleano de pressionado. Já o estado ativo não era ressetado no inicio de cada GameLoop, mas apenas quando a tecla fosse liberada.

Quando implementei a classe no jogo, eu somente tive que mencionar a captura de polling da mesma na camada mais acima de abstração da engine (ou seja, em paGameLoop), e o usuário se preocuparia apenas em capturar o estado atual da tecla desejada por meio de um ponteiro.

Por hoje é só. Ainda pretendo implementar uma interface secundária de captura de eventos para os usuários que não forem utilizar a paGameLoop.

Até a próxima!

quinta-feira, 10 de maio de 2012

Demais alterações

Olá!


Terminada a detecção dos erros anteriores e a organização da classe paGameLoop, iniciei a refatoração da classe paSDL. Pra começar troquei seu nome para paSDLWindow, de forma que os métodos relacionados a tratamento de eventos e desenho e carregamenta de surfaces necessariamente devem ser removidos. Como a interface de tratamento de eventos ainda não está completa, decidi começar pelo desenho.

Esse processo deu a luz a uma nova classe: paSDLDraw. Ela é responsável por carregar e desenhar qualquer coisa que envolva a SDL. Os maiores trabalhos que tive com ela foram remodelar a classe paSDLSprite para que esta não mais acessasse a classe paSDLWindow para desenhar, e também na classe paOpenGL, a qual desenha as texturas usando o tratamento de inversão de píxels com a SDL.

Meus próximos objetivos agora são finalizar a refatoração da classe paSDLWindow, assim como as da paOpenGL; e depois iniciar a revisão do código referente à classe paCamera, que ainda não está completa!

Até a próxima!

Refatorações e Correções de problemas

Olá a todos!

Nessa quarta-feira (09/05) me dediquei inteiramente a buscar maneiras de melhorar o código da engine para poder seguir em frente. Os maiores problemas envolvidos a essa iniciativa envolviam o fato de que muitas implementações mais novas estavam pouco encapsuladas (por exemplo, a classe paGameLoop acabava deixando de fazer algumas funções mais complexas, deixando essa responsabilidade para o usuário).
Outros problemas referiam-se às classes paSDL e paOpenGL. O maior deles era que a classe openGL é filha de SDL. Pensando nas relações hierarquicas "É UM", essa assertiva se torna confusa.

Buscando resolver essas coisas, comecei inicialmente tentando modificar a classe paGameLoop para fazer algumas funções de ajustes da janela, como inicializá-la, desabilitar o modo de controle de GameLoop padrão, configurar o desenho, dentre outras. Ou seja, o usuário que não desejar implementar as configurações desejadas para a janela e para a engine manualmente, poderá fazer uso desses métodos de configuração.

Nessa altura do campeonato, alguns bugs e comportamentos estranhos estavam me incomodando (para uma maior visão sobre o problema abordado a seguir, leia o post anterior). O primeiro deles envolvia a lentidão da compilação após a inserção das novas configurações de projeto ja comentadas anteriormente. Em seguida vinham erros msiteriosos que apareciam nos includes e em algumas regiões do código, mas que, ao compilar, o executável era gerado com sucesso. O ultimo problema envolvia a necessidade de gerar um novo arquivo lib a cada modificação na engine, além de que muitas vezes parecia que os arquivos acessados pelos jogos não eram os mesmos que os arquivos da engine que estava modificando

Como havia feito muitas modificações no projeto, estava difícil saber de onde vinham todos esses erros. E depois de tentar resolvê-los de centenas de maneiras diferentes, acabei desistindo e voltando para a abordagem anterior de um projeto só com a engine e os jogos em conjunto. Enquanto programava no código desta maneira, descobri que o motivo da lentidão na compilação eram os propertie managers que não faziam parte do computador que eu estava usando. Agora sei que mesmo funcionando, não é a melhor escolha manter os propertie managers de ambos os computadores no projeto.

O outro caso dos erros misteriosos se resolveu quando eu passei a dizer o endereço exato dos arquivos do tipo header no include. Como dividi o projeto em uma pasta include e outra para a lib, mantendo os arquivos cpp junto ao arquivo de projeto do visual studio, os arquivos .h, mesmo estando juntos, eram sinalizados como arquivos não encontrados pelo visual studio. O intrigante é que a teoria de que estes arquivos estavam no local certo se fazia satisfeita quando a compilação rodava normalmente.

Por exemplo, o include abaixo no paSDLSprite.h era sublinhado pelo VS como um erro:

#include "paSDL.h"

Engraçado para arquivos localizados no mesmo lugar... Mas a solução para satisfazer as vontades do VS está em especificar o endereço do arquivo de acordo com o local onde se encontra o arquivo do projeto:

#include "include/paSDL.h"


Por enquanto é só. No próximo post especificarei as demais modificações que fiz na engine...

terça-feira, 8 de maio de 2012

Nova organização do projeto no VS 2010

Olá leitor!

Hoje vou falar sobre o processo de organização que o Projeto passou dentro de seu ambiente de desenvolvimento: A IDE Visual Studio 2010!

No início do desenvolvimento da engine, o ambiente estava apenas dividido basicamente em uma pasta para os headers files e outra para os cpp files.
Com o aumento das classes e a integração com a biblioteca de matemática de vetores do professor V. Mendonça, foi necessário criar pastas dentro do projeto que o dividissem em 4 partes:

a) .h paEngine;
b) .h math
c) .cpp paEngine;
d) .cpp math

Para um projeto único, esta abordagem é suficiente. Porém, o que estava acontecendo é que eu utilizava a engine em diversos projetos: TicketToRide, Protótipo3D, Gerador de Mapas e exercícios OpenGL, sem contar as trocas de versão com a Keli.

Consequentemente, como a engine estava em fase de desenvolvimento, diversas alterações se faziam necessárias, resultando em um problema de controle de versão ideal para a engine.
A primeira solução foi trocar o método manual de controle de versão que estavamos utilizando pelo controle usando o GIT, mas ainda sim correriamos o risco de acabarmos esquecendo de atualizar a versão, e toda e qualquer ateraçãozinha acarretaria em uma nova versão também.

A solução que encontrei para o problema foi criar um projeto no Visual Studio do tipo Static Library. Com ele, eu teria a engine focalizada em um único local e o problema de alteração mútua da mesma se resolveria.
Resolvido o problema, ainda de quebra acabei fortalecendo ainda mais o encapsulamento do projeto, e finalmente formalizei a engine em um formato simples para o compartilhamento da mesma com minha colega Keli.

Resolvido o problema maior, ainda tive que dar conta de outro detalhe: Os chatíssimos Includes!!!

Como utilizo mais de um computador para trabalhar, constantemente é necessária a mudança dos endereços das variáveis de ambiente responsáveis por linkar as libs ao programa. Isso se tornou ainda mais complicado no caso da engine modulada em dois projetos, pois para trabalhar com ela necessitaria não mais atualizar os linkers de um projeto (coisa que ja é muito chata de se fazer), mas sim de dois! Se trocasse de computador 3 vezes ao dia, teria 6 alterações de linker!

A solução encontrada foi criar arquivos do tipo Property Manager, os quais possibilitam que se forneça todas as configurações de propriedades do projeto no mesmo, e em seguida incluí-lo ao projeto em questão. Ou seja, configurei dois arquivos Property Manager, um para cada computador, e dessa forma só preciso agora incluir ambos no projeto e adeus includes chatos...

Por hoje é só!
Até a próxima...

sexta-feira, 4 de maio de 2012

DOCUMENTAÇÃO
Documento de Arquitetura do Jogo (6)

Olá!
   Continuando com a descrição dos aspéctos do Documento de Arquitetura, hoje veremos como foi construído o sexto tópico, intitulado Estimativa de Desenvolvimento, por nós, onde foi utilizado o método Planning Poker. Também será abordado como este planejamento foi integrado à ferramenta Pivotal Tracker, sendo este um ambiente de gerenciamento de projeto baseado na metodologia Scrum.

Sobre Planning Poker:
   É um Método de estimativa que usa como base o conhecimento dos desenvolvedores para estimar a quantidade de trabalho necessário para realizar o projeto.
   Para isso, são feitas estórias com suas devidas tarefas. Cada tarefa tem seu peso e a complexidade estimada, sendo esta última decidida pela própria equipe de acordo com uma escala pré-estabelecida.
    Geralmente se utiliza um baralho com os valores da escala para ser jogado durante a reunião com a equipe, definindo assim através de uma discussão entre os membros o valor mais adequado. No caso de divergências sem consenso, o maior valor atribuído será o levado em consideração na documentação.

(Figura 1 - Exemplo de baralho Planning Poker)
(Figura 1 - Exemplo de baralho Planning Poker)

Modelo de Estórias:

Estória 1: <descrição da estória>
Tarefa 1: Criação de Menu
Complexidade: 1
Tempo: 2 horas

Estória 2: <descrição da estória>
Tarefa 1: Criação de Menu
Complexidade: 2
Tempo: 4 horas
Tempo Total = 2h + 4 hs =  6 horas

Utilizando o Método:
     Pensamos em tudo o que achamos necessário para a realização do projeto, e em seguida analisamos as tarefas semelhantes e as agrupamos, formando as estórias. Utilizamos a escala de Fibonacci (1,2,3,5,8,13,21) para dar os pesos a cada uma das tarefas da estória.

   Segue uma de nossas estórias e suas tarefas com devidos pesos e atribuição de horas:

Estória: Programação básica da engine.
Descrição: Criação inicial de uma engine que possibilite a criação de protótipos usando OpenGL.
· Tarefa 1: Programação da interface de configuração da janela para WINDOWS. (3)
· Tarefa 2: Programação do desenho básico na tela com SDL. (1)
· Tarefa 3: Programação de uma interface de desenho de Sprite em quadros. (13)
· Tarefa 4: Programação do Game Loop. (21)
· Tarefa 5: Programação da captura de eventos usando Polling (Atenção especial para o MOUSE). (21)
· Tarefa 6: Programação da interface básica de configuração de desenho em OpenGL.(3)
Complexidade: 62
Tempo: 150 homens/hora.

Sobre o Pivotal Tracker:
É uma ferramenta online muito utilizada para projetos ágeis. Nela os desenvolvedores controlam as sprints através do peso atribuído a cada tarefa e a velocidade selecionada.
Mais informações: https://www.pivotaltracker.com/

Utilizando a Ferramenta:
Como a ferramenta trabalha com o escopo de uma única sprint por vez, cada tarefa criada anteriormente utilizando a metodologia é cadastrada e não as estórias.
Assim, ao clicar em “ADD STORY”, cadastramos uma de nossas tarefas no painel (Figura 2) que aparece já na aba “ICEBOX”; e nele colocamos nome, tipo, pontos (complexidade), responsável, descrição, etiquetas, tarefas (para controle de quem estiver implementando), atividades e até anexos se necessário.
(Figura 2 – Painel de cadastro da tarefa-estória)
(Figura 2 – Painel de cadastro da tarefa-estória)

          Ao cadastrar todas as tarefas já definidas, basta definir a velocidade das iterações e arrastar as tarefas para “CURRENT” ou “BACKLOG”, e estas se organizarão de acordo com a complexidade e a velocidade.

(Figura 3 – Visão Básica da ferramenta Pivotal Tracker com tarefas do projeto)
(Figura 3 – Visão Básica da ferramenta Pivotal Tracker com tarefas do projeto)

Confira o link do nosso projeto cadastrado como Public no Pivotal Tracker: 

Link: https://www.pivotaltracker.com/projects/534473

Até a próxima!