Olá senhores [beware, long post]
Agora de volta à civilização e com acesso decente a interwebs posso falar mais disso…
Esses dias mexi um pouco no Horus Eye pra implementar o novo sistema de AI que discutimos nas ultimas reuniões do mês
A idéia era de o sistema básico (o framework mesmo) fazer parte da UGDK, mas ai me toquei que a AI precisa ser ligada a um tipo base de “entidade” (que possa ter uma AI), o que no nosso caso é a Creature do Horus Eye, mas como isso tá só no Horus Eye por motivos óbvios, acabei fazendo tudo no Horus Eye mesmo e não toquei na UGDK.
Anyway o sistema em si já está funcionando, o que é algo muito legal hahaha, mas ainda irá necessitar de uma refatorada no código…
Por enquanto as AIs estão iguais a como estavam antes (usando o novo sistema, e já tirei o código antigo da Mummy, mas iguais em comportamento e ações), não tive tempo de adicionar nada novo ainda, pelas razões que seguem…
As classes novas que contém a lógica das AIs (são algumas classes “blocos” pequenas, por enquanto 5) são separadas da herança Sprite->WorldObject->Creature->Mummy/Hero, então elas não tem acesso as várias coisas protected das Creatures pra poderem fazer o que tem que fazer. Funcionava antes pq o código ficava na Mummy, que tem acesso. Mas not anymore. E essas coisas eram tudo protected, como por exemplo as skills (nao tinha getter pra pegar de fora), ou a função de Move() da Creature.
Então tive que fazer alguns getters e outras funções auxiliares na Mummy e na Creature (mostly na Creature).
Tinha tentado fazer com que a Creature fosse friend da classe base dos blocos de AI, mas não funfou pois como vim a descobrir, o friendship das classes é uma das poucas coisas que uma classe não herda da classe-pai. Ainda tem umas possibilidades que posso testar com esse negócio de friend, mas não sei se vai funcionar e honestamente acho que é mó POG usar friend, homicidio de OO
Mas até ai, beleza, consegui fazer a AI como tava antes.
Quando fui pensar em coisas novas pra implementar (de comportamento das AIs) que me veio a duvida que é a maior razão desse post… (por sinal, sorry pelo tamanho. Se você leu até aqui, parabéns! xD)
É muito dificil fazer com que a AI perceba mudanças no mundo… pra fazer algo assim teriamos que ficar iterando por coisas a cada frame, o que não é algo legal…
Veja o seguinte exemplo: quero ter uma mumia que desvie (ou pelo menos tente) de projeteis do Kha (pelo menos o básico).
Ai vc pensa: É ridiculo! Vejo quando o Kha atira, faço uma mágica com vetores pra ver se tal tiro tá vindo na minha direção, se sim, me movo.
True story. Mas como raios vou ver como o Kha atira? Tem nada no código pra ajudar com isso. A unica solução para a AI é iterar pelos WorldObjects que o World mantém, ver os que sao Projectile, ver os que vieram do Kha, talvez ver o tempo de vida deles pra ver se eh um projetil “recente”, ver o vetor de direcao e talvez velocidade. Ou seja, trabalho pra caralho. Fora que a lista de WorldObjects do World é protected, teriamos que alterar o World pra poder acessá-la, entre outros problemas em acessar essas coisas.
Ou seja, não é trabalho pra caralho, é trabalho pra !&#$^*%A&^SDRU#YGE^!#TXUDQGWXDB!R# SBRUBLES
Minha idéia (e a razão por trás do post, fora falar que o sistema novo tá funcionando e é mó legal xD), é fazer um sistema de eventos.
Certas classes tem certos eventos (como World->New Object Added, ou Hero->Fired ), e qualquer parte do código pode registrar (ou talvez também remover) funções de callback para esses eventos. Ai quando algo desses eventos acontece, (tipo, heroi atirar), ele percorrer e executa essas funções.
Um sistema de eventos desses, e os eventos apropriados nas classes ia ajudar PAGARAIIIIO as AIs e provavelmente outras partes do jogo também.
Como já to fazendo isso das AIs, me voluntario a implementar tal sistema.
Passei aqui e fiz esse post gigantesco pra discutir tal idéia, ver se realmente querem que eu implemente algo assim, e idéias de como implementá-lo.
Como percebi esses dias, meu C++ anda meio enferrujado… Umas idéias sobre como implementar poderiam ajudar xD
Como não sei bem de usar ponteiro de função em C++ e como disse meu C++ anda enferrujado, tive duas idéias parecidas:
1)fazer uma classe base EventHandler, com uma função, Call ou o operador(), sei lá. Ai as classes que tem eventos tem uma lista de EventHandlers pra cada evento, e quando o evento acontece percorre e da os Calls() neles. Os lugares que quiserem receber tal evento implementam sua classe que herda da EventHandler, com sua implementação como quiserem da tal função.
2)Classes que tem eventos também fazem uma classe auxiliar pra cuidar de tal event, tipo WhateverHandler pro evento Whatever. Ai ela tem uma lista de WhateverHandlers, e quando ele acontece, a classe percorre pelos WhateverHandlers e executa uma funcão delas. As classes que quiserem receber o evento Whatever podem herdar de WhateverHandler (pelo que lembro pode ter herança multipla em C++) mas ai fazem sua implementação da tal função.
:P