#include "GameObjectManager.h" #include "Environment.h" #include "ObjLoader.h" #include "Inventory.h" #include "TextModel.h" // Add this include for LoadFromTextFile namespace ZL { const float GameObjectManager::INVENTORY_ICON_SIZE = 32.0f; const float GameObjectManager::INVENTORY_MARGIN = 10.0f; void GameObjectManager::initialize() { // Load textures roomTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")); coneTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./conus.bmp")); // Load models colorCubeMesh = CreateCube3D(5.0); colorCubeMeshMutable.data = CreateCube3D(5.0); colorCubeMeshMutable.RefreshVBO(); testObjMesh = LoadFromObjFile("./chair_01.obj"); testObjMesh.Scale(10); testObjMesh.SwapZandY(); testObjMeshMutable.data = testObjMesh; testObjMeshMutable.RefreshVBO(); textMesh = ZL::LoadFromTextFile("./mesh001.txt"); // Add ZL:: namespace coneMesh = ZL::LoadFromTextFile("./cone001.txt"); // Add ZL:: namespace coneMesh.Scale(200); textMeshMutable.AssignFrom(textMesh); textMeshMutable.RefreshVBO(); coneMeshMutable.AssignFrom(coneMesh); coneMeshMutable.RefreshVBO(); // Load bone animations bx.LoadFromFile("mesh_armature_and_animation_data.txt"); // Create active object ActiveObject ao1; ao1.activeObjectMesh = ZL::LoadFromTextFile("./book001.txt"); // Add ZL:: namespace ao1.activeObjectMesh.Scale(4); ao1.activeObjectMeshMutable.AssignFrom(ao1.activeObjectMesh); ao1.activeObjectMeshMutable.RefreshVBO(); ao1.objectPos = Vector3f{50, 0, -300}; ao1.activeObjectTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./book03.bmp")); ao1.activeObjectScreenTexturePtr = std::make_shared(CreateTextureDataFromBmp24("./aoscreen01.bmp")); ao1.activeObjectScreenMesh = CreateRect2D({ 0.f, 0.f }, { 64.f, 64.f }, 0.5); ao1.activeObjectScreenMeshMutable.AssignFrom(ao1.activeObjectScreenMesh); ao1.activeObjectScreenMeshMutable.RefreshVBO(); activeObjects.push_back(ao1); // Initialize audio audioPlayer = std::make_unique(); if (audioPlayer) { audioPlayer->playMusic("Symphony No.6 (1st movement).ogg"); } // Initialize inventory inventoryIconMesh = CreateRect2D( {0.0f, 0.0f}, {INVENTORY_ICON_SIZE/2, INVENTORY_ICON_SIZE/2}, 0.5f ); inventoryIconMeshMutable.AssignFrom(inventoryIconMesh); inventoryIconMeshMutable.RefreshVBO(); // Add test items to inventory auto testRoomTexture = std::make_shared(CreateTextureDataFromBmp24("./Kitchen_ceramics.bmp")); auto testConeTexture = std::make_shared(CreateTextureDataFromBmp24("./conus.bmp")); AddItemToInventory("RoomCeramics", testRoomTexture); AddItemToInventory("Cone", testConeTexture); } void GameObjectManager::update() { updateScene(16); // Добавим фиксированный timestep для обновления сцены } void GameObjectManager::handleEvent(const SDL_Event& event) { if (event.type == SDL_MOUSEBUTTONDOWN) { bx.Interpolate(animationCounter); animationCounter += 2; } else if (event.type == SDL_MOUSEWHEEL) { static const float zoomstep = 1.0f; if (event.wheel.y > 0) { Environment::zoom -= zoomstep; } else if (event.wheel.y < 0) { Environment::zoom += zoomstep; } if (Environment::zoom < zoomstep) { Environment::zoom = zoomstep; } } else if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { case SDLK_LEFT: case SDLK_a: Environment::leftPressed = true; if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } break; case SDLK_RIGHT: case SDLK_d: Environment::rightPressed = true; if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } break; case SDLK_UP: case SDLK_w: Environment::upPressed = true; if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } break; case SDLK_DOWN: case SDLK_s: Environment::downPressed = true; if (audioPlayer) { audioPlayer->playSound("Звук-Идут-по-земле.ogg"); } break; // ...handle other keys... } } else if (event.type == SDL_KEYUP) { switch (event.key.keysym.sym) { case SDLK_LEFT: case SDLK_a: Environment::leftPressed = false; break; case SDLK_RIGHT: case SDLK_d: Environment::rightPressed = false; break; case SDLK_UP: case SDLK_w: Environment::upPressed = false; break; case SDLK_DOWN: case SDLK_s: Environment::downPressed = false; break; } } if (event.type == SDL_MOUSEMOTION) { // Сохраняем позицию мыши для последующей проверки lastMouseX = event.motion.x; lastMouseY = event.motion.y; } } void GameObjectManager::updateScene(size_t ms) { const float SPEED = 0.1f; if (Environment::leftPressed) { Environment::cameraShift.v[0] += SPEED * ms; } if (Environment::rightPressed) { Environment::cameraShift.v[0] -= SPEED * ms; } if (Environment::upPressed) { Environment::cameraShift.v[2] += SPEED * ms; } if (Environment::downPressed) { Environment::cameraShift.v[2] -= SPEED * ms; } Environment::characterPos.v[0] = -Environment::cameraShift.v[0]; Environment::characterPos.v[1] = -Environment::cameraShift.v[1]; Environment::characterPos.v[2] = -Environment::cameraShift.v[2]; for (auto& ao : activeObjects) { float dist = sqrtf( pow(Environment::characterPos.v[0] - ao.objectPos.v[0], 2) + pow(Environment::characterPos.v[1] - ao.objectPos.v[1], 2) + pow(Environment::characterPos.v[2] - ao.objectPos.v[2], 2) ); ao.highlighted = (dist < 50.f); } } bool GameObjectManager::isPointInObject(int screenX, int screenY, int objectScreenX, int objectScreenY) const { // Простая проверка попадания точки в квадрат 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) { for (auto& ao : activeObjects) { int screenX, screenY; worldToScreenCoordinates(ao.objectPos, projectionModelView, Environment::width, Environment::height, screenX, screenY); if (isPointInObject(mouseX, mouseY, screenX, screenY)) { std::cout << "Mouse over object at screen coordinates: " << screenX << ", " << screenY << " (world pos: " << ao.objectPos.v[0] << ", " << ao.objectPos.v[1] << ", " << ao.objectPos.v[2] << ")" << std::endl; } } } void GameObjectManager::worldToScreenCoordinates(Vector3f objectPos, Matrix4f projectionModelView, int screenWidth, int screenHeight, int& screenX, int& screenY) { 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]; float ndcY = clipCoords.v[1] / clipCoords.v[3]; screenX = (int)((ndcX + 1.0f) * 0.5f * screenWidth); screenY = (int)((1.0f + ndcY) * 0.5f * screenHeight); } } // namespace ZL