#include "gamecube.h" #include #include #include #include "raylib.h" // Stellen Sie sicher, dass raylib.h hier oder in gamecube.h inkludiert ist // ----------------------------------------------------------- // 3D Memory Game – Hauptprogramm // ----------------------------------------------------------- enum GameScreen {MENU = 0, GAMEPLAY}; void SetupGame(std::vector& cubes, int pairs) { cubes.clear(); Color colors[] = {RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, WHITE, SKYBLUE}; std::vector positions; int count = pairs * 2; int cols = 3; int rows = 2; if (count > 6) { cols = 4; rows = 3; } int index = 0; // Generiert Positionen basierend auf der Größe for (int r = 0; r < rows && index < count; ++r) { for (int c = 0; c < cols && index < count; ++c) { // Zentriert die Würfel um (0,0,0) positions.push_back({(float)c * 2.0f - (cols -1 ), 0.0f, (float)r * 2.0f - (rows -1)}); index++; } } std::vector colorPool; for (int i = 0; i < pairs; i++) { colorPool.push_back(colors[i]); colorPool.push_back(colors[i]); } // Fisher-Yates Shuffle for (int i= colorPool.size() -1; i > 0; --i) { int j = rand() % (i + 1); std::swap(colorPool[i], colorPool[j]); } // Würfel erstellen for (int i = 0; i < count; i++) cubes.emplace_back(positions[i], colorPool[i]); } int main() { // Zufall initialisieren#include "gamecube.h" //#include //#include // //// ----------------------------------------------------------- //// 3D Memory Game – Hauptprogramm //// ----------------------------------------------------------- //int main() //{ // // Zufall initialisieren // srand(time(NULL)); // // // Fenster und Kamera // InitWindow(800, 600, "3D Memory Game with Matrix3D Library"); // SetTargetFPS(60); // // Camera3D camera{}; // camera.position = {6.0f, 6.0f, 6.0f}; // camera.target = {0.0f, 0.0f, 0.0f}; // camera.up = {0.0f, 1.0f, 0.0f}; // camera.fovy = 45.0f; // camera.projection = CAMERA_PERSPECTIVE; // // // Nur 3 Farben für 3 Paare // Color colors[] = { RED, GREEN, BLUE }; // // // 6 Karten-Positionen im 3x2 Raster // std::vector positions = {{-2, 0, -2}, {0, 0, -2}, {2, 0, -2},{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}}; // // // Farben doppelt in einen Pool legen und mischen // std::vector colorPool; // for (int i = 0; i < 3; i++) // { // colorPool.push_back(colors[i]); // colorPool.push_back(colors[i]); // } // // // Fisher-Yates Shuffle mit rand() // for (int i = colorPool.size() - 1; i > 0; --i) // { // int j = rand() % (i + 1); // Zufallsindex von 0 bis i // std::swap(colorPool[i], colorPool[j]); // } // // // Karten/Würfel erstellen // std::vector cubes; // for (int i = 0; i < 6; i++) // cubes.emplace_back(positions[i], colorPool[i]); // // gamecube* first = nullptr; // gamecube* second = nullptr; // float flipSpeed = 5.0f; // Drehgeschwindigkeit // bool gameWon = false; // // // ----------------------------------------------------------- // // Hauptspielschleife // // ----------------------------------------------------------- // while (!WindowShouldClose()) // { // // Klick-Erkennung // if (!gameWon && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) // { // Vector2 mouse = GetMousePosition(); // // for (auto &c : cubes) // { // if (!c.IsFlipped() && !c.IsMatched()) // { // Vector2 screenPos = GetWorldToScreen({c.GetPosition().x, c.GetPosition().y, c.GetPosition().z}, camera); // // if (fabs(mouse.x - screenPos.x) < 40 && fabs(mouse.y - screenPos.y) < 40) // c.FlipForward(); // } // } // } // // // Animation aller Würfel // for (auto &c : cubes) // { // c.Update(flipSpeed); // // // Sobald ein Würfel vollständig umgedreht ist → merken // if (c.IsFlipped() && !c.IsMatched()) // { // if (!first) first = &c; // else if (!second && &c != first) second = &c; // } // } // // // Matching-Logik // if (first && second) // { // Color col1 = first->GetColor(); // Color col2 = second->GetColor(); // // if (col1.r == col2.r && col1.g == col2.g && col1.b == col2.b) // { // first->SetMatched(true); // second->SetMatched(true); // } // else // { // first->FlipBackward(); // second->FlipBackward(); // } // // first = second = nullptr; // } // // // Gewinnprüfung // if (!gameWon) // gameWon = std::all_of(cubes.begin(), cubes.end(), [](const gamecube &c){ return c.IsMatched(); }); // // // ----------------------------------------------------------- // // Zeichnen // // ----------------------------------------------------------- // BeginDrawing(); // ClearBackground(RAYWHITE); // BeginMode3D(camera); // // for (auto &c : cubes) // c.Draw(); // // EndMode3D(); // // if (gameWon) // DrawText("Congrats! You found all pairs!", 150, 260, 30, DARKBLUE); // else // DrawText("Flip 2 cubes - find matching pairs!", 10, 10, 20, DARKGRAY); // // EndDrawing(); // } // // CloseWindow(); // return 0; //} srand(time(NULL)); double startTime = 0.0; double endTime = 0.0; bool timerStarted = false; GameScreen currentScreen = MENU; int selectedPairs = 3; // 1. SPIELSPEZIFISCHE VARIABLEN HIER DEKLARIEREN (ohne Initialisierung) std::vector cubes; gamecube* first = nullptr; gamecube* second = nullptr; float flipSpeed = 5.0f; // Drehgeschwindigkeit bool gameWon = false; int moves = 0; // Fenster und Kamera InitWindow(800, 600, "3D Memory Game with Matrix3D Library"); SetTargetFPS(60); Camera3D camera{}; camera.position = {6.0f, 6.0f, 6.0f}; camera.target = {0.0f, 0.0f, 0.0f}; camera.up = {0.0f, 1.0f, 0.0f}; camera.fovy = 45.0f; camera.projection = CAMERA_PERSPECTIVE; // ----------------------------------------------------------- // Hauptspielschleife // ----------------------------------------------------------- while (!WindowShouldClose()) { // ------------------------------------------------------- // UPDATE-LOGIK NACH ZUSTAND // ------------------------------------------------------- switch (currentScreen) { case MENU: { // Menü-Abfrage: Auf Tastendruck warten if (IsKeyPressed(KEY_THREE)) { selectedPairs = 3; // 6 Würfel SetupGame(cubes, selectedPairs); gameWon = false; first = second = nullptr; currentScreen = GAMEPLAY; timerStarted = false; // Timer-Reset moves = 0; } else if (IsKeyPressed(KEY_SIX)) { selectedPairs = 6; // 12 Würfel SetupGame(cubes, selectedPairs); gameWon = false; first = second = nullptr; currentScreen = GAMEPLAY; timerStarted = false; // Timer-Reset moves = 0; } break; } case GAMEPLAY: { // Timer starten if (!timerStarted) { startTime = GetTime(); timerStarted = true; } // Klick-Erkennung <<<<<<< HEAD if (!gameWon && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { Vector2 mouse = GetMousePosition(); for (auto &c : cubes) { if (!c.IsFlipped() && !c.IsMatched()) { Vector2 screenPos = GetWorldToScreen({c.GetPosition().x, c.GetPosition().y, c.GetPosition().z}, camera); if (fabs(mouse.x - screenPos.x) < 40 && fabs(mouse.y - screenPos.y) < 40) c.FlipForward(); ======= // Klick-Erkennung (nur wenn noch nicht 2 ausgewählt sind) if (!gameWon && IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && (second == nullptr)) { Vector2 mouse = GetMousePosition(); Ray ray = GetMouseRay(mouse, camera); gamecube* hitCube = nullptr; float bestDist = 1e9f; for (auto &c : cubes) { if (c.IsMatched() || c.IsFlipped()) continue; auto p = c.GetPosition(); BoundingBox box; box.min = { p.x - 0.75f, p.y - 0.75f, p.z - 0.75f }; box.max = { p.x + 0.75f, p.y + 0.75f, p.z + 0.75f }; RayCollision col = GetRayCollisionBox(ray, box); if (col.hit && col.distance < bestDist) { bestDist = col.distance; hitCube = &c; } } if (hitCube) { if (!first) { first = hitCube; first->FlipForward(); } else if (hitCube != first) { second = hitCube; second->FlipForward(); >>>>>>> 5fc4346 (funktioniert, 3 oder 6 + Timer komplett) } } } // Animation aller Würfel for (auto &c : cubes) { c.Update(flipSpeed); <<<<<<< HEAD if (c.IsFlipped() && !c.IsMatched()) { if (!first) first = &c; else if (!second && &c != first) second = &c; } } // Matching-Logik if (first && second) ======= } // Matching-Logik // Matching-Logik: erst wenn beide vollständig umgedreht sind if (first && second && first->IsFlipped() && second->IsFlipped()) >>>>>>> 5fc4346 (funktioniert, 3 oder 6 + Timer komplett) { moves++; Color col1 = first->GetColor(); Color col2 = second->GetColor(); if (col1.r == col2.r && col1.g == col2.g && col1.b == col2.b) { first->SetMatched(true); second->SetMatched(true); } else { first->FlipBackward(); second->FlipBackward(); } <<<<<<< HEAD first = second = nullptr; ======= first = nullptr; second = nullptr; >>>>>>> 5fc4346 (funktioniert, 3 oder 6 + Timer komplett) } // Gewinnprüfung if (!gameWon) { // Prüft, ob ALLE Würfel gematcht sind gameWon = std::all_of(cubes.begin(), cubes.end(), [](const gamecube &c){ return c.IsMatched(); }); if (gameWon) { endTime = GetTime() - startTime; } } break; } // ENDE GAMEPLAY UPDATE } // ----------------------------------------------------------- // ZEICHNEN NACH ZUSTAND // ----------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); switch (currentScreen) { case MENU: { // Menü-Darstellung DrawText("3D MEMORY SPIEL", GetScreenWidth() / 2 - MeasureText("3D MEMORY SPIEL", 50) / 2, 80, 50, DARKGRAY); DrawText("Waehlen Sie die Spielgroesse:", 50, 200, 25, BLACK); DrawText("Druecken Sie [3] fuer 3 Paare (6 Wuerfel)", 50, 240, 20, BLUE); DrawText("Druecken Sie [6] fuer 6 Paare (12 Wuerfel)", 50, 280, 20, BLUE); break; } case GAMEPLAY: { // Spiel-Darstellung BeginMode3D(camera); for (auto &c : cubes) c.Draw(); EndMode3D(); if (gameWon) { DrawText("Congrats! You found all pairs!", 150, 260, 30, DARKBLUE); char buffer[64]; sprintf(buffer, "Cleared in %.2f seconds", endTime); DrawText(buffer, 150, 300, 28, DARKGREEN); } else { DrawText("Flip 2 cubes - find matching pairs!", 10, 10, 20, DARKGRAY); char liveBuf[64]; sprintf(liveBuf, "Time: %.2f", GetTime() - startTime); DrawText(liveBuf, 10, 40, 20, DARKGRAY); char moveBuf[64]; snprintf(moveBuf, sizeof(moveBuf), "Moves: %d", moves); DrawText(moveBuf, 10, 70, 20, DARKGRAY); } break; } // ENDE GAMEPLAY DRAW } EndDrawing(); } CloseWindow(); return 0; }