terça-feira, 22 de março de 2011

Máquina de Estados e AI Básica

Máquina de Estados

No projeto, todo GameObject tem uma máquina de estados baseada nesse artigo aqui: http://www.ai-junkie.com/architecture/state_driven/tut_state1.html

Um objeto como o player ou um monstro tem estados como Walk, Run, Idle, Attack e por aí vai, dependendo das funcionalidades que forem implementadas.

O uso da Máquina de estados facilitou e organizou meu projeto. Uma das coisas que mais me agradou foram os 3 métodos de cada estado:
//this will execute when the state is entered
virtual void Enter(Miner*)=0;

//this is called by the miner’s update function each update-step
virtual void Execute(Miner*)=0;

//this will execute when the state is exited
virtual void Exit(Miner*)=0;

Inicializar variáveis, carregar informações e coisas do tipo vão no Enter.
Um dos problemas que enfrentei no começo do projeto foi a mudança de sprite para cada tipo de ação do Character, principalmente em relação aos sprites de ataque. Então eu uso o Enter para carregar as informações de Área de Dano, Ataque e Colisão do Character para seu estado.

Inteligência Artificial Básica

Para o desenvolvimento da AI eu estou usando o conceito de MVC.
A classe Controller é assim:
class Controller {
public:
Controller() {}
virtual ~Controller() {}
virtual void update(Model *targetModel, GameObject *myObj) = 0;
virtual void init() = 0;
virtual bool getACTION() const =0;
virtual bool getDOWN() const =0;
virtual bool getLEFT() const =0;
virtual bool getRIGHT() const =0;
virtual bool getRUN() const =0;
virtual bool getSPECIAL_ATACK() const =0;
virtual bool getUP() const =0;
virtual void setACTION(bool ACTION) = 0;
virtual void setDOWN(bool DOWN) = 0;
virtual void setLEFT(bool LEFT) = 0;
virtual void setRIGHT(bool RIGHT) = 0;
virtual void setRUN(bool RUN) = 0;
virtual void setSPECIAL_ATACK(bool SPECIAL_ATACK) = 0;
virtual void setUP(bool UP) = 0;
};

Onde os Getters and Setters correspondem ao comandos dados pelo usuário no caso da classe filha ControllerInput. O método update foi colocado no Controller já pensando na AI.
A classe FightAI é filha da Controller e o método update é chamado para setar os atributos da classe:
bool LEFT;
bool RIGHT;
bool UP;
bool DOWN;
bool ACTION;
bool SPECIAL_ATACK;
bool RUN;

Assim, não foi preciso mudar o código do resto do jogo, uma vez que a classe Controller é usada pelo software a partir dos seus getters.

A AI de luta que eu programei é a mais simples possível. Ela apenas move o objeto (setando os direcionais) na direção do Player. Ao chegar na distância que é possível acertar um golpe ele ataca. Uma coisa que devo fazer posteriormente é acrescentar um fator randômico às escolhas da AI, deixando ele mais real e suscetível a erros. Além disso falta fazer o inimigo desviar dos objetos.

Eu não fiz uma máquina de estados própria para a AI, como eu queria fazer no princípio. O que eu faço é usar a máquina de estados, que já existe para todos os objetos, e retirar a informação sobre qual é o estado atual para as decisões da AI.
Related Posts Plugin for WordPress, Blogger...