diff --git a/platformer/assets/scenes/level1.cubos b/platformer/assets/scenes/level1.cubos index efd916f..3ecc2af 100644 --- a/platformer/assets/scenes/level1.cubos +++ b/platformer/assets/scenes/level1.cubos @@ -28,20 +28,22 @@ "demo::Mover": { "from": { "x": -10, - "y": -10, + "y": 5, "z": -5 }, "to": { - "x": -10, - "y": 10, + "x": -20, + "y": 0, "z": 5 }, - "duration": 5.0 + "speed": 10.0 } }, "platform-2.base": { - "cubos::engine::Position": { - "x": 10 + "demo::Mover": { + "from": { + "x": 10 + } } }, "sun": { diff --git a/platformer/assets/scenes/platform.cubos b/platformer/assets/scenes/platform.cubos index c620262..f2ee7cf 100644 --- a/platformer/assets/scenes/platform.cubos +++ b/platformer/assets/scenes/platform.cubos @@ -16,8 +16,17 @@ "y": 0.5, "z": 8 }, + "demo::Mover": { + "speed": 0.0 + }, "cubos::engine::Collider": {}, - "cubos::engine::PhysicsVelocity": {} + "cubos::engine::PhysicsVelocity": {}, + "cubos::engine::PhysicsMass": { + "mass": 1.0, + "inverseMass": 1.0 + }, + "cubos::engine::PreviousPosition": {}, + "cubos::engine::AccumulatedCorrection": {} } } } \ No newline at end of file diff --git a/platformer/src/mover/mover.cpp b/platformer/src/mover/mover.cpp index bd58b96..5cc720b 100644 --- a/platformer/src/mover/mover.cpp +++ b/platformer/src/mover/mover.cpp @@ -10,8 +10,7 @@ CUBOS_REFLECT_IMPL(demo::Mover) return cubos::core::ecs::ComponentTypeBuilder("demo::Mover") .withField("from", &Mover::from) .withField("to", &Mover::to) - .withField("duration", &Mover::duration) - .withField("time", &Mover::time) + .withField("speed", &Mover::speed) .withField("direction", &Mover::direction) .build(); } diff --git a/platformer/src/mover/mover.hpp b/platformer/src/mover/mover.hpp index b03eac5..c651097 100644 --- a/platformer/src/mover/mover.hpp +++ b/platformer/src/mover/mover.hpp @@ -12,8 +12,8 @@ namespace demo glm::vec3 from; glm::vec3 to; - float duration = 2.0F; - float time = 0.0F; + float speed = 2.0F; bool direction = false; + bool initialized = false; }; } // namespace demo diff --git a/platformer/src/mover/plugin.cpp b/platformer/src/mover/plugin.cpp index 168f0d1..c1c4253 100644 --- a/platformer/src/mover/plugin.cpp +++ b/platformer/src/mover/plugin.cpp @@ -3,9 +3,11 @@ #include #include +#include #include +using cubos::core::data::old::Debug; using cubos::core::ecs::Query; using cubos::core::ecs::Read; using cubos::core::ecs::Write; @@ -18,21 +20,33 @@ static void moverSystem(Query, Write, Writetime += deltaTime->value * (mover->direction ? 1.0F : -1.0F); - if (mover->time > mover->duration || mover->time < 0.0F) + if (!mover->initialized) + { + mover->initialized = true; + mover->direction = true; + position->vec = mover->from; + } + + glm::vec3 target = mover->direction ? mover->to : mover->from; + if (glm::distance(position->vec, target) < 1.0F) { - mover->time = glm::clamp(mover->time, 0.0F, mover->duration); mover->direction = !mover->direction; + target = mover->direction ? mover->to : mover->from; } - auto prev = position->vec; - position->vec = glm::mix(mover->from, mover->to, mover->time / mover->duration); - velocity->velocity = (position->vec - prev) / deltaTime->value; + if (target == position->vec) + { + velocity->velocity = {0.0F, 0.0F, 0.0F}; + } + else + { + velocity->velocity = glm::normalize(target - position->vec) * mover->speed; + } } } void demo::moverPlugin(Cubos& cubos) { cubos.addComponent(); - cubos.system(moverSystem).before("cubos.transform.update"); + cubos.system(moverSystem).before("player.move").tagged("cubos.physics.apply_forces"); } diff --git a/platformer/src/orbit_camera/plugin.cpp b/platformer/src/orbit_camera/plugin.cpp index e2a81ce..23779c8 100644 --- a/platformer/src/orbit_camera/plugin.cpp +++ b/platformer/src/orbit_camera/plugin.cpp @@ -23,7 +23,7 @@ static void inputSystem(Read input, Query> c { camera->theta += input->axis("look-horizontal", camera->playerId) * deltaTime->value * camera->rotationSpeed; camera->phi += input->axis("look-vertical", camera->playerId) * deltaTime->value * camera->rotationSpeed; - camera->phi = glm::clamp(camera->phi, 0.1F, 179.9F); + camera->phi = glm::clamp(camera->phi, 1.0F, 89.0F); camera->distance += input->axis("look-zoom", camera->playerId) * deltaTime->value * camera->zoomSpeed; camera->distance = glm::clamp(camera->distance, 1.0F, 100.0F); } diff --git a/platformer/src/player/player.cpp b/platformer/src/player/player.cpp index 86d4309..781f929 100644 --- a/platformer/src/player/player.cpp +++ b/platformer/src/player/player.cpp @@ -8,7 +8,7 @@ CUBOS_REFLECT_IMPL(demo::Player) { return cubos::core::ecs::ComponentTypeBuilder("demo::Player") .withField("id", &Player::id) - .withField("isOnGround", &Player::isOnGround) + .withField("ground", &Player::ground) .withField("animationTime", &Player::animationTime) .withField("animationSpeed", &Player::animationSpeed) .withField("speed", &Player::speed) diff --git a/platformer/src/player/player.hpp b/platformer/src/player/player.hpp index ae0f186..adbd4c7 100644 --- a/platformer/src/player/player.hpp +++ b/platformer/src/player/player.hpp @@ -12,7 +12,6 @@ namespace demo CUBOS_REFLECT; int id = 0; - bool isOnGround = false; float animationTime = 0.0F; float animationSpeed = 1.0F; float jumpForce = 1000.0F; @@ -24,5 +23,8 @@ namespace demo cubos::core::ecs::Entity rightFoot; glm::vec3 forward = {0.0F, 0.0F, 1.0F}; glm::vec3 right = {1.0F, 0.0F, 0.0F}; + + cubos::core::ecs::Entity ground{}; + bool wasOnGround = false; }; } // namespace demo diff --git a/platformer/src/player/plugin.cpp b/platformer/src/player/plugin.cpp index 23f80c9..1f22772 100644 --- a/platformer/src/player/plugin.cpp +++ b/platformer/src/player/plugin.cpp @@ -26,30 +26,44 @@ using namespace cubos::engine; using namespace demo; -static void move(Query, Write, Write, Write> query, - Query> offsets, Read input, Read deltaTime, Write settings, - EventReader collisions) +static void collisionSystem(Query, Write> players, Query> velocities, + EventReader collisions) { for (auto collision : collisions) { - // Only handle collisions between players and other entities which are not players. - if (!query[collision.entity] /* || query[collision.other]*/) + // Only handle player collisions + if (!players[collision.entity]) { continue; } - auto [player, position, velocity, rotation] = *query[collision.entity]; + auto [player, position] = *players[collision.entity]; position->vec -= collision.normal * collision.penetration; - velocity->velocity -= collision.normal * glm::dot(collision.normal, velocity->velocity); + + auto [playerVelocity] = *velocities[collision.entity]; + playerVelocity->velocity -= collision.normal * glm::dot(collision.normal, playerVelocity->velocity); if (collision.normal.y < -0.1F) { - player->isOnGround = true; + player->ground = collision.other; + player->wasOnGround = true; + } + else + { + player->ground = Entity{}; + player->wasOnGround = false; } } +} + +static void move(Query, Write, Write> query, Query> velocities, + Query> offsets, Read input, Read deltaTime, Write settings) +{ - for (auto [entity, player, position, velocity, rotation] : query) + for (auto [entity, player, position, rotation] : query) { + auto [velocity] = *velocities[entity]; + const float force = settings->getDouble("force", 5000.0F); const float dragForce = settings->getDouble("dragForce", -2000.0F); const float rotationSpeed = settings->getDouble("rotationSpeed", 0.02F); @@ -58,27 +72,28 @@ static void move(Query, Write, Write, W // auto moveHorizontal = input->axis("horizontal", player->id); auto jump = input->pressed("jump", player->id); - if (player->isOnGround) + glm::vec3 targetTorso = {0.0F, 0.0F, 0.0F}; + glm::vec3 targetLeftHand = {7.0F, -3.0F, 0.0F}; + glm::vec3 targetRightHand = {-7.0F, -3.0F, 0.0F}; + glm::vec3 targetLeftFoot = {3.5F, -10.0F, 1.0F}; + glm::vec3 targetRightFoot = {-3.5F, -10.0F, 1.0F}; + + if (!player->ground.isNull()) { glm::vec3 newVelocity = moveVertical * player->forward * player->speed; - velocity->velocity.x = newVelocity.x; - velocity->velocity.z = newVelocity.z; + if (velocities[player->ground]) + { + auto [groundVelocity] = *velocities[player->ground]; + velocity->velocity = glm::max(velocity->velocity, groundVelocity->velocity); + } + velocity->velocity.x += newVelocity.x; + velocity->velocity.z += newVelocity.z; if (jump) { velocity->impulse += glm::vec3{0.0F, 1.0F, 0.0F} * player->jumpForce; - player->isOnGround = false; } - } - - glm::vec3 targetTorso = {0.0F, 0.0F, 0.0F}; - glm::vec3 targetLeftHand = {7.0F, -3.0F, 0.0F}; - glm::vec3 targetRightHand = {-7.0F, -3.0F, 0.0F}; - glm::vec3 targetLeftFoot = {3.5F, -10.0F, 1.0F}; - glm::vec3 targetRightFoot = {-3.5F, -10.0F, 1.0F}; - if (player->isOnGround) - { player->animationTime += glm::sign(moveVertical) * deltaTime->value * player->speed * player->animationSpeed; @@ -97,7 +112,14 @@ static void move(Query, Write, Write, W targetTorso.y += glm::sin(player->animationTime) * 0.5; } - player->isOnGround = false; + if (!player->wasOnGround) + { + player->ground = Entity{}; + } + else + { + player->wasOnGround = false; + } } else { @@ -124,10 +146,9 @@ static void move(Query, Write, Write, W } } -// handle dead - void demo::playersPlugin(Cubos& cubos) { cubos.addComponent(); cubos.system(move).tagged("player.move").tagged("cubos.physics.apply_forces").before("cubos.transform.update"); + cubos.system(collisionSystem).after("player.move").tagged("cubos.physics.apply_forces"); }