Steering Behaviors – Arrive
Hoje fiz a implementação do Steering Behavior arrive. Cheguei a conclusão que terei que montar outro modelo, mais simples, provavelmente similar aos triângulos do Buckland.
Isso porque as naves do Batalha Estelar não tem freio. E eu não gostaria de prejudicar o Game Play colocando um freio por lá. É possível calcular o uso do acelerador de tal forma a emular um freio, mas isso também seria um tanto injusto com o jogador, que não tem um dedo tão preciso assim. Por incrível que pareça, o comportamento Seek é extremamente realista e já atenderia ao propósito.
Sem problemas. Não deve levar mais do que poucos dias para montar os triangulozinhos do Buckland. Também é uma ótima oportunidade de reprensar na física, mais de acordo com o que o autor propõe. E seria necessário de um jeito ou de outro para implementar um comportamento de grupo. Numa dessas, acabo alterando o Batalha Estelar, ou repensando as classes dos behaviors.
Templates tem funcionado muito bem, mas a integração com o código ainda é um pouco difícil. Vou dar um pequeno tempo nesse estudo, faço o protótipo com os triângulos, monto os behaviors e depois volto a pensar em como tornar a integração mais suave. Nesse meio tempo, o estudo sobre templates continua. O que fiz com templates funcionou melhor do que eu esperava e meu feeling de que esse é o caminho para um código adaptativo aumentou.
Essa semana, o tempo de trabalho foi maior, de aproximadamente 10 horas.
A classe arrive ficou assim:
namespace behavior
{
enum Deceleration { SLOW=3, dNORMAL=2, dFAST=1 };
template <typename Target>
class Arrive
{
private:
const Vehicle& vehicle;
const Target& target;
const Deceleration deceleration;
public:
Arrive(const Vehicle& _vehicle, const Target& _target,
Deceleration _deceleration = dNORMAL)
: vehicle(_vehicle), target(_target), deceleration(_deceleration) {};
virtual math::Vector2D calculate()
{
math::Vector2D targetPos(target.getX(), target.getY());
math::Vector2D path(targetPos - vehicle.getPosition());
double distance = path.getSize();
if (distance <= 0)
return math::Vector2D();
//Because deceleration is enumerated as an int, this value is required
//to provide fine tweaking of the deceleration
const float decelerationTweaker = 0.3f;
//Calculate the speed required to reach
float speed = distance / (deceleration * decelerationTweaker);
//Make sure the speed does not exceed the maximum allowed speed
speed = std::min(speed, vehicle.getMaxSpeed());
//From here proceed just like Seek, except we don't need to normalize
//the ToTarget vector because we have already gone the trouble
//of calculation it's length: dist
math::Vector2D desiredVelocity = path * (speed / distance);
return (desiredVelocity - vehicle.getVelocity());
};
};
};