From 60b610d11122a3a6a1cb438ed7754fd2180eb0c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D1=8C=D0=B1=D0=B5=D1=80=D1=82=20=D0=93=D0=B0?= =?UTF-8?q?=D0=B4=D0=B8=D0=B5=D0=B2?= Date: Sun, 2 Mar 2025 21:46:38 +0600 Subject: [PATCH 1/4] kolliziya dobavlena 2 krovat --- BoundaryBox.h | 83 +++++++++++++- GameObjectManager.cpp | 254 +++++++++++++++++++++--------------------- GameObjectManager.h | 5 +- 3 files changed, 214 insertions(+), 128 deletions(-) diff --git a/BoundaryBox.h b/BoundaryBox.h index cede401..d90c672 100644 --- a/BoundaryBox.h +++ b/BoundaryBox.h @@ -1,7 +1,18 @@ #pragma once #include "Math.h" +#include +#include namespace ZL { + +// Базовый класс для всех коллизий +class Collidable { +public: + virtual bool checkCollision(const Vector3f& position) const = 0; + virtual ~Collidable() = default; +}; + +// Прямоугольная граница комнаты class BoundaryBox { public: BoundaryBox(float width, float height) @@ -17,4 +28,74 @@ private: float halfWidth; float halfHeight; }; -} + +// Круглая коллизия для объектов +class CircleCollider : public Collidable { +public: + CircleCollider(const Vector3f& center, float radius) + : center(center) + , radius(radius) {} + + bool checkCollision(const Vector3f& position) const override { + float dx = position.v[0] - center.v[0]; + float dz = position.v[2] - center.v[2]; + return (dx * dx + dz * dz) <= (radius * radius); + } + + void setPosition(const Vector3f& newPos) { center = newPos; } + void setRadius(float newRadius) { radius = newRadius; } + +private: + Vector3f center; + float radius; +}; + +// Прямоугольная коллизия для объектов +class RectangleCollider : public Collidable { +public: + RectangleCollider(const Vector3f& min, const Vector3f& max) + : minPoint(min) + , maxPoint(max) {} + + bool checkCollision(const Vector3f& position) const override { + return (position.v[0] >= minPoint.v[0] && position.v[0] <= maxPoint.v[0] && + position.v[2] >= minPoint.v[2] && position.v[2] <= maxPoint.v[2]); + } + +private: + Vector3f minPoint; + Vector3f maxPoint; +}; + +// Менеджер коллизий +class CollisionManager { +public: + void setRoomBoundary(float width, float height) { + roomBoundary = std::make_unique(width, height); + } + + void addCollider(std::shared_ptr collider) { + colliders.push_back(collider); + } + + bool checkCollision(const Vector3f& position) const { + // Проверяем границы комнаты + if (roomBoundary && !roomBoundary->isInside(position)) { + return true; + } + + // Проверяем коллизии с объектами + for (const auto& collider : colliders) { + if (collider->checkCollision(position)) { + return true; + } + } + return false; + } + +private: + std::unique_ptr roomBoundary; + std::vector> colliders; +}; + +} // namespace ZL diff --git a/GameObjectManager.cpp b/GameObjectManager.cpp index 8458d4b..0985e52 100644 --- a/GameObjectManager.cpp +++ b/GameObjectManager.cpp @@ -12,8 +12,8 @@ const float GameObjectManager::INVENTORY_MARGIN = 10.0f; void GameObjectManager::initialize() { - current_room_index = 0; - objects_in_inventory = 0; + current_room_index = 0; + objects_in_inventory = 0; coneTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./conus.bmp")); @@ -28,7 +28,7 @@ void GameObjectManager::initialize() { testObjMeshMutable.data = testObjMesh; testObjMeshMutable.RefreshVBO(); - textMesh = ZL::LoadFromTextFile("./textures/mesh_first_room.txt"); + textMesh = ZL::LoadFromTextFile("./textures/mesh_first_room.txt"); // Add ZL:: namespace textMesh.Scale(10); textMesh.SwapZandY(); textMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 0.5))); @@ -37,7 +37,6 @@ void GameObjectManager::initialize() { coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace coneMesh.Scale(200); - textMeshMutable.AssignFrom(textMesh); textMeshMutable.RefreshVBO(); coneMeshMutable.AssignFrom(coneMesh); @@ -47,8 +46,8 @@ void GameObjectManager::initialize() { //bx.LoadFromFile("./violetta001.txt"); violaIdleModel.LoadFromFile("./idleviola001.txt"); violaWalkModel.LoadFromFile("./walkviolla001.txt"); + // Create active object - ActiveObject ao1; ao1.name = "book"; ao1.activeObjectMesh = ZL::LoadFromTextFile("./book001.txt"); // Add ZL:: namespace @@ -79,8 +78,6 @@ void GameObjectManager::initialize() { ao2.activeObjectScreenMeshMutable.RefreshVBO(); */ - - Room room_1; room_1.roomTexture = std::make_shared(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")); room_1.objects.push_back(ao1); @@ -92,7 +89,7 @@ void GameObjectManager::initialize() { Room room_2; room_2.roomTexture = std::make_shared(CreateTextureDataFromBmp24("./background.bmp")); room_2.sound_name = "Symphony No.6 (1st movement).ogg"; - room_2.roomLogic = createRoom2Logic(); + room_2.roomLogic = createRoom1Logic(); rooms.push_back(room_2); activeObjects = rooms[current_room_index].objects; @@ -119,9 +116,63 @@ void GameObjectManager::initialize() { AddItemToInventory("book2", std::make_shared(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")), objects_in_inventory+1); objects_in_inventory++; - //SDL_ShowCursor(SDL_DISABLE); SDL_SetRelativeMouseMode(SDL_TRUE); + + // Устанавливаем границы комнаты 800x800 + collisionMgr.setRoomBoundary(800.0f, 800.0f); + + // Создаем стены комнаты (толстые коллизии вдоль границ) + auto wallNorth = std::make_shared(Vector3f{0, 0, -350}, 50.0f); + auto wallSouth = std::make_shared(Vector3f{0, 0, 350}, 50.0f); + auto wallEast = std::make_shared(Vector3f{350, 0, 0}, 50.0f); + auto wallWest = std::make_shared(Vector3f{-350, 0, 0}, 50.0f); + + collisionMgr.addCollider(wallNorth); + collisionMgr.addCollider(wallSouth); + collisionMgr.addCollider(wallEast); + collisionMgr.addCollider(wallWest); + + // Создаем точки коллизии + auto point1 = std::make_shared(Vector3f{125.0f, 0.0f, -214.0f}, 30.0f); + auto point2 = std::make_shared(Vector3f{380.0f, 0.0f, -206.0f}, 30.0f); + auto point3 = std::make_shared(Vector3f{385.0f, 0.0f, -377.0f}, 30.0f); + auto point4 = std::make_shared(Vector3f{112.0f, 0.0f, -377.0f}, 30.0f); + + collisionMgr.addCollider(point1); + collisionMgr.addCollider(point2); + collisionMgr.addCollider(point3); + collisionMgr.addCollider(point4); + + // Создаем коллизию для кровати как прямоугольник + // Используем точки как границы прямоугольника + // Vector3f bedMin{112.0f, 0.0f, -377.0f}; // Минимальные координаты + // Vector3f bedMax{385.0f, 0.0f, 390.0f}; // Максимальные координаты + // auto bedCollider = std::make_shared(bedMin, bedMax); + // collisionMgr.addCollider(bedCollider); + + // Создаем линию коллизии по X (горизонтальная) + const float step = 20.0f; // Расстояние между точками коллизии + for(float x = 98.0f; x < 400.0f; x += step) { + auto point = std::make_shared(Vector3f{x, 0.0f, -200.0f}, 10.0f); + collisionMgr.addCollider(point); + } + + // Создаем линию коллизии по Z (вертикальная) + for(float z = -200.0f; z > -400.0f; z -= step) { + auto point = std::make_shared(Vector3f{400.0f, 0.0f, z}, 10.0f); + collisionMgr.addCollider(point); + } + + // Добавляем линию коллизии от (105, 0, -235) до (105, 0, -350) + const float lineStartZ = -235.0f; + const float lineEndZ = -350.0f; + const float stepLine = 5.0f; // Шаг между коллайдерами + const float colliderRadius = 5.0f; // Радиус каждого коллайдера + for (float z = lineStartZ; z >= lineEndZ; z -= stepLine) { + auto lineCollider = std::make_shared(Vector3f{105.0f, 0.0f, z}, colliderRadius); + collisionMgr.addCollider(lineCollider); + } } void GameObjectManager::switch_room(int index){ @@ -142,35 +193,27 @@ void GameObjectManager::switch_room(int index){ std::cout << "Current music" << rooms[current_room_index].sound_name << std::endl; } - - void GameObjectManager::handleEvent(const SDL_Event& event) { -// debug room switching + // debug room switching if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_RIGHT) { switch_room(1); } else if (event.type == SDL_MOUSEBUTTONDOWN) { - if (InventoryItem* item = GetItemSelected(true)) { + const auto highlightedObjects = aoMgr.findByHighlighted(true); - } - else { - const auto highlightedObjects = aoMgr.findByHighlighted(true); + for (auto* ao : highlightedObjects) { + if (!ao) { + continue; + } - for (auto* ao : highlightedObjects) { - if (!ao) { - continue; + AddItemToInventory(ao->name, ao->activeObjectTexturePtr, objects_in_inventory+1); + objects_in_inventory++; + + aoMgr.removeByName(ao->name); } - - AddItemToInventory(ao->name, ao->activeObjectTexturePtr, objects_in_inventory+1); - objects_in_inventory++; - - aoMgr.removeByName(ao->name); + // bx.Interpolate(animationCounter); + // animationCounter += 2; } - } -// bx.Interpolate(animationCounter); -// animationCounter += 2; - } - else if (event.type == SDL_MOUSEWHEEL) { static const float zoomstep = 1.0f; if (event.wheel.y > 0) { @@ -182,27 +225,24 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { if (Environment::zoom < zoomstep) { Environment::zoom = zoomstep; } - if (Environment::zoom > 4) - { + if (Environment::zoom > 4) { Environment::zoom = 4; } } else if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { - case SDLK_SPACE: - Environment::showMouse = !Environment::showMouse; + case SDLK_SPACE: + Environment::showMouse = !Environment::showMouse; - if (Environment::showMouse) - { - SDL_SetRelativeMouseMode(SDL_FALSE); - } - else - { - SDL_SetRelativeMouseMode(SDL_TRUE); - lastMouseX = 0; - lastMouseY = 0; - } - break; + if (Environment::showMouse) { + SDL_SetRelativeMouseMode(SDL_FALSE); + } + else { + SDL_SetRelativeMouseMode(SDL_TRUE); + lastMouseX = 0; + lastMouseY = 0; + } + break; case SDLK_ESCAPE: case SDLK_q: @@ -214,8 +254,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } - if (Environment::violaCurrentAnimation == 0) - { + if (Environment::violaCurrentAnimation == 0) { Environment::violaCurrentAnimation = 1; Environment::violaLastWalkFrame = -1; } @@ -226,8 +265,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } - if (Environment::violaCurrentAnimation == 0) - { + if (Environment::violaCurrentAnimation == 0) { Environment::violaCurrentAnimation = 1; Environment::violaLastWalkFrame = -1; } @@ -238,8 +276,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } - if (Environment::violaCurrentAnimation == 0) - { + if (Environment::violaCurrentAnimation == 0) { Environment::violaCurrentAnimation = 1; Environment::violaLastWalkFrame = -1; } @@ -250,32 +287,21 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } - if (Environment::violaCurrentAnimation == 0) - { + if (Environment::violaCurrentAnimation == 0) { Environment::violaCurrentAnimation = 1; Environment::violaLastWalkFrame = -1; } break; - case SDLK_1: case SDLK_2: - case SDLK_3: - case SDLK_4: - case SDLK_5: - case SDLK_6: - case SDLK_7: - case SDLK_8: - case SDLK_9: - { - + { + int hot_key = (event.key.keysym.sym == SDLK_1) ? 1 : 2; UnselectAllItems(); - if (InventoryItem* item = GetItemByHotkey(event.key.keysym.sym - SDLK_1 + 1)) { + if (InventoryItem* item = GetItemByHotkey(hot_key)) { item->isSelected = true; } } - break; - // ...handle other keys... } } @@ -284,10 +310,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { case SDLK_LEFT: case SDLK_a: Environment::leftPressed = false; - if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false) - { - if (Environment::violaCurrentAnimation == 1) - { + if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) { + if (Environment::violaCurrentAnimation == 1) { Environment::violaCurrentAnimation = 0; Environment::violaCurrentIdleFrame = -1; } @@ -296,10 +320,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { case SDLK_RIGHT: case SDLK_d: Environment::rightPressed = false; - if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false) - { - if (Environment::violaCurrentAnimation == 1) - { + if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) { + if (Environment::violaCurrentAnimation == 1) { Environment::violaCurrentAnimation = 0; Environment::violaCurrentIdleFrame = -1; } @@ -308,10 +330,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { case SDLK_UP: case SDLK_w: Environment::upPressed = false; - if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false) - { - if (Environment::violaCurrentAnimation == 1) - { + if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) { + if (Environment::violaCurrentAnimation == 1) { Environment::violaCurrentAnimation = 0; Environment::violaCurrentIdleFrame = -1; } @@ -320,10 +340,8 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { case SDLK_DOWN: case SDLK_s: Environment::downPressed = false; - if (Environment::leftPressed == false && Environment::rightPressed == false && Environment::upPressed == false && Environment::downPressed == false) - { - if (Environment::violaCurrentAnimation == 1) - { + if (!Environment::leftPressed && !Environment::rightPressed && !Environment::upPressed && !Environment::downPressed) { + if (Environment::violaCurrentAnimation == 1) { Environment::violaCurrentAnimation = 0; Environment::violaCurrentIdleFrame = -1; } @@ -332,49 +350,39 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { } } if (event.type == SDL_MOUSEMOTION) { - - if (Environment::showMouse == false) - { + if (!Environment::showMouse) { int mouseX, mouseY; SDL_GetRelativeMouseState(&mouseX, &mouseY); float diffX = 0.01f * mouseX; - float diffY = 0.01f * mouseY; Environment::cameraPhi += diffX; - if (Environment::settings_inverseVertical) - { + if (Environment::settings_inverseVertical) { Environment::cameraAlpha -= diffY; } - else - { + else { Environment::cameraAlpha += diffY; } - if (Environment::cameraAlpha < 0.1 * M_PI / 2.0) - { + if (Environment::cameraAlpha < 0.1 * M_PI / 2.0) { Environment::cameraAlpha = 0.1 * M_PI / 2.0; } - else if (Environment::cameraAlpha > 0.9 * M_PI / 2.0) - { + else if (Environment::cameraAlpha > 0.9 * M_PI / 2.0) { Environment::cameraAlpha = 0.9 * M_PI / 2.0; } - } - else - { + else { lastMouseX = event.motion.x; lastMouseY = event.motion.y; } } } - void GameObjectManager::updateScene(size_t ms) { const float SPEED = 0.1f; - Vector2f directionVector = { 0.f, SPEED }; //x and z + Vector2f directionVector = { 0.f, SPEED }; // x and z // Вычисляем новые координаты вектора float x_new = directionVector.v[0] * cos(Environment::cameraPhi) - directionVector.v[1] * sin(Environment::cameraPhi); @@ -384,7 +392,7 @@ void GameObjectManager::updateScene(size_t ms) { directionVector.v[0] = x_new; directionVector.v[1] = y_new; - //Only forward is allowed + // Only forward is allowed /* if (Environment::leftPressed) { Environment::cameraShift.v[0] += SPEED * ms; @@ -397,7 +405,8 @@ void GameObjectManager::updateScene(size_t ms) { } if (Environment::downPressed) { Environment::cameraShift.v[2] -= SPEED * ms; - }*/ + } + */ Vector3f newPosition = Environment::cameraShift; if (Environment::upPressed) { @@ -418,10 +427,15 @@ void GameObjectManager::updateScene(size_t ms) { } Vector3f characterNewPos{-newPosition.v[0], -newPosition.v[1], -newPosition.v[2]}; - // Проверяем, что новая позиция внутри разрешенной зоны - if (walkArea.isInside(characterNewPos)) { + // Заменяем проверку walkArea.isInside() на проверку через collisionMgr + if (!collisionMgr.checkCollision(characterNewPos)) { Environment::cameraShift = newPosition; Environment::characterPos = characterNewPos; + + std::cout << "Player position: x=" << characterNewPos.v[0] + << ", y=" << characterNewPos.v[1] + << ", z=" << characterNewPos.v[2] << "\r"; + std::cout.flush(); // Чтобы обновлялось в той же строке } for (auto& [key, obj] : aoMgr.activeObjectsEntities) { @@ -433,38 +447,30 @@ void GameObjectManager::updateScene(size_t ms) { obj.highlighted = (dist < 50.f); } - if (rooms[current_room_index].roomLogic) { rooms[current_room_index].roomLogic(*this, ms); } - if (Environment::violaCurrentAnimation == 0) - { - + if (Environment::violaCurrentAnimation == 0) { Environment::violaCurrentIdleFrame += ms / 24.f; - while (Environment::violaCurrentIdleFrame >= 40) - { + while (Environment::violaCurrentIdleFrame >= 40) { Environment::violaCurrentIdleFrame -= 40; } - if (int(Environment::violaCurrentIdleFrame) != Environment::violaLastIdleFrame) - { + if (int(Environment::violaCurrentIdleFrame) != Environment::violaLastIdleFrame) { violaIdleModel.Interpolate(int(Environment::violaCurrentIdleFrame)); Environment::violaLastIdleFrame = int(Environment::violaCurrentIdleFrame); } } - else if (Environment::violaCurrentAnimation == 1) - { + else if (Environment::violaCurrentAnimation == 1) { Environment::violaCurrentWalkFrame += ms / 24.f; - while (Environment::violaCurrentWalkFrame >= 30) - { + while (Environment::violaCurrentWalkFrame >= 30) { Environment::violaCurrentWalkFrame -= 30; } - if (int(Environment::violaCurrentWalkFrame) != Environment::violaLastWalkFrame) - { + if (int(Environment::violaCurrentWalkFrame) != Environment::violaLastWalkFrame) { violaWalkModel.Interpolate(int(Environment::violaCurrentWalkFrame)); Environment::violaLastWalkFrame = int(Environment::violaCurrentWalkFrame); } @@ -472,14 +478,12 @@ void GameObjectManager::updateScene(size_t ms) { } bool GameObjectManager::isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const { - const int baseObjectSize = 32; // Base half-size - const float scale = 1.0f; // Get scale from item if needed - const int scaledObjectSize = static_cast(baseObjectSize * scale); - - return (screenX >= objectScreenX - scaledObjectSize && - screenX <= objectScreenX + scaledObjectSize && - screenY >= objectScreenY - scaledObjectSize && - screenY <= objectScreenY + scaledObjectSize); + // Простая проверка попадания точки в квадрат 64x64 вокруг центра объекта + const int objectSize = 32; // Половина размера области выделения + return (screenX >= objectScreenX - objectSize && + screenX <= objectScreenX + objectSize && + screenY >= objectScreenY - objectSize && + screenY <= objectScreenY + objectSize); } void GameObjectManager::checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView) { @@ -505,7 +509,7 @@ void GameObjectManager::worldToScreenCoordinates(Vector3f objectPos, int screenWidth, int screenHeight, int& screenX, int& screenY) { - Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f}; + Vector4f inx = { objectPos.v[0], objectPos.v[1], objectPos.v[2], 1.0f }; Vector4f clipCoords = MultMatrixVector(projectionModelView, inx); float ndcX = clipCoords.v[0] / clipCoords.v[3]; diff --git a/GameObjectManager.h b/GameObjectManager.h index d160bbf..92f6ee6 100644 --- a/GameObjectManager.h +++ b/GameObjectManager.h @@ -6,11 +6,11 @@ #include #include "ActiveObject.h" #include "Room.h" +#include "BoundaryBox.h" // Добавляем включение #ifdef __linux__ #include #endif #include "OpenGlExtensions.h" -#include "BoundaryBox.h" // Добавляем новый include namespace ZL { @@ -68,7 +68,8 @@ private: Matrix4f projectionModelView, int screenWidth, int screenHeight, int& screenX, int& screenY); - BoundaryBox walkArea{800.0f, 800.0f}; // Изменяем размер с 400 на 800 + BoundaryBox walkArea{800.0f, 800.0f}; // Зона для ходьбы 800x800 + CollisionManager collisionMgr; // Добавляем менеджер коллизий }; } // namespace ZL From 5c571578dd9040fc9d7cdf07b1b176663a086f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BB=D1=8C=D0=B1=D0=B5=D1=80=D1=82=20=D0=93=D0=B0?= =?UTF-8?q?=D0=B4=D0=B8=D0=B5=D0=B2?= Date: Sun, 2 Mar 2025 22:09:25 +0600 Subject: [PATCH 2/4] da --- BoundaryBox.h | 1 + GameObjectManager.cpp | 2 +- GameObjectManager.h | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/BoundaryBox.h b/BoundaryBox.h index d90c672..05f1a71 100644 --- a/BoundaryBox.h +++ b/BoundaryBox.h @@ -80,6 +80,7 @@ public: bool checkCollision(const Vector3f& position) const { // Проверяем границы комнаты + std::cout << "checkCollision" << std::endl; if (roomBoundary && !roomBoundary->isInside(position)) { return true; } diff --git a/GameObjectManager.cpp b/GameObjectManager.cpp index bbb59e3..1e64150 100644 --- a/GameObjectManager.cpp +++ b/GameObjectManager.cpp @@ -370,7 +370,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { Environment::cameraAlpha = 0.9 * M_PI / 2.0; } } - else { + else {checkCollision lastMouseX = event.motion.x; lastMouseY = event.motion.y; } diff --git a/GameObjectManager.h b/GameObjectManager.h index 2b4c05c..c21b989 100644 --- a/GameObjectManager.h +++ b/GameObjectManager.h @@ -4,6 +4,7 @@ #include "AudioPlayerAsync.h" #include #include +#include // Добавляем include для std::list #include "ActiveObject.h" #include "Room.h" #include "BoundaryBox.h" // Добавляем включение @@ -45,8 +46,8 @@ public: ZL::VertexDataStruct textMesh; ZL::VertexRenderStruct textMeshMutable; - //ZL::VertexDataStruct coneMesh; - //ZL::VertexRenderStruct coneMeshMutable; + ZL::VertexDataStruct coneMesh; // Раскомментировали + ZL::VertexRenderStruct coneMeshMutable; // Раскомментировали std::vector activeObjects; std::vector rooms; From fe5d8c2f47ea5d8cf0ca9868a81f91c179b3c538 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 2 Mar 2025 19:32:10 +0300 Subject: [PATCH 3/4] working with collisions --- BoundaryBox.h | 1 - GameObjectManager.cpp | 26 ++++++++++++++++++-------- ZeptoLabTest1.vcxproj | 1 + ZeptoLabTest1.vcxproj.filters | 3 +++ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/BoundaryBox.h b/BoundaryBox.h index 05f1a71..d90c672 100644 --- a/BoundaryBox.h +++ b/BoundaryBox.h @@ -80,7 +80,6 @@ public: bool checkCollision(const Vector3f& position) const { // Проверяем границы комнаты - std::cout << "checkCollision" << std::endl; if (roomBoundary && !roomBoundary->isInside(position)) { return true; } diff --git a/GameObjectManager.cpp b/GameObjectManager.cpp index 1e64150..98a24e9 100644 --- a/GameObjectManager.cpp +++ b/GameObjectManager.cpp @@ -70,12 +70,12 @@ void GameObjectManager::initialize() { textMesh.Scale(10); - textMesh.SwapZandY(); - textMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 0.5))); + //textMesh.SwapZandY(); + //textMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 0.5))); textMesh.Move(Vector3f{ 0, 93, 0 }); - coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace - coneMesh.Scale(200); + //coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace + //coneMesh.Scale(200); textMeshMutable.AssignFrom(textMesh); @@ -163,6 +163,9 @@ void GameObjectManager::initialize() { //SDL_ShowCursor(SDL_DISABLE); SDL_SetRelativeMouseMode(SDL_TRUE); + collisionMgr.setRoomBoundary(800, 800); + collisionMgr.addCollider(std::make_shared(Vector3f{80, 0, 200}, Vector3f{400, 0, 400})); + return true; }; @@ -370,7 +373,7 @@ void GameObjectManager::handleEvent(const SDL_Event& event) { Environment::cameraAlpha = 0.9 * M_PI / 2.0; } } - else {checkCollision + else { lastMouseX = event.motion.x; lastMouseY = event.motion.y; } @@ -424,16 +427,23 @@ void GameObjectManager::updateScene(size_t ms) { newPosition.v[0] += directionVector.v[1] * ms; } + Vector3f characterNewPos{-newPosition.v[0], -newPosition.v[1], -newPosition.v[2]}; + + std::cout << "Player position: x=" << characterNewPos.v[0] + << ", y=" << characterNewPos.v[1] + << ", z=" << characterNewPos.v[2] << "\r"; + std::cout.flush(); + // Заменяем проверку walkArea.isInside() на проверку через collisionMgr - if (!collisionMgr.checkCollision(characterNewPos)) { + if (collisionMgr.checkCollision(characterNewPos) == false) { Environment::cameraShift = newPosition; Environment::characterPos = characterNewPos; - + /* std::cout << "Player position: x=" << characterNewPos.v[0] << ", y=" << characterNewPos.v[1] << ", z=" << characterNewPos.v[2] << "\r"; - std::cout.flush(); // Чтобы обновлялось в той же строке + std::cout.flush(); // Чтобы обновлялось в той же строке*/ } for (auto& [key, obj] : aoMgr.activeObjectsEntities) { diff --git a/ZeptoLabTest1.vcxproj b/ZeptoLabTest1.vcxproj index a65d219..121ae81 100755 --- a/ZeptoLabTest1.vcxproj +++ b/ZeptoLabTest1.vcxproj @@ -173,6 +173,7 @@ + diff --git a/ZeptoLabTest1.vcxproj.filters b/ZeptoLabTest1.vcxproj.filters index 815a529..88d64f0 100755 --- a/ZeptoLabTest1.vcxproj.filters +++ b/ZeptoLabTest1.vcxproj.filters @@ -146,5 +146,8 @@ Header Files + + Header Files + \ No newline at end of file From a3075433f0b223a21e202b56216e1a7f73d30ee6 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 2 Mar 2025 19:58:38 +0300 Subject: [PATCH 4/4] Move collision box and model to the room itself --- BoundaryBox.h | 19 +++++++++++----- GameObjectManager.cpp | 52 +++++++++++++++++-------------------------- GameObjectManager.h | 18 +++++++-------- RenderSystem.cpp | 5 ++--- Room.h | 12 +++++++++- 5 files changed, 57 insertions(+), 49 deletions(-) diff --git a/BoundaryBox.h b/BoundaryBox.h index d90c672..264dc57 100644 --- a/BoundaryBox.h +++ b/BoundaryBox.h @@ -15,6 +15,10 @@ public: // Прямоугольная граница комнаты class BoundaryBox { public: + BoundaryBox() + { + } + BoundaryBox(float width, float height) : halfWidth(width/2) , halfHeight(height/2) {} @@ -25,8 +29,8 @@ public: } private: - float halfWidth; - float halfHeight; + float halfWidth = 0; + float halfHeight = 0; }; // Круглая коллизия для объектов @@ -70,8 +74,13 @@ private: // Менеджер коллизий class CollisionManager { public: + CollisionManager() + { + + } + void setRoomBoundary(float width, float height) { - roomBoundary = std::make_unique(width, height); + roomBoundary = BoundaryBox(width, height); } void addCollider(std::shared_ptr collider) { @@ -80,7 +89,7 @@ public: bool checkCollision(const Vector3f& position) const { // Проверяем границы комнаты - if (roomBoundary && !roomBoundary->isInside(position)) { + if (!roomBoundary.isInside(position)) { return true; } @@ -94,7 +103,7 @@ public: } private: - std::unique_ptr roomBoundary; + BoundaryBox roomBoundary; std::vector> colliders; }; diff --git a/GameObjectManager.cpp b/GameObjectManager.cpp index 98a24e9..d408622 100644 --- a/GameObjectManager.cpp +++ b/GameObjectManager.cpp @@ -33,7 +33,7 @@ void GameObjectManager::initialize() { current_room_index = 0; objects_in_inventory = 0; - coneTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./conus.bmp")); + //coneTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./conus.bmp")); // Load models /* @@ -47,7 +47,12 @@ void GameObjectManager::initialize() { loadingThread = std::thread([this]() { - textMesh = ZL::LoadFromTextFile("./oneroom001.txt"); + preloadedRoomMeshArr.resize(1); + preloadedRoomMeshArr[0] = ZL::LoadFromTextFile("./oneroom001.txt"); + preloadedRoomMeshArr[0].Scale(10); + preloadedRoomMeshArr[0].Move(Vector3f{ 0, 93, 0 }); + + violaIdleModel.LoadFromFile("./idleviola001.txt"); violaWalkModel.LoadFromFile("./walkviolla001.txt"); sideThreadLoadingCompleted = true; @@ -61,29 +66,6 @@ void GameObjectManager::initialize() { std::function loadingFunction3 = [this]() { - /* - testObjMesh = LoadFromObjFile("./chair_01.obj"); - testObjMesh.Scale(10); - testObjMesh.SwapZandY(); - testObjMeshMutable.data = testObjMesh; - testObjMeshMutable.RefreshVBO();*/ - - - textMesh.Scale(10); - //textMesh.SwapZandY(); - //textMesh.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI * 0.5))); - textMesh.Move(Vector3f{ 0, 93, 0 }); - - //coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace - //coneMesh.Scale(200); - - - textMeshMutable.AssignFrom(textMesh); - textMeshMutable.RefreshVBO(); - //coneMeshMutable.AssignFrom(coneMesh); - //coneMeshMutable.RefreshVBO(); - - // Create active object ActiveObject ao1; @@ -123,6 +105,11 @@ void GameObjectManager::initialize() { room_1.objects.push_back(ao1); room_1.sound_name = "Symphony No.6 (1st movement).ogg"; room_1.roomLogic = createRoom1Logic(); + room_1.textMesh = preloadedRoomMeshArr[0]; + room_1.textMeshMutable.AssignFrom(room_1.textMesh); + room_1.collisionMgr.setRoomBoundary(800, 800); + room_1.collisionMgr.addCollider(std::make_shared(Vector3f{ 80, 0, 200 }, Vector3f{ 400, 0, 400 })); + rooms.push_back(room_1); aoMgr.addActiveObject(ao1); @@ -130,6 +117,11 @@ void GameObjectManager::initialize() { room_2.roomTexture = std::make_shared(CreateTextureDataFromBmp24("./background.bmp")); room_2.sound_name = "Symphony No.6 (1st movement).ogg"; room_2.roomLogic = createRoom2Logic(); + room_2.textMesh = preloadedRoomMeshArr[0]; + room_2.textMeshMutable.AssignFrom(room_2.textMesh); + room_2.collisionMgr.setRoomBoundary(800, 800); + room_2.collisionMgr.addCollider(std::make_shared(Vector3f{ 80, 0, 200 }, Vector3f{ 400, 0, 400 })); + rooms.push_back(room_2); activeObjects = rooms[current_room_index].objects; @@ -152,7 +144,7 @@ void GameObjectManager::initialize() { inventoryIconMeshMutable.AssignFrom(inventoryIconMesh); inventoryIconMeshMutable.RefreshVBO(); - roomTexturePtr = rooms[current_room_index].roomTexture; + //roomTexturePtr = rooms[current_room_index].roomTexture; AddItemToInventory("book1", std::make_shared(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")), objects_in_inventory + 1); objects_in_inventory++; @@ -163,9 +155,7 @@ void GameObjectManager::initialize() { //SDL_ShowCursor(SDL_DISABLE); SDL_SetRelativeMouseMode(SDL_TRUE); - collisionMgr.setRoomBoundary(800, 800); - collisionMgr.addCollider(std::make_shared(Vector3f{80, 0, 200}, Vector3f{400, 0, 400})); - + return true; }; @@ -178,7 +168,7 @@ void GameObjectManager::initialize() { void GameObjectManager::switch_room(int index){ current_room_index = index; - roomTexturePtr = rooms[current_room_index].roomTexture; + //roomTexturePtr = rooms[current_room_index].roomTexture; //audioPlayer.reset(); // This deletes the current AudioPlayer @@ -436,7 +426,7 @@ void GameObjectManager::updateScene(size_t ms) { std::cout.flush(); // Заменяем проверку walkArea.isInside() на проверку через collisionMgr - if (collisionMgr.checkCollision(characterNewPos) == false) { + if (rooms[current_room_index].collisionMgr.checkCollision(characterNewPos) == false) { Environment::cameraShift = newPosition; Environment::characterPos = characterNewPos; /* diff --git a/GameObjectManager.h b/GameObjectManager.h index c21b989..d32b067 100644 --- a/GameObjectManager.h +++ b/GameObjectManager.h @@ -4,10 +4,9 @@ #include "AudioPlayerAsync.h" #include #include -#include // Добавляем include для std::list +#include #include "ActiveObject.h" #include "Room.h" -#include "BoundaryBox.h" // Добавляем включение #ifdef __linux__ #include #endif @@ -28,7 +27,7 @@ public: void checkMouseIntersection(int mouseX, int mouseY, const Matrix4f& projectionModelView); // Добавляем новый метод std::shared_ptr testObjTexturePtr; - std::shared_ptr roomTexturePtr; + //std::shared_ptr roomTexturePtr; std::shared_ptr coneTexturePtr; //ZL::VertexDataStruct colorCubeMesh; @@ -43,11 +42,11 @@ public: ZL::BoneSystem violaWalkModel; ZL::VertexRenderStruct violaWalkModelMutable; - ZL::VertexDataStruct textMesh; - ZL::VertexRenderStruct textMeshMutable; + std::vector preloadedRoomMeshArr; - ZL::VertexDataStruct coneMesh; // Раскомментировали - ZL::VertexRenderStruct coneMeshMutable; // Раскомментировали + + //ZL::VertexDataStruct coneMesh; // Раскомментировали + //ZL::VertexRenderStruct coneMeshMutable; // Раскомментировали std::vector activeObjects; std::vector rooms; @@ -72,18 +71,19 @@ public: std::thread loadingThread; bool sideThreadLoadingCompleted = false; + int current_room_index; private: + //int animationCounter = 0; int lastMouseX = 0; // Добавляем переменные для хранения позиции мыши int lastMouseY = 0; - int current_room_index; + bool isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const; void worldToScreenCoordinates(Vector3f objectPos, // Добавляем метод Matrix4f projectionModelView, int screenWidth, int screenHeight, int& screenX, int& screenY); BoundaryBox walkArea{800.0f, 800.0f}; // Зона для ходьбы 800x800 - CollisionManager collisionMgr; // Добавляем менеджер коллизий }; } // namespace ZL diff --git a/RenderSystem.cpp b/RenderSystem.cpp index 0152d68..4317e52 100644 --- a/RenderSystem.cpp +++ b/RenderSystem.cpp @@ -171,9 +171,8 @@ void RenderSystem::drawWorld(GameObjectManager& gameObjects) { } // Draw room - glBindTexture(GL_TEXTURE_2D, gameObjects.roomTexturePtr->getTexID()); - renderer.DrawVertexRenderStruct(gameObjects.textMeshMutable); - + glBindTexture(GL_TEXTURE_2D, gameObjects.rooms[gameObjects.current_room_index].roomTexture->getTexID()); + renderer.DrawVertexRenderStruct(gameObjects.rooms[gameObjects.current_room_index].textMeshMutable); Matrix4f latestProjectionModelView = renderer.GetProjectionModelViewMatrix(); diff --git a/Room.h b/Room.h index 9ce5939..4982d3f 100644 --- a/Room.h +++ b/Room.h @@ -4,8 +4,9 @@ #include "Math.h" #include #include "ActiveObject.h" -#include +#include +#include "BoundaryBox.h" namespace ZL { struct Room{ @@ -13,7 +14,16 @@ struct Room{ std::vector objects; std::string sound_name; + ZL::VertexDataStruct textMesh; + ZL::VertexRenderStruct textMeshMutable; + + CollisionManager collisionMgr; + std::function roomLogic; + Room() + { + } + }; }