added test script to lauch rockets, nicer explosions.

This commit is contained in:
Andreas Ortmann 2016-10-02 21:06:02 +02:00
parent 4712926be2
commit 9ce106c179
11 changed files with 127 additions and 35 deletions

View file

@ -94,7 +94,10 @@ namespace endofthejedi {
} }
} }
void RendererPolygon3d::addExplosionEffect(size_t id, const glm::vec2 &explCenter, size_t n, float duration) void RendererPolygon3d::addExplosionEffect(
size_t id, const glm::vec2 &explCenter, const glm::vec2 &missileVelocity,
bool isPlanetHit,
size_t n, float duration)
{ {
//float particleRadius = 0.005; //float particleRadius = 0.005;
//float particleRadius = 0.003; //float particleRadius = 0.003;
@ -124,7 +127,13 @@ namespace endofthejedi {
glm::vec3 pos = glm::vec3(explCenter, 0.0) + glm::ballRand(explCoreSize); glm::vec3 pos = glm::vec3(explCenter, 0.0) + glm::ballRand(explCoreSize);
glm::vec3 v = glm::ballRand(maxVelocity); glm::vec3 v = glm::ballRand(maxVelocity);
// TODO: is that good?
if (isPlanetHit) {
v *= util::randf_0_1() * util::randf_0_1() * util::randf_0_1(); v *= util::randf_0_1() * util::randf_0_1() * util::randf_0_1();
} else {
v *= util::randf_0_1();
}
// find collisions with planetns and limit max distance so particles // find collisions with planetns and limit max distance so particles
// won't fly through planets // won't fly through planets
@ -136,7 +145,8 @@ namespace endofthejedi {
const game::Planet *nearestPlanet = nullptr; const game::Planet *nearestPlanet = nullptr;
for (const game::Planet *planet : m_state->planets) { for (const game::Planet *planet : m_state->planets) {
const glm::vec3 ppos3 = glm::vec3(planet->position, 0.0f); const glm::vec3 ppos3 = glm::vec3(planet->position, 0.0f);
// TODO: check if inside planet!
// TODO: that's slightly wrong. use intersection for this.
float dist = glm::distance(ppos3, pos); float dist = glm::distance(ppos3, pos);
if (dist <= planet->radius) { if (dist <= planet->radius) {
isInsidePlanet = true; isInsidePlanet = true;
@ -158,18 +168,40 @@ namespace endofthejedi {
} }
} }
if (isInsidePlanet) { bool makeStationary = false;
if (isInsidePlanet && isPlanetHit) {
util::IntersectionTest intersect; util::IntersectionTest intersect;
if (!intersect.raySphere( if (!intersect.raySphere(
pos, v, glm::vec3(explCenter, 0.0f), v,
glm::vec3(nearestPlanet->position, 0.0f), nearestPlanet->radius)) glm::vec3(nearestPlanet->position, 0.0f), nearestPlanet->radius))
{ {
makeStationary = true;
//std::cout<<"warning: intersection should be valid!" << std::endl; //std::cout<<"warning: intersection should be valid!" << std::endl;
// TODO: must be as they lie on a plane and the dist is < as // TODO: must be as they lie on a plane and the dist is < as
// the radius. // the radius.
// handle if this is wrong. // handle if this is wrong.
} else { } else {
// simple reflection, ignoring the missile velocity: this looks good enough
(void) missileVelocity;
glm::vec3 planetNormal = glm::normalize(pos - glm::vec3(nearestPlanet->position, 0.0f));
v = glm::length(v) * planetNormal;
// TODO
// considering the missile velocity is not yet working:
// set position to the intersection point between explosion
// center and planet surface
//pos = intersect.pointAtDistance(intersect.distance());
//v = glm::vec3(missileVelocity, 0.0f);
//v = v - 2.0f*glm::dot(v, planetNormal) * planetNormal;
//v *= 4.0;
//maxParticleDist = 100.0;
//v = -v;
//pos = glm::vec3(nearestPlanet->position, 0.0f) + nearestPlanet->radius*planetNormal;
// set position to the intersection point between explosion // set position to the intersection point between explosion
// center and planet surface // center and planet surface
//const glm::vec3 planetNormal = glm::vec3(glm::normalize(explCenter - nearestPlanet->position), 0.0f); //const glm::vec3 planetNormal = glm::vec3(glm::normalize(explCenter - nearestPlanet->position), 0.0f);
@ -196,6 +228,16 @@ namespace endofthejedi {
//glm::vec3 r = vc - 2.0f*glm::dot(vc, planetNormal) * planetNormal; //glm::vec3 r = vc - 2.0f*glm::dot(vc, planetNormal) * planetNormal;
//v = r; //v = r;
} }
} else if (isInsidePlanet && !isPlanetHit) {
// if a planet is just hit by explosions particles but not the
// missile itself, don't reflect the particles in the planet.
// just set them as stationary at place of explosion
makeStationary = true;
}
if (makeStationary) {
v = glm::vec3(0.0f, 0.0f, 0.0f);
pos = glm::vec3(explCenter, 0.0f);;
} }
batch->setParticle(i, pos, v, maxParticleDist); batch->setParticle(i, pos, v, maxParticleDist);
@ -218,12 +260,16 @@ namespace endofthejedi {
} }
if (!gotIt) { if (!gotIt) {
addExplosionEffect(expl->id, expl->position, 1000, 1.0); addExplosionEffect(
expl->id, expl->position,
expl->missileVelocity,
(expl->hit == game::Hit::Planet),
1000, 1.0);
} }
} }
//if (m_particles.size() == 0) { //if (m_particles.size() == 0) {
// addExplosionEffect(0, glm::vec2(0.0, 0.0), 1000, 2.0); // addExplosionEffect(0, glm::vec2(0.0, 0.0), glm::vec2(0.0, 0.0), false, 10000, 2.0);
//} //}
std::vector<ParticleBatch*> rm; std::vector<ParticleBatch*> rm;

View file

@ -42,7 +42,10 @@ namespace endofthejedi {
void addModel(const std::string &filename, PolygonModel **dest); void addModel(const std::string &filename, PolygonModel **dest);
void addExplosionEffect(size_t id, const glm::vec2 &pos, size_t n, float duration); void addExplosionEffect(
size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity,
bool hitPlanet,
size_t n, float duration);
void advanceGraphicObjects(float dt); void advanceGraphicObjects(float dt);

View file

@ -0,0 +1,17 @@
#include "explosion.hpp"
namespace game {
size_t s_id_counter = 0;
Explosion::Explosion(size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit, float maxAge)
: id(id)
, hit(hit)
, position(pos)
, missileVelocity(missileVelocity)
, age(0.0)
, maxAge(maxAge * (1.0 + 0.1*util::randf_0_1()))
, maxRadius(0.05)
{
}
}

View file

@ -12,26 +12,17 @@ namespace game {
*/ */
class Explosion { class Explosion {
public: public:
Explosion(const glm::vec2 &pos, Hit hit, float maxAge=1.0) Explosion(size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit, float maxAge=1.0);
: hit(hit)
, position(pos)
, age(0.0)
, maxAge(maxAge * (1.0 + 0.1*util::randf_0_1()))
, maxRadius(0.05)
{
static size_t id_counter = 0;
id = id_counter++;
}
const size_t id;
const Hit hit; // kind of the explosion depends on the hit type const Hit hit; // kind of the explosion depends on the hit type
const glm::vec2 position; // position where it starts const glm::vec2 position; // position where it starts
const glm::vec2 missileVelocity; // impact velocity of the missile
float age; // age (in seconsd) of the explosion float age; // age (in seconsd) of the explosion
// age (in seconds) when the explosion is not visible // age (in seconds) when the explosion is not visible
// anymore and will disappear afterwards // anymore and will disappear afterwards
const float maxAge; const float maxAge;
const float maxRadius; // current radius depends on time. const float maxRadius; // current radius depends on time.
size_t id;
}; };
} }

View file

@ -37,7 +37,7 @@ namespace game {
if (dist <= other->ship->radius) { if (dist <= other->ship->radius) {
// TODO: collect all hits and return the first one only // TODO: collect all hits and return the first one only
// TODO: find exact hit position! // TODO: find exact hit position!
return Missile::Event(position, player->id, other->id); return Missile::Event(position, velocity, player->id, other->id);
} }
} }
} }
@ -49,7 +49,7 @@ namespace game {
if (dist <= planet->radius) { if (dist <= planet->radius) {
// TODO: collect all hits and return the first one only // TODO: collect all hits and return the first one only
// TODO: find exact hit position! // TODO: find exact hit position!
return Missile::Event(position, planet->id); return Missile::Event(position, velocity, planet->id);
} }
dist *= 20.0; dist *= 20.0;
@ -77,9 +77,9 @@ namespace game {
// check if distance to center of the universe is getting too big // check if distance to center of the universe is getting too big
float distToCenter = glm::length(position); float distToCenter = glm::length(position);
if (distToCenter > state->maxMissileDistance()) { if (distToCenter > state->maxMissileDistance()) {
return Missile::Event(position, Hit::BorderOfUniverse); return Missile::Event(position, velocity, Hit::BorderOfUniverse);
} }
return Missile::Event(position); return Missile::Event(position, velocity);
} }
} }

View file

@ -22,23 +22,24 @@ namespace game {
// stops existing afterwards. // stops existing afterwards.
class Event { class Event {
public: public:
Event(const glm::vec2 &pos) Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity)
: Event(pos, Hit::Nothing) : Event(pos, missileVelocity, Hit::Nothing)
{ {
} }
Event(const glm::vec2 &pos, Hit hit) Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit)
: hit(hit), position(pos) : hit(hit), position(pos), missileVelocity(missileVelocity)
{ {
} }
Event(const glm::vec2 &pos, int planetId) : Event(pos, Hit::Planet) Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, int planetId)
: Event(pos, missileVelocity, Hit::Planet)
{ {
this->planetId = planetId; this->planetId = planetId;
} }
Event(const glm::vec2 &pos, int playerIdKiller, int playerIdVictim) Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, int playerIdKiller, int playerIdVictim)
: Event(pos, Hit::Ship) : Event(pos, missileVelocity, Hit::Ship)
{ {
this->playerIdKiller = playerIdKiller; this->playerIdKiller = playerIdKiller;
this->playerIdVictim = playerIdVictim; this->playerIdVictim = playerIdVictim;
@ -46,6 +47,7 @@ namespace game {
Hit hit; Hit hit;
glm::vec2 position; glm::vec2 position;
glm::vec2 missileVelocity;
// if a player was hit, these are valid. // if a player was hit, these are valid.
int playerIdKiller; int playerIdKiller;

View file

@ -36,6 +36,7 @@ namespace game {
m_defaultEnergy = 10.0; m_defaultEnergy = 10.0;
m_maxNumTraces = 10; m_maxNumTraces = 10;
m_developerMode = devMode; m_developerMode = devMode;
m_nextExplosionId = 0;
setPlayingFieldCenter(0, 0); setPlayingFieldCenter(0, 0);
@ -441,7 +442,7 @@ namespace game {
return; return;
} }
explosions.push_back(new Explosion(evt->position, evt->hit)); explosions.push_back(new Explosion(m_nextExplosionId++, evt->position, evt->missileVelocity, evt->hit));
} }
void State::advanceTraceAges(float dt) void State::advanceTraceAges(float dt)

View file

@ -141,6 +141,7 @@ namespace game {
float m_defaultEnergy; float m_defaultEnergy;
int m_nextId; int m_nextId;
int m_maxNumTraces; int m_maxNumTraces;
size_t m_nextExplosionId;
float m_time; float m_time;
bool m_developerMode; bool m_developerMode;

View file

@ -45,12 +45,24 @@ namespace util {
float IntersectionTest::distance() const { assert(m_valid); return m_distance; } float IntersectionTest::distance() const { assert(m_valid); return m_distance; }
bool IntersectionTest::valid() const { return m_valid; } bool IntersectionTest::valid() const { return m_valid; }
glm::vec3 IntersectionTest::pointAtDistance(float d)
{
assert(m_valid);
return m_rayPos + m_rayDir * d;
}
bool IntersectionTest::raySphere( bool IntersectionTest::raySphere(
const glm::vec3 &rayPos, const glm::vec3 &rayDir, const glm::vec3 &rayPos, const glm::vec3 &rayDir,
const glm::vec3 &spherePos, float sphereRadius) const glm::vec3 &spherePos, float sphereRadius)
{ {
m_valid = false; m_valid = false;
// TODO: save if hit.
m_valid = true;
m_rayPos = rayPos;
m_rayDir = rayDir;
m_distance = 0.5;
// TODO: get code // TODO: get code
return m_valid; return m_valid;

View file

@ -28,6 +28,8 @@ namespace util {
// intersection distance // intersection distance
float distance() const; float distance() const;
glm::vec3 pointAtDistance(float d);
// returns true if there's an interseciton. // returns true if there's an interseciton.
bool valid() const; bool valid() const;
@ -40,5 +42,7 @@ namespace util {
private: private:
bool m_valid; bool m_valid;
float m_distance; float m_distance;
glm::vec3 m_rayPos;
glm::vec3 m_rayDir;
}; };
} }

15
test/amok.sh Executable file
View file

@ -0,0 +1,15 @@
#!/usr/bin/env python3
import os
import random
import time
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("192.168.0.191", 3490))
for i in range(100):
a = random.randint(0, 360)
msg = str(a) + " \r\n"
s.send(msg.encode())
time.sleep(0.1)