KlassischeKeplerKriege/game/state/missile.cpp

86 lines
2.6 KiB
C++
Raw Normal View History

#include "missile.hpp"
#include <cmath>
#include "state.hpp"
#include "player.hpp"
#include "ship.hpp"
#include "planet.hpp"
#include "trace.hpp"
#include <glm/gtx/norm.hpp>
namespace game {
Missile::Missile(Player *player, const glm::vec2 &pos, float angle, float speed)
: player(player)
, position(pos)
{
velocity = speed * glm::vec2(std::sin(angle), std::cos(angle));
//std::cout << "spawned missile for player " << playerId << " @ ("
// << pos.x << ", " << pos.y << ") speed = " << speed << std::endl;
}
Missile::~Missile()
{
//std::cout<<"destroyed missile" << std::endl;
}
Missile::Event Missile::advance(const game::State *state, float dt)
{
glm::vec2 gravityForce = glm::vec2(0.0, 0.0);
for (const Player *other : state->players) {
if (other->ship != nullptr && other != player) {
glm::vec2 diff = other->ship->position - position;
float dist = glm::length(diff);
if (dist <= other->ship->radius) {
// TODO: collect all hits and return the first one only
// TODO: find exact hit position!
return Missile::Event(position, player->id, other->id);
}
}
}
// get forces
for (const Planet *planet : state->planets) {
glm::vec2 diff = planet->position - position;
float dist = glm::length(diff);
if (dist <= planet->radius) {
// TODO: collect all hits and return the first one only
// TODO: find exact hit position!
return Missile::Event(position, Missile::HitObject::HitPlanet);
}
dist *= 20.0;
if (dist > 0.001) {
float G = 0.1;
gravityForce += G * diff / (1.0f + dist*dist);
}
}
// simple (and bad) euler integration.
position += 0.5f * gravityForce*dt*dt + velocity*dt;
velocity += gravityForce * dt;
//const float thr = 0.01;
//float s = glm::length(velocity);
//if (s > thr) {
// velocity = glm::normalize(velocity) * thr;
//}
glm::vec2 nextPos = position + velocity;
// TODO: collision checks
position = nextPos;
// check if distance to center of the universe is getting too big
float distToCenter = glm::length(position);
if (distToCenter > state->maxMissileDistance()) {
return Missile::Event(position, Missile::HitObject::LeftUniverse);
}
return Missile::Event(position);
}
}