added inventory & active object
This commit is contained in:
1 parent
e1b491be73
commit
b3fda88784
16 files changed
+793
-98
No files matched your search
+134
-32
@@ -148,34 +148,11 @@ namespace ZL
|
||||
roomMesh.RefreshVBO();
|
||||
std::cout << "Load resurces step 5" << std::endl;
|
||||
|
||||
// Load static game objects
|
||||
gameObjects = GameObjectLoader::loadAndCreateGameObjects("resources/config2/gameobjects.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
/*
|
||||
std::cout << "Load resurces step 5" << std::endl;
|
||||
fireboxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/Cube001.png", CONST_ZIP_FILE));
|
||||
fireboxMesh.data = LoadFromTextFile02("resources/w/firebox.txt", CONST_ZIP_FILE);
|
||||
fireboxMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
fireboxMesh.RefreshVBO();
|
||||
|
||||
|
||||
std::cout << "Load resurces step 6" << std::endl;
|
||||
inaiTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/inai001.png", CONST_ZIP_FILE));
|
||||
std::cout << "Load resurces step 6.1" << std::endl;
|
||||
inaiMesh.data = LoadFromTextFile02("resources/w/inai001.txt", CONST_ZIP_FILE);
|
||||
inaiMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
inaiMesh.data.Move({ 2.5, 1.4, -9.9 });
|
||||
inaiMesh.RefreshVBO();
|
||||
|
||||
std::cout << "Load resurces step 7" << std::endl;
|
||||
benchTexture = std::make_unique<Texture>(CreateTextureDataFromPng("resources/w/bench001opt.png", CONST_ZIP_FILE));
|
||||
benchMesh.data = LoadFromTextFile02("resources/w/bench002opt.txt", CONST_ZIP_FILE);
|
||||
benchMesh.data.Scale(3.f);
|
||||
benchMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY())).toRotationMatrix());
|
||||
benchMesh.data.Move({ -2.1, 0.5, -7.9 });
|
||||
benchMesh.RefreshVBO();
|
||||
*/
|
||||
|
||||
std::cout << "Load resurces step 8" << std::endl;
|
||||
|
||||
// Load interactive objects
|
||||
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects("resources/config2/gameobjects.json", renderer, CONST_ZIP_FILE);
|
||||
|
||||
auto violaTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/viola.png", CONST_ZIP_FILE));
|
||||
|
||||
@@ -236,8 +213,91 @@ namespace ZL
|
||||
scriptEngine.init(this);
|
||||
|
||||
std::cout << "Load resurces step 13" << std::endl;
|
||||
|
||||
// Load UI with inventory button
|
||||
try {
|
||||
menuManager.uiManager.loadFromFile("resources/config2/ui_inventory.json", renderer, CONST_ZIP_FILE);
|
||||
std::cout << "UI loaded successfully" << std::endl;
|
||||
|
||||
menuManager.uiManager.setNodeVisible("inventory_items_panel", false);
|
||||
menuManager.uiManager.setNodeVisible("close_inventory_button", false);
|
||||
|
||||
menuManager.uiManager.setTextButtonCallback("inventory_button", [this](const std::string& name) {
|
||||
std::cout << "[UI] Inventory button clicked" << std::endl;
|
||||
//scriptEngine.callItemPickupCallback("toggle_inventory");
|
||||
scriptEngine.showInventory(this);
|
||||
//scriptEngine
|
||||
//scriptEngine
|
||||
});
|
||||
|
||||
menuManager.uiManager.setTextButtonCallback("close_inventory_button", [this](const std::string& name) {
|
||||
std::cout << "[UI] Close button clicked" << std::endl;
|
||||
menuManager.uiManager.setNodeVisible("inventory_items_panel", false);
|
||||
menuManager.uiManager.setNodeVisible("close_inventory_button", false);
|
||||
inventoryOpen = false;
|
||||
});
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Failed to load UI: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
InteractiveObject* Game::raycastInteractiveObjects(const Eigen::Vector3f& rayOrigin, const Eigen::Vector3f& rayDir) {
|
||||
if (interactiveObjects.empty()) {
|
||||
std::cout << "[RAYCAST] No interactive objects to check" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::cout << "[RAYCAST] Starting raycast with " << interactiveObjects.size() << " objects" << std::endl;
|
||||
std::cout << "[RAYCAST] Ray origin: (" << rayOrigin.x() << ", " << rayOrigin.y() << ", " << rayOrigin.z() << ")" << std::endl;
|
||||
std::cout << "[RAYCAST] Ray dir: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
|
||||
|
||||
float closestDistance = FLT_MAX;
|
||||
InteractiveObject* closestObject = nullptr;
|
||||
|
||||
for (auto& intObj : interactiveObjects) {
|
||||
std::cout << "[RAYCAST] Checking object: " << intObj.name << " (active: " << intObj.isActive << ")" << std::endl;
|
||||
|
||||
if (!intObj.isActive) {
|
||||
std::cout << "[RAYCAST] -> Object inactive, skipping" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "[RAYCAST] Position: (" << intObj.position.x() << ", " << intObj.position.y() << ", "
|
||||
<< intObj.position.z() << "), Radius: " << intObj.interactionRadius << std::endl;
|
||||
|
||||
Eigen::Vector3f toObject = intObj.position - rayOrigin;
|
||||
std::cout << "[RAYCAST] Vector to object: (" << toObject.x() << ", " << toObject.y() << ", " << toObject.z() << ")" << std::endl;
|
||||
|
||||
float distanceAlongRay = toObject.dot(rayDir);
|
||||
std::cout << "[RAYCAST] Distance along ray: " << distanceAlongRay << std::endl;
|
||||
|
||||
if (distanceAlongRay < 0.1f) {
|
||||
std::cout << "[RAYCAST] -> Object behind camera, skipping" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
Eigen::Vector3f closestPointOnRay = rayOrigin + rayDir * distanceAlongRay;
|
||||
float distToObject = (closestPointOnRay - intObj.position).norm();
|
||||
|
||||
std::cout << "[RAYCAST] Distance to object: " << distToObject
|
||||
<< " (interaction radius: " << intObj.interactionRadius << ")" << std::endl;
|
||||
|
||||
if (distToObject <= intObj.interactionRadius && distanceAlongRay < closestDistance) {
|
||||
std::cout << "[RAYCAST] *** HIT DETECTED! ***" << std::endl;
|
||||
closestDistance = distanceAlongRay;
|
||||
closestObject = &intObj;
|
||||
}
|
||||
}
|
||||
|
||||
if (closestObject) {
|
||||
std::cout << "[RAYCAST] *** RAYCAST SUCCESS: Found object " << closestObject->name << " ***" << std::endl;
|
||||
} else {
|
||||
std::cout << "[RAYCAST] No objects hit" << std::endl;
|
||||
}
|
||||
|
||||
return closestObject;
|
||||
}
|
||||
|
||||
void Game::drawUI()
|
||||
{
|
||||
@@ -291,6 +351,11 @@ namespace ZL
|
||||
glBindTexture(GL_TEXTURE_2D, benchTexture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(benchMesh);
|
||||
*/
|
||||
for (auto& intObj : interactiveObjects) {
|
||||
if (intObj.isActive) {
|
||||
intObj.draw(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
if (player) player->draw(renderer);
|
||||
for (auto& npc : npcs) npc->draw(renderer);
|
||||
@@ -374,9 +439,23 @@ namespace ZL
|
||||
|
||||
if (player) player->update(delta);
|
||||
for (auto& npc : npcs) npc->update(delta);
|
||||
|
||||
// Check if player reached target interactive object
|
||||
if (targetInteractiveObject && player) {
|
||||
float distToObject = (player->position - targetInteractiveObject->position).norm();
|
||||
|
||||
// If player is close enough to pick up the item
|
||||
if (distToObject <= targetInteractiveObject->interactionRadius + 1.0f) {
|
||||
std::cout << "[PICKUP] Player reached object! Distance: " << distToObject << std::endl;
|
||||
std::cout << "[PICKUP] Calling Lua callback for: " << targetInteractiveObject->id << std::endl;
|
||||
|
||||
// Call Lua callback
|
||||
scriptEngine.callItemPickupCallback(targetInteractiveObject->id);
|
||||
|
||||
targetInteractiveObject = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Game::render() {
|
||||
@@ -456,13 +535,14 @@ namespace ZL
|
||||
|
||||
if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
|
||||
if (event.button.button == SDL_BUTTON_LEFT) {
|
||||
// Преобразуем экранные пиксели в проекционные единицы
|
||||
int mx = static_cast<int>((float)event.button.x / Environment::width * Environment::projectionWidth);
|
||||
int my = static_cast<int>((float)event.button.y / Environment::height * Environment::projectionHeight);
|
||||
|
||||
if (event.type == SDL_MOUSEBUTTONDOWN) {
|
||||
std::cout << "\n========== MOUSE DOWN EVENT ==========" << std::endl;
|
||||
handleDown(ZL::UiManager::MOUSE_FINGER_ID, mx, my);
|
||||
|
||||
// Unproject click to ground plane (y=0) for Viola's walk target
|
||||
// Calculate ray for picking
|
||||
float ndcX = 2.0f * event.button.x / Environment::width - 1.0f;
|
||||
float ndcY = 1.0f - 2.0f * event.button.y / Environment::height;
|
||||
float aspect = (float)Environment::width / (float)Environment::height;
|
||||
@@ -479,11 +559,33 @@ namespace ZL
|
||||
|
||||
Eigen::Vector3f rayDir = (camForward + camRight * (ndcX * aspect * tanHalfFov) + camUp * (ndcY * tanHalfFov)).normalized();
|
||||
|
||||
if (rayDir.y() < -0.001f && player) {
|
||||
std::cout << "[CLICK] Camera position: (" << camPos.x() << ", " << camPos.y() << ", " << camPos.z() << ")" << std::endl;
|
||||
std::cout << "[CLICK] Ray direction: (" << rayDir.x() << ", " << rayDir.y() << ", " << rayDir.z() << ")" << std::endl;
|
||||
|
||||
// First check if we clicked on interactive object
|
||||
InteractiveObject* clickedObject = raycastInteractiveObjects(camPos, rayDir);
|
||||
if (clickedObject && player && clickedObject->isActive) {
|
||||
std::cout << "[CLICK] *** SUCCESS: Clicked on interactive object: " << clickedObject->name << " ***" << std::endl;
|
||||
std::cout << "[CLICK] Object position: (" << clickedObject->position.x() << ", "
|
||||
<< clickedObject->position.y() << ", " << clickedObject->position.z() << ")" << std::endl;
|
||||
std::cout << "[CLICK] Player position: (" << player->position.x() << ", "
|
||||
<< player->position.y() << ", " << player->position.z() << ")" << std::endl;
|
||||
|
||||
targetInteractiveObject = clickedObject;
|
||||
player->setTarget(clickedObject->position);
|
||||
std::cout << "[CLICK] Player moving to object..." << std::endl;
|
||||
}
|
||||
else if (rayDir.y() < -0.001f && player) {
|
||||
// Otherwise, unproject click to ground plane for Viola's walk target
|
||||
float t = -camPos.y() / rayDir.y();
|
||||
Eigen::Vector3f hit = camPos + rayDir * t;
|
||||
std::cout << "[CLICK] Clicked on ground at: (" << hit.x() << ", " << hit.z() << ")" << std::endl;
|
||||
player->setTarget(Eigen::Vector3f(hit.x(), 0.f, hit.z()));
|
||||
}
|
||||
else {
|
||||
std::cout << "[CLICK] No valid target found" << std::endl;
|
||||
}
|
||||
std::cout << "========================================\n" << std::endl;
|
||||
} else {
|
||||
handleUp(ZL::UiManager::MOUSE_FINGER_ID, mx, my);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user