Estou trabalhando em um jogo em que o jogador pode pegar objetos usando algo como um raio de trator e carregá-los.
Atrair o objeto em direção ao centro do feixe não é difícil. Mas quando o objeto estiver próximo o suficiente do centro, preciso mantê-lo lá enquanto o jogador se move, e é com isso que estou tendo problemas. Posso pensar em duas maneiras de fazer isso, e ambas têm problemas:
Atualize a posição do objeto sempre que a posição do jogador mudar, mantendo-o centralizado no raio.
Atualize a velocidade do objeto para apontar diretamente para o centro do feixe, quanto mais longe, maior a velocidade.
Mover e girar funciona bem com as duas abordagens, mas a física está errada quando o objeto carregado colide com outros objetos:
Com a primeira abordagem, a física é completamente ignorada. O objeto carregado simplesmente empurra qualquer coisa para fora do caminho. Isso ocorre porque as mudanças de posição devem ser feitas apenas como parte da física do mundo, com base na velocidade.
Com a segunda abordagem, a física basicamente se comporta como deveria, mas reage exageradamente. O problema é: Para manter o objeto transportado no centro do feixe, mesmo quando estiver girando e se movendo, preciso usar valores altos de velocidade. Assim, uma vez que o objeto carregado toca outro, fica com velocidade demais da colisão.
Como posso implementar isso corretamente? Meu melhor palpite agora é seguir a segunda abordagem e adicionar um tratamento especial para objetos transportados à física mundial, reduzindo a velocidade a valores sãos para colisões ou quando o jogador parar de carregá-los. Mas isso parece uma solução bastante deselegante.
Edit: Adicionando algum pseudo-código para ilustrar como funciona agora (essa seria a segunda abordagem acima)
void attract_object(object, ticks) {
Vector distance = beam_center - object.center;
// If the object is not close to the beam center, attract it slowly
if (magnitude(distance) > 10) {
object.velocity += distance.normalized() * ticks * 0.1;
return;
}
// Here comes the part we're talking about. That magic 0.5 is just high enough
// that the object isn't lost while moving around. But it's still so high that
// other objects are repelled with way too much force.
object.velocity = distance * ticks * 0.5;
}
Pelo que vejo, isso acontece quando o objeto carregado empurra outro objeto:
- O objeto carregado colide com outro objeto
- As velocidades dos objetos são distribuídas adequadamente, de modo que o objeto carregado é empurrado para longe do centro do feixe no processo
- O código acima faz com que o objeto carregado retorne ao centro do feixe, com tanta velocidade que ele retornará rapidamente
- Quando o objeto transportado se move de volta para o centro do feixe, metade de sua alta velocidade é transferida para o outro objeto, repelindo-o violentamente. Como a velocidade inicial do objeto transportado parece ser sã, posso imaginar que as etapas 2 a 4 são repetidas várias vezes, construindo uma velocidade tão alta.
Essa parece ser a causa. Eu não consigo pensar em uma boa maneira de corrigi-lo :(