diff options
author | Andy Belle-Isle <drumsetmonkey@gmail.com> | 2019-10-09 02:40:20 -0400 |
---|---|---|
committer | Andy Belle-Isle <drumsetmonkey@gmail.com> | 2019-10-09 02:40:20 -0400 |
commit | f8b062e3fe43ece368c99d1083a929de92b7cff2 (patch) | |
tree | ad6d5d85a0190165f100e505f259a8b4d5aa4915 | |
parent | a422f32613441b5313e4a3bb0fab61f8cb87914c (diff) |
Started more advanced collision detetction
-rw-r--r-- | Scripts/init.lua | 16 | ||||
-rw-r--r-- | src/components/Position.hpp | 2 | ||||
-rw-r--r-- | src/engine.cpp | 17 | ||||
-rw-r--r-- | src/physics.cpp | 50 | ||||
-rw-r--r-- | src/script/vectors.cpp | 6 | ||||
-rw-r--r-- | src/world.cpp | 121 | ||||
-rw-r--r-- | src/world.hpp | 6 |
7 files changed, 153 insertions, 65 deletions
diff --git a/Scripts/init.lua b/Scripts/init.lua index da2517f..80fee32 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -4,20 +4,24 @@ player = { Player = 0, EventListeners = { MoveLeftPressed = function(self) - self.Velocity.x = self.Velocity.x - 3.0 + --self.Velocity.x = self.Velocity.x - 3.0 + self.Velocity.y = self.Velocity.y - 1.0 self.Render.flipx = true; end, MoveLeftReleased = function(self) -- TODO can't put text at world coordinates right now --game.puts("default", self.Position.x, self.Position.y+100, "Hey. Hag?") - self.Velocity.x = self.Velocity.x + 3.0 + --self.Velocity.x = self.Velocity.x + 3.0 + self.Velocity.y = self.Velocity.y + 1.0 end, MoveRightPressed = function(self) - self.Velocity.x = self.Velocity.x + 3.0 + --self.Velocity.x = self.Velocity.x + 3.0 + self.Velocity.y = self.Velocity.y + 1.0 self.Render.flipx = false; end, MoveRightReleased = function(self) - self.Velocity.x = self.Velocity.x - 3.0 + --self.Velocity.x = self.Velocity.x - 3.0 + self.Velocity.y = self.Velocity.y - 1.0 end, JumpKeyPressed = function(self) if self.Physics.standing == true then @@ -28,7 +32,7 @@ player = { end }, Position = { - 15.0, 10.0 + 15.0, 20.0 }, Velocity = { x = 0.0, @@ -91,7 +95,7 @@ ball = { dofile("Scripts/world.lua") playerSpawn = game.spawn(player); -game.spawn(ball); +--game.spawn(ball); ------------------- -- SERIALIZING -- diff --git a/src/components/Position.hpp b/src/components/Position.hpp index bfa4b41..1c649b4 100644 --- a/src/components/Position.hpp +++ b/src/components/Position.hpp @@ -26,7 +26,7 @@ struct Position : Component<Position> public: float x, y, z; - Position(float _x = 0, float _y = 0, float _z = 0) : + Position(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) : x(_x), y(_y), z(_z) {} Position FromLua(sol::object ref) diff --git a/src/engine.cpp b/src/engine.cpp index 81e0272..a3c4c6a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -164,10 +164,21 @@ void Engine::run(void) debugThread = std::thread([this, &fpsCounter](void) { while (shouldRun()) { - std::this_thread::sleep_for(1s); - fps = fpsCounter; + std::this_thread::sleep_for(250ms); + fps = fpsCounter*4; fpsCounter = 0; - systems.system<TextSystem>()->put("default", 0, 0, "fps: "s + std::to_string(fps)); + + systems.system<TextSystem>()-> + put("default", 0, 0, "fps: "s + std::to_string(fps)); + + entities.each<Player, Position>( + [this](entityx::Entity, Player &p, Position &pos){ + (void)p; + std::string pr = "pos: " + std::to_string(pos.x) + + "," + std::to_string(pos.y); + systems.system<TextSystem>()->put("default", 0, -24, pr); + + }); } }); diff --git a/src/physics.cpp b/src/physics.cpp index 85b929c..4567288 100644 --- a/src/physics.cpp +++ b/src/physics.cpp @@ -38,29 +38,45 @@ void PhysicsSystem::update([[maybe_unused]]entityx::EntityManager& entities, bool has_phys = e.has_component<Physics>(); - pos.x += (vel.x * dt/1000.0); - pos.y += (vel.y * dt/1000.0); - // If the entity has physics if (has_phys) { + Physics *p = e.component<Physics>().get(); - float fallPosition = currentWorld->getHeight(pos.x, pos.y, 0.0); + glm::vec3 start = pos.vec(); + + glm::vec3 goal = pos.vec(); + goal.x += (vel.x * dt/1000.0); + goal.y += (vel.y * dt/1000.0); + + glm::vec3 end = currentWorld->collide(start, goal, *p); + (void)end; + + //std::cout << end.x << "," << end.y << std::endl; + + pos.x = goal.x; + pos.y = goal.y; + pos.z = goal.z; + + //float fallPosition = currentWorld->getHeight(pos.x, pos.y, 0.0); - Physics *p = e.component<Physics>().get(); // TODO only make this occur when the entity has a hitbox - if (pos.y == fallPosition) { - p->standing = true; - return; - } + //if (pos.y == fallPosition) { + // p->standing = true; + // return; + //} - if (pos.y < fallPosition) { - pos.y = fallPosition; - vel.y = 0; - p->standing = true; - } else { - p->standing = false; - vel.y -= 32.2 * (dt/1000.0f); - } + //if (pos.y < fallPosition) { + // pos.y = fallPosition; + // vel.y = 0; + // p->standing = true; + //} else { + // p->standing = false; + //if (p->gravity) + // vel.y -= 32.2 * (dt/1000.0f); + //} + } else { + pos.x += (vel.x * dt/1000.0); + pos.y += (vel.y * dt/1000.0); } }); } diff --git a/src/script/vectors.cpp b/src/script/vectors.cpp index 4f8b344..aa27aad 100644 --- a/src/script/vectors.cpp +++ b/src/script/vectors.cpp @@ -34,7 +34,7 @@ namespace Script template<> glm::vec2 to<glm::vec2>(sol::object obj) { - glm::vec2 toReturn; + glm::vec2 toReturn(0.0f); if (obj.get_type() == sol::type::table) { sol::table table = obj; @@ -60,7 +60,7 @@ namespace Script template<> glm::vec3 to<glm::vec3>(sol::object obj) { - glm::vec3 toReturn; + glm::vec3 toReturn(0.0f); if (obj.get_type() == sol::type::table) { sol::table table = obj; @@ -84,7 +84,7 @@ namespace Script template<> glm::vec4 to<glm::vec4>(sol::object obj) { - glm::vec4 toReturn; + glm::vec4 toReturn(0.0f); if (obj.get_type() == sol::type::table) { sol::table table = obj; diff --git a/src/world.cpp b/src/world.cpp index 8987eac..61a30de 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -134,55 +134,110 @@ double World::getHeight(double x, double y, double z) return 0; } -std::vector<std::pair<glm::vec2, glm::vec2>> -World::getIntersectingPlanes(glm::vec2 origin, glm::vec2 dest) +bool World::isSolid(glm::vec3 pos) { - (void)origin; - (void)dest; - //glm::ivec2 worldOrigin = origin*unitSize; - //glm::ivec2 worldDest = dest*unitSize; + for (auto &l : solidLayers) { + if (pos.z == l->drawLayer) { + int wx = pos.x * unitSize; + int wy = pos.y * unitSize; + if (wx < 0 || wy < 0) return true; - return std::vector<std::pair<glm::vec2, glm::vec2>>(); + return l->hitbox[wx][wy]; + } + } + return false; } -glm::vec3 World::collide(glm::vec3 &start, glm::vec3 &end, Physics &phys) +std::vector<glm::vec3> +World::getIntersectingPlanes(glm::vec3 origin, Physics &phys) { - (void)start; - (void)end; - (void)phys; - for (auto &l : solidLayers) { - if (end.z == l->drawLayer) { - glm::vec2 len = end-start; - glm::vec2 dir = glm::normalize(len); - float step = 1.0f/unitSize; + std::vector<glm::vec3> planes; - // TODO move this - glm::vec2 pos = start; + glm::vec3 goal = origin; - for (float i = 0; i < len.length(); i+=step) { - pos += dir; + origin.x += phys.corners[0].x; + origin.y += phys.corners[0].y; - if (dir.x > 0.0f) { - // Moving to the right - //glm::vec2 origin = pos + phys.corners[1]; // bottom right - //glm::vec2 orDir = glm::vec2(0, 1); + goal.x += phys.corners[3].x; + goal.y += phys.corners[3].y; - } else if (dir.x < 0.0f) { - // Moving to the left - - } + float step = 1.0f/unitSize; + for (;origin.y <= goal.y; origin.y += step){ + for (;origin.x <= goal.x; origin.x += step) { + if (isSolid(origin)) { + planes.push_back(origin); + } + } + } - if (dir.y > 0.0f) { - // Moving upwards + return planes; +} - } else if (dir.y < 0.0f) { - // Moving downwards +glm::vec3 World::collide(glm::vec3 &start, glm::vec3 &end, Physics &phys) +{ + // How far to push the entity to unintersect with the world + glm::vec3 push(0); + for (auto &l : solidLayers) { + if (start.z == l->drawLayer) { + glm::vec3 len = end-start; + glm::vec3 dir = glm::normalize(len); + float step = 1.0f/unitSize; + glm::vec3 pos = start; + + for (float i = 0.0f; i < glm::length(len); i+=step, pos+=dir) { + // Get all colliding world spaces + std::vector<glm::vec3> inter = getIntersectingPlanes(pos, phys); + + if (i == 0.0f) + std::cout << inter.size() << std::endl; + + // If there are no colliding world spaces, don't bother + if (inter.size()) { + if (dir.x > 0.0f) { + // Moving to the right + int closest = inter.at(0).x; + for (auto &p : inter) { + if (p.x < closest) + closest = p.x; + } + push.x -= abs(closest - (pos.x + phys.corners[1].x)); + + } else if (dir.x < 0.0f) { + // Moving to the left + int closest = inter.at(0).x; + for (auto &p : inter) { + if (p.x > closest) + closest = p.x; + } + push.x += abs(closest - (pos.x + phys.corners[0].x)); + } + + if (dir.y > 0.0f) { + // Moving upwards + int closest = inter.at(0).y; + for (auto &p : inter) { + if (p.y < closest) + closest = p.y; + } + push.y -= abs(closest - (pos.y + phys.corners[2].y)); + } else if (dir.y < 0.0f) { + // Moving downwards + int closest = inter.at(0).y; + for (auto &p : inter) { + if (p.y > closest) + closest = p.y; + } + push.y += abs(closest - (pos.y + phys.corners[0].y)); + } + + if (push != glm::vec3(0.0f)) + return pos + push; } } } } - return glm::vec3(0); + return end; } diff --git a/src/world.hpp b/src/world.hpp index 0c1275e..2d11706 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -128,8 +128,10 @@ private: std::vector<std::shared_ptr<SolidLayer>> solidLayers; std::vector<std::shared_ptr<Layer>> drawLayers; - std::vector<std::pair<glm::vec2, glm::vec2>> - getIntersectingPlanes(glm::vec2 origin, glm::vec2 dir); + std::vector<glm::vec3> + getIntersectingPlanes(glm::vec3 origin, Physics &phys); + + bool isSolid(glm::vec3 pos); protected: // RENDER |