85 lines
2.6 KiB
C++
85 lines
2.6 KiB
C++
#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, Hit::Planet);
|
|
}
|
|
|
|
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, Hit::BorderOfUniverse);
|
|
}
|
|
|
|
return Missile::Event(position);
|
|
}
|
|
}
|