From 9ce106c179e702d43d63c5f1a7f1388ae45833f0 Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Sun, 2 Oct 2016 21:06:02 +0200 Subject: [PATCH] added test script to lauch rockets, nicer explosions. --- .../renderer_polygon_3d.cpp | 62 ++++++++++++++++--- .../renderer_polygon_3d.hpp | 5 +- game/state/explosion.cpp | 17 +++++ game/state/explosion.hpp | 15 +---- game/state/missile.cpp | 8 +-- game/state/missile.hpp | 16 ++--- game/state/state.cpp | 3 +- game/state/state.hpp | 1 + game/util.cpp | 12 ++++ game/util.hpp | 8 ++- test/amok.sh | 15 +++++ 11 files changed, 127 insertions(+), 35 deletions(-) create mode 100755 test/amok.sh diff --git a/game/renderer_polygon_3d/renderer_polygon_3d.cpp b/game/renderer_polygon_3d/renderer_polygon_3d.cpp index d4f2d8e..247ab85 100644 --- a/game/renderer_polygon_3d/renderer_polygon_3d.cpp +++ b/game/renderer_polygon_3d/renderer_polygon_3d.cpp @@ -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.003; @@ -124,7 +127,13 @@ namespace endofthejedi { glm::vec3 pos = glm::vec3(explCenter, 0.0) + glm::ballRand(explCoreSize); glm::vec3 v = glm::ballRand(maxVelocity); - v *= util::randf_0_1() * util::randf_0_1() * util::randf_0_1(); + + // TODO: is that good? + if (isPlanetHit) { + 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 // won't fly through planets @@ -136,7 +145,8 @@ namespace endofthejedi { const game::Planet *nearestPlanet = nullptr; for (const game::Planet *planet : m_state->planets) { 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); if (dist <= planet->radius) { isInsidePlanet = true; @@ -158,18 +168,40 @@ namespace endofthejedi { } } - if (isInsidePlanet) { + bool makeStationary = false; + + if (isInsidePlanet && isPlanetHit) { util::IntersectionTest intersect; if (!intersect.raySphere( - pos, v, - glm::vec3(nearestPlanet->position, 0.0f), nearestPlanet->radius)) + glm::vec3(explCenter, 0.0f), v, + glm::vec3(nearestPlanet->position, 0.0f), nearestPlanet->radius)) { + makeStationary = true; //std::cout<<"warning: intersection should be valid!" << std::endl; // TODO: must be as they lie on a plane and the dist is < as // the radius. // handle if this is wrong. } 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 // center and planet surface //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; //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); @@ -218,12 +260,16 @@ namespace endofthejedi { } 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) { - // 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 rm; diff --git a/game/renderer_polygon_3d/renderer_polygon_3d.hpp b/game/renderer_polygon_3d/renderer_polygon_3d.hpp index acdc851..5f0f1b6 100644 --- a/game/renderer_polygon_3d/renderer_polygon_3d.hpp +++ b/game/renderer_polygon_3d/renderer_polygon_3d.hpp @@ -42,7 +42,10 @@ namespace endofthejedi { 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); diff --git a/game/state/explosion.cpp b/game/state/explosion.cpp index e69de29..0f8239b 100644 --- a/game/state/explosion.cpp +++ b/game/state/explosion.cpp @@ -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) + { + } +} + diff --git a/game/state/explosion.hpp b/game/state/explosion.hpp index 9e8145d..6d6d295 100644 --- a/game/state/explosion.hpp +++ b/game/state/explosion.hpp @@ -12,26 +12,17 @@ namespace game { */ class Explosion { public: - Explosion(const glm::vec2 &pos, 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++; - } + Explosion(size_t id, const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit, float maxAge=1.0); + const size_t id; const Hit hit; // kind of the explosion depends on the hit type 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 // age (in seconds) when the explosion is not visible // anymore and will disappear afterwards const float maxAge; const float maxRadius; // current radius depends on time. - - size_t id; }; } diff --git a/game/state/missile.cpp b/game/state/missile.cpp index 07e61c1..5b7462e 100644 --- a/game/state/missile.cpp +++ b/game/state/missile.cpp @@ -37,7 +37,7 @@ namespace game { 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); + return Missile::Event(position, velocity, player->id, other->id); } } } @@ -49,7 +49,7 @@ namespace game { if (dist <= planet->radius) { // TODO: collect all hits and return the first one only // TODO: find exact hit position! - return Missile::Event(position, planet->id); + return Missile::Event(position, velocity, planet->id); } dist *= 20.0; @@ -77,9 +77,9 @@ namespace game { // 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, velocity, Hit::BorderOfUniverse); } - return Missile::Event(position); + return Missile::Event(position, velocity); } } diff --git a/game/state/missile.hpp b/game/state/missile.hpp index c7aa1df..bd7beb5 100644 --- a/game/state/missile.hpp +++ b/game/state/missile.hpp @@ -22,23 +22,24 @@ namespace game { // stops existing afterwards. class Event { public: - Event(const glm::vec2 &pos) - : Event(pos, Hit::Nothing) + Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity) + : Event(pos, missileVelocity, Hit::Nothing) { } - Event(const glm::vec2 &pos, Hit hit) - : hit(hit), position(pos) + Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, Hit hit) + : 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; } - Event(const glm::vec2 &pos, int playerIdKiller, int playerIdVictim) - : Event(pos, Hit::Ship) + Event(const glm::vec2 &pos, const glm::vec2 &missileVelocity, int playerIdKiller, int playerIdVictim) + : Event(pos, missileVelocity, Hit::Ship) { this->playerIdKiller = playerIdKiller; this->playerIdVictim = playerIdVictim; @@ -46,6 +47,7 @@ namespace game { Hit hit; glm::vec2 position; + glm::vec2 missileVelocity; // if a player was hit, these are valid. int playerIdKiller; diff --git a/game/state/state.cpp b/game/state/state.cpp index 7276cd1..be541ed 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -36,6 +36,7 @@ namespace game { m_defaultEnergy = 10.0; m_maxNumTraces = 10; m_developerMode = devMode; + m_nextExplosionId = 0; setPlayingFieldCenter(0, 0); @@ -441,7 +442,7 @@ namespace game { 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) diff --git a/game/state/state.hpp b/game/state/state.hpp index 2850ff9..da6a656 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -141,6 +141,7 @@ namespace game { float m_defaultEnergy; int m_nextId; int m_maxNumTraces; + size_t m_nextExplosionId; float m_time; bool m_developerMode; diff --git a/game/util.cpp b/game/util.cpp index 3556228..531775a 100644 --- a/game/util.cpp +++ b/game/util.cpp @@ -45,12 +45,24 @@ namespace util { float IntersectionTest::distance() const { assert(m_valid); return m_distance; } 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( const glm::vec3 &rayPos, const glm::vec3 &rayDir, const glm::vec3 &spherePos, float sphereRadius) { m_valid = false; + // TODO: save if hit. + m_valid = true; + m_rayPos = rayPos; + m_rayDir = rayDir; + m_distance = 0.5; + // TODO: get code return m_valid; diff --git a/game/util.hpp b/game/util.hpp index ff80995..1bd7bd3 100644 --- a/game/util.hpp +++ b/game/util.hpp @@ -28,6 +28,8 @@ namespace util { // intersection distance float distance() const; + glm::vec3 pointAtDistance(float d); + // returns true if there's an interseciton. bool valid() const; @@ -38,7 +40,9 @@ namespace util { const glm::vec3 &spherePos, float sphereRadius); private: - bool m_valid; - float m_distance; + bool m_valid; + float m_distance; + glm::vec3 m_rayPos; + glm::vec3 m_rayDir; }; } diff --git a/test/amok.sh b/test/amok.sh new file mode 100755 index 0000000..b71afeb --- /dev/null +++ b/test/amok.sh @@ -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) +