Mostrando postagens com marcador componentes. Mostrar todas as postagens
Mostrando postagens com marcador componentes. Mostrar todas as postagens

terça-feira, 21 de dezembro de 2010

Reforma na Action RPG Lib

Considerações para a próxima versão

Problemas

->Problema com os sprites e suas dimensões, já que um sprite pode diferir de tamanho para o mesmo personagem.
Além Disso, existe o problema maior que é onde estaria o referencial de uma imagem. Há sprites em que o pé do Character está na base da imagem e em outros o pé está no meio da imagem.
O que causa problemas no código de colisão e em outros lugares tambem.


Solução
Eu decidi que a posição de cada objeto será o posição da metade da largura objeto e a altura da base. No caso de um humano o Ponto de Referência seria o ponto entre os pés, aproximadamente.


->Animação Baseada em tempo: o problema é quando um personagem anda 0.31 pixels/frame. Na hora de desenhar, cada pixel é indivisível, assim quando arredondo o personagem andará 0 pixels.

Solução
A solução que usei é armazenar cada parcela de pixel que o personagem andou até que se some 1, e assim realizar o movimento.

Decisões

->Para facilitar tanto programação e entendimento será passado como argumento do método os componentes. Assim ficará claro que outros componentes cada componente depende.

->Componente State: A criação desse componente facilitará o controle dos estados do componente.

->Especialização de Componentes: Existirá tipos de State como CharState, ItemState e MonsterState. Assim, cada tipo de GameObject terá um State mais personalizado, simplificando cada Máquina de Estados. Será extendido para controle, Movimentação e muitas outras coisas. Isso irá diminui a genericidade de cada componente, mas simplifica e organiza o código.

->A primeira vista, parece ser interessante abusar do uso de interfaces. O que eu vou tentar fazer.

->Estudar mais a fundo State Pattern

Pra finalizar segue um link interessante sobre Component Pattern

segunda-feira, 7 de junho de 2010

Componentes Talk e Fight

Agora vamos falar dos componentes responsáveis pelos diálogos do jogo e pela Action do Action RPG.
Para diálogos eu pensei em 2 componentes: o Talk e o Listen. Um responsável por falar e outro por ouvir. Quem ouve são os jogadores, então apenas eles terão esse componente. Já o Talk estaria presente em qualquer entidade que tiver algo a falar. Vai ser nesse componente que vai ficar o texto a ser mostrado. O exemplo mais óbvio é um NPC da cidade falando sobre o mal que assombra a cidade mas tem muitos outro também. Uma placa indicando a direção do castelo precisa "falar" pois para o jogador o texto da placa aparece na forma de diálogo. Uma árvore também pode falar ou um baú trancado avisa que ele está trancado.
O componente Listen acessa o componente Talk da outra entidade, ativando o dialógo que é mostrado na tela.
Para a luta vai existir um componente Fight. Ele vai ser responsável pelo ataque e pelos testes de acerto. Aqui também ficarão propriedades relacionadas como precisão e esquiva e essas propriedades podem ser alteradas pelos componentes relacionados a os atributos como um componente de habilidades do personagem. Porém o Fight não enxergará esses componentes e agirá independente dos mesmos.

domingo, 30 de maio de 2010

Detalhes de implementação

Após escolher a estrutura do jogo faltava definir como seria a implementação dos componentes e da classe GameObject. O decidido foi fazer uma classe Component e todas os componentes herdam essa classe. Além disso a Component tem um ponteiro de map de GameObjects.
Eu prefiri definir a classe GameObject apenas com os componentes e com um identificador.

class GameObject {
public:
typedef int ObjID;
GameObject();
virtual ~GameObject();
Collection components;
};

class Component {
//ID do objeto que contem o componente
GameObject::ObjID owner;
public:
//Contem todos os objetos do jogo
map *objs;
// Todo componente tem um tipo
virtual int getType(){
return -1;
}
GameObject::ObjID getOwner() const
{
return owner;
}
}

Qualquer atributo como nome do objeto ou outra funcionalidade será adicionada a classe na forma de um componente. Os componentes podem ser criados pelo objeto ou fora do objeto.
Dentro do objeto tem o problema de deixar o objeto mais difícil de reconfigurar e uma vez que uma das vantagens de usar componentes é deixar o objeto mais flexível, isso é um problema a ser considerado.
Fora do objeto o código externo passará o componente criado para o objeto e isso manterá a flexibilidade, já que o objeto poderá ser alterado completamente apenas alterando seus componentes. Outra vantagem é a de que, como o GameObject recebe os componentes criados como classes derivadas de Component e por isso ele só conhece essa classe, o código está mantendo um fraco encapsulamento.

O problema agora é como seria a comunicação entre os componentes, uma vez que o componente Movement precisa do componente Position, por exemplo. Há três formas:
Acesso direto aos outros componentes
Na minha opinião é maís fácil de se pensar uma vez que não é preciso realizar a comunicação implicitamente utilizando métodos da classe componente. Porém tem a desvantagem de aumentar o acoplamento. A grande vantagem é que é simples e rápida.
Modificando atributos do GameObject
Diminui o acoplamento porque os componentes não sabem da existência um do outro. E requer informações compatilhadas e isso pode causar uma sobrecarga da classe GameObject com informações que nem todo objeto do jogo vai precisar. Além disso a comunicação seria implícita, o que aumenta a dificuldade de projetar o jogo.
Por mensagens
É o mais complexo mas tem fraco acoplamento e a classe GameObject é mais simples. O acoplamento seria deixado para o valor das mensagens e da interpretação da mesma e não requer informação compartilhada porque a troca de informação é feita apenas entre componentes.

Não há resposta certa e é aconselhado usar um pouco de cada. Em alguns componentes muito relacionados como Movement e Position não seria tanto problema o acoplamento devido ao acesso direto porque eles já são acoplados por um depender tanto do outro. Caso todos os objetos tem alguma informação comum ela pode ser compartilhada entre os componentes.
As mensagens normalmente são usadas para comunicação menos importante, como uma comunicação entre o componente de áudio e o componente físico.

Na Action RPG Lib eu optei por começar usando o acesso direto dos componentes porque eu ainda não vou descrever todo o sistema antes de começar programar e é mais fácil de pensar. Se no meio do projeto eu perceber que seria melhor outras abordagens eu tento implementa-las ou anoto para implementar na versão 2(espero).

Fonte: Game Programming Patterns - Component

quarta-feira, 26 de maio de 2010

Herança x Componentes

Quando eu comecei a Action RPG Lib mais programando do que projetando ela era baseada em herança.
Mas eu comecei ter umas dúvidas de como eram organizados os jogos e acabei achando muitos artigos falando sobre o porque de não usar herança nos jogos e fui apresentado a programação de jogos baseada em componentes.
Esses artigos falam das várias desvantagens de se utilizar herança e as vantagens de se utilizar componentes.
Evolve Your Heirachy
Component-Based Architechture: Getting Away from Inheritance
A grande vantagem dos componentes que me convenceu a utilizar essa abordagem é o fato de ser muito mais reutilizável. E o que tem sido minha dificuldade fazendo do modo antigo era manter um código de fraco acoplamento.
No jogos Component-based os objetos do jogo são todos da mesma classe, GameObject no meu caso. O que muda de uma item para o personagem são os componentes que eles terão. Então o personagem teria um componente para posição, para movimento e para a fala, por exemplo. Uma árvore teria posição apenas. Mas se eu quisesse uma árvore que fala eu colocaria um componente de fala nessa árvore. Para o caso do meu jogo a grande vantagem é que eu poderia implementar várias funcionalidades depois, na forma de componentes.
Related Posts Plugin for WordPress, Blogger...