From 26954f634946e35d7d57841142255d4390db699a Mon Sep 17 00:00:00 2001 From: Pc Date: Wed, 8 Jan 2025 14:59:02 +0100 Subject: [PATCH 1/3] OK --- main.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/main.cpp b/main.cpp index 29ca6ff..f7bbbba 100644 --- a/main.cpp +++ b/main.cpp @@ -75,6 +75,159 @@ int monitormode = 0; int monitormodecounter = 0; std::time_t monitormodehelper; + + +//Zmienne do ruchu ##############################################^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +FPSCounter fpsCounter; +static const int targetFPS = 144; // Celowany FPS +//Fps counter +void LimitFPS(int targetFPS) { + static auto lastTime = std::chrono::high_resolution_clock::now(); + auto currentTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = currentTime - lastTime; + + // JeÅ›li upÅ‚ynęło za maÅ‚o czasu, aby osiÄ…gnąć target FPS, czekamy + double frameTime = 1.0 / targetFPS; // Czas na jednÄ… klatkÄ™ w sekundach + if (elapsed.count() < frameTime) { + std::this_thread::sleep_for(std::chrono::duration(frameTime - elapsed.count())); + } + + lastTime = std::chrono::high_resolution_clock::now(); +} +bool keyWPressed = false; +bool keySPressed = false; +bool keyAPressed = false; +bool keyDPressed = false; + +float Foward = 0.0f; // Pozycja Å‚azika w przód/tyÅ‚ +float Sides = 0.0f; // Pozycja Å‚azika w lewo/prawo +float Rotation = 0.0f; // Rotacja Å‚azika (w stopniach) + +float CameraHeight = 50.0f; // Wysokość kamery +float MoveSpeed = 1.0f; // PrÄ™dkość poruszania siÄ™ + + +float velocity = 0.0f; // Aktualna prÄ™dkość Å‚azika +const float friction = 0.05f; // Współczynnik tarcia (μ) +const float maxSpeed = 3.0f; // Maksymalna prÄ™dkość Å‚azika +const float acceleration = 0.2f; +float rotationVelocity = 0.0f; // PrÄ™dkość obrotu Å‚azika +const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu +const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu +const float maxRotationSpeed = 3.0f; // Maksymalna prÄ™dkość obrotu + + + + + +// Funkcja do obracania Å‚azika wokół osi Y +void RotateRoverAndCamera(float angle) { + Rotation += angle; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; +} +void UpdateRover() { + bool isMovingForward = velocity > 0; + + // Przyspieszanie w przód + if (keyWPressed) { + velocity += acceleration; + if (velocity > maxSpeed) velocity = maxSpeed; + } + // Przyspieszanie w tyÅ‚ + else if (keySPressed) { + velocity -= acceleration; + if (velocity < -maxSpeed) velocity = -maxSpeed; + } + // Hamowanie (wytracanie prÄ™dkoÅ›ci z powodu tarcia) + else { + if (velocity > 0) { + velocity -= friction; + if (velocity < 0) velocity = 0; + } + else if (velocity < 0) { + velocity += friction; + if (velocity > 0) velocity = 0; + } + } + + // Zmienna do rozpoznania kierunku obrotu + int rotationDirection = 0; + + // Obracanie (zależnie od kierunku ruchu) + if (keyAPressed) { + if (isMovingForward) { + // Obracanie w lewo, gdy poruszamy siÄ™ do przodu + rotationDirection = -1; // W lewo + rotationVelocity += rotationAcceleration; + } else { + // Obracanie w prawo, gdy poruszamy siÄ™ do tyÅ‚u + rotationDirection = 1; // W prawo + rotationVelocity -= rotationAcceleration; + } + } + else if (keyDPressed) { + if (isMovingForward) { + // Obracanie w prawo, gdy poruszamy siÄ™ do przodu + rotationDirection = 1; // W prawo + rotationVelocity -= rotationAcceleration; + } else { + // Obracanie w lewo, gdy poruszamy siÄ™ do tyÅ‚u + rotationDirection = -1; // W lewo + rotationVelocity += rotationAcceleration; + } + } + else { + // Trzeci warunek: Hamowanie obrotu (gdy brak wciÅ›niÄ™tych klawiszy A i D, ale poruszamy siÄ™) + if (velocity != 0) { + if (rotationVelocity > 0) { + rotationVelocity -= rotationFriction; + if (rotationVelocity < 0) rotationVelocity = 0; + } + else if (rotationVelocity < 0) { + rotationVelocity += rotationFriction; + if (rotationVelocity > 0) rotationVelocity = 0; + } + } + else { + // Czwarty warunek: Kiedy nie poruszamy siÄ™ ani do przodu, ani do tyÅ‚u + // Hamowanie obrotu, ale nie przyspieszamy + if (rotationVelocity > 0) { + rotationVelocity -= rotationFriction; + if (rotationVelocity < 0) rotationVelocity = 0; + } + else if (rotationVelocity < 0) { + rotationVelocity += rotationFriction; + if (rotationVelocity > 0) rotationVelocity = 0; + } + } + } + + // Ogranicz prÄ™dkość obrotu, aby nie rosÅ‚a zbyt szybko + if (rotationVelocity > maxRotationSpeed) rotationVelocity = maxRotationSpeed; + if (rotationVelocity < -maxRotationSpeed) rotationVelocity = -maxRotationSpeed; + + // **Aktualizacja pozycji w kierunku przód-tyÅ‚ (ruch w osi Y)**: + // Poruszamy siÄ™ na podstawie wartoÅ›ci `velocity` wzdÅ‚uż osi Y + float radRotation = Rotation * GL_PI / 180.0f; + Foward -= velocity * sin(radRotation); // Przemieszczanie siÄ™ wzdÅ‚uż osi Y (przód-tyÅ‚) + + // **Aktualizacja pozycji w lewo-prawo (ruch w osi X)**: + // Przemieszczanie w poziomie (w lewo/prawo) odbywa siÄ™ w zależnoÅ›ci od prÄ™dkoÅ›ci + Sides -= velocity * cos(radRotation); // Przemieszczanie siÄ™ wzdÅ‚uż osi X (lewo/prawo) + + // Aktualizacja kÄ…ta obrotu (obrot w zależnoÅ›ci od wartoÅ›ci `rotationVelocity`) + Rotation += rotationVelocity; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; +} + + + + + + + // Change viewing volume and viewport. Called when window is resized void ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 100.0f; From cfb3f12ef455073e4d3723e1a78190f74510bc75 Mon Sep 17 00:00:00 2001 From: Pc Date: Thu, 16 Jan 2025 23:46:42 +0100 Subject: [PATCH 2/3] Kolizja z plotem --- Rover.cpp | 0 grafikaKBT.vcxproj | 1 + grafikaKBT.vcxproj.filters | 11 ++- main.cpp | 160 ++++++++++++++++++++++++++++--------- 4 files changed, 134 insertions(+), 38 deletions(-) create mode 100644 Rover.cpp diff --git a/Rover.cpp b/Rover.cpp new file mode 100644 index 0000000..e69de29 diff --git a/grafikaKBT.vcxproj b/grafikaKBT.vcxproj index 28784d3..8d5ad99 100644 --- a/grafikaKBT.vcxproj +++ b/grafikaKBT.vcxproj @@ -123,6 +123,7 @@ + diff --git a/grafikaKBT.vcxproj.filters b/grafikaKBT.vcxproj.filters index 2f91739..3bbb550 100644 --- a/grafikaKBT.vcxproj.filters +++ b/grafikaKBT.vcxproj.filters @@ -36,6 +36,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -65,4 +74,4 @@ Source Files - + \ No newline at end of file diff --git a/main.cpp b/main.cpp index 5ccf6ae..6f94d21 100644 --- a/main.cpp +++ b/main.cpp @@ -98,6 +98,7 @@ void LimitFPS(int targetFPS) { lastTime = std::chrono::high_resolution_clock::now(); } +bool Kolizja = false; bool keyWPressed = false; bool keySPressed = false; bool keyAPressed = false; @@ -112,46 +113,67 @@ float MoveSpeed = 1.0f; // PrÄ™dkość poruszania siÄ™ float velocity = 0.0f; // Aktualna prÄ™dkość Å‚azika -const float friction = 0.1f; // Współczynnik tarcia (μ) +const float friction = 0.05f; // Współczynnik tarcia (μ) const float maxSpeed = 3.0f; // Maksymalna prÄ™dkość Å‚azika const float acceleration = 0.2f; + float rotationVelocity = 0.0f; // PrÄ™dkość obrotu Å‚azika + const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu const float maxRotationSpeed = 3.0f; // Maksymalna prÄ™dkość obrotu +// Struktura do reprezentacji pÅ‚otu +struct Plot { + GLfloat xc; // Åšrodek pÅ‚otu w osi X + GLfloat yc; // Åšrodek pÅ‚otu w osi Y (nieużywane w kolizji, ale może być pomocne) + GLfloat zc; // Åšrodek pÅ‚otu w osi Z + GLfloat length; // DÅ‚ugość pÅ‚otu + GLfloat gruboscY; // Grubość pÅ‚otu + bool mod_x; // 0 - pÅ‚ot pionowy, 1 - pÅ‚ot poziomy +}; +// Funkcja sprawdzajÄ…ca kolizjÄ™ z pÅ‚otem +// Funkcja sprawdzajÄ…ca kolizjÄ™ z pÅ‚otem, uwzglÄ™dniajÄ…c wymiary Å‚azika +bool CheckFenceCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const Plot& plot) { + if (plot.mod_x == 0) { // PÅ‚ot pionowy (równolegÅ‚y do osi Z) + float xMin = plot.xc - plot.gruboscY / 2.0f; + float xMax = plot.xc + plot.gruboscY / 2.0f; + float zMin = plot.zc - plot.length / 2.0f; + float zMax = plot.zc + plot.length / 2.0f; - -// Funkcja do poruszania Å‚azikiem -void MoveRover(bool forward) { - // Zamieniamy kÄ…t na radiany - float radRotation = Rotation * GL_PI / 180.0f; - - // Wektor ruchu w kierunku przód/tyÅ‚ (kierunek Å‚azika) - float moveX = cos(radRotation); - float moveZ = sin(radRotation); - - // Ruch w przód - if (forward) { - Sides -= MoveSpeed * moveX; - Foward -= MoveSpeed * moveZ; + // Sprawdzenie, czy którykolwiek fragment Å‚azika wchodzi w obszar pÅ‚otu + if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X + roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z + return true; + } } - // Ruch w tyÅ‚ - else { - Sides += MoveSpeed * moveX; - Foward += MoveSpeed * moveZ; + else { // PÅ‚ot poziomy (równolegÅ‚y do osi X) + float xMin = plot.xc - plot.length / 2.0f; + float xMax = plot.xc + plot.length / 2.0f; + float zMin = plot.zc - plot.gruboscY / 2.0f; + float zMax = plot.zc + plot.gruboscY / 2.0f; + + // Sprawdzenie, czy którykolwiek fragment Å‚azika wchodzi w obszar pÅ‚otu + if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X + roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z + return true; + } } + return false; } -// Funkcja do obracania Å‚azika wokół osi Y -void RotateRoverAndCamera(float angle) { - Rotation += angle; - if (Rotation >= 360.0f) Rotation -= 360.0f; - if (Rotation < 0.0f) Rotation += 360.0f; +// Funkcja ogólna do sprawdzania kolizji ze wszystkimi pÅ‚otami +bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector& fences) { + for (const auto& fence : fences) { + if (CheckFenceCollision(roverXMin, roverXMax, roverZMin, roverZMax, fence)) { + return true; // Kolizja wykryta z którymÅ› pÅ‚otem + } + } + return false; // Brak kolizji } -void UpdateRover() { +void UpdateRover(const std::vector& fences) { // Przyspieszanie w przód if (keyWPressed) { velocity += acceleration; @@ -195,17 +217,77 @@ void UpdateRover() { } } - // Aktualizacja pozycji na podstawie prÄ™dkoÅ›ci - float radRotation = Rotation * GL_PI / 180.0f; - Sides -= velocity * cos(radRotation); - Foward -= velocity * sin(radRotation); + // Wyliczenie nowej pozycji na podstawie prÄ™dkoÅ›ci + float radRotation = Rotation * GL_PI / 180.0f; // Przeliczamy rotacjÄ™ na radiany + float newSides = Sides - velocity * cos(radRotation); // Nowa pozycja w osi X + float newFoward = Foward - velocity * sin(radRotation); // Nowa pozycja w osi Z - // Aktualizacja kÄ…ta obrotu - Rotation += rotationVelocity; - if (Rotation >= 360.0f) Rotation -= 360.0f; - if (Rotation < 0.0f) Rotation += 360.0f; + // Wyliczenie obszaru zajmowanego przez Å‚azik + float roverXMin = newSides - 15.0f; + float roverXMax = newSides + 15.0f; + float roverZMin = newFoward - 15.0f; + float roverZMax = newFoward + 15.0f; + + // Sprawdzanie kolizji przed aktualizacjÄ… pozycji + if (Kolizja == true) { + if (CheckAllFencesCollision(roverXMin, roverXMax, roverZMin, roverZMax, fences)) { + // JeÅ›li jest kolizja, zatrzymujemy Å‚azik + velocity = 0.0f; + cout << "Kolizja podczas ruchu\n"; + } + else { + // JeÅ›li brak kolizji, aktualizujemy pozycjÄ™ + Sides = newSides; + Foward = newFoward; + } + + // Sprawdzanie kolizji podczas obrotu + if (rotationVelocity != 0.0f) { + // Wyliczamy narożniki Å‚azika po obrocie + float newRotation = Rotation + rotationVelocity; + float radNewRotation = newRotation * GL_PI / 180.0f; + + // Wyliczamy offsety narożników w nowych współrzÄ™dnych + float offsetX = 15.0f * cos(radNewRotation); + float offsetZ = 15.0f * sin(radNewRotation); + + // Wyznaczamy nowe granice Å‚azika + float rotatedXMin = Sides - offsetX; + float rotatedXMax = Sides + offsetX; + float rotatedZMin = Foward - offsetZ; + float rotatedZMax = Foward + offsetZ; + + // Sprawdzamy kolizjÄ™ dla granic po obrocie + if (CheckAllFencesCollision(rotatedXMin, rotatedXMax, rotatedZMin, rotatedZMax, fences)) { + rotationVelocity = 0.0f; // Zatrzymujemy obrót w przypadku kolizji + cout << "Kolizja podczas obrotu\n"; + } + else { + // Aktualizujemy rotacjÄ™ tylko, jeÅ›li nie ma kolizji + Rotation = newRotation; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; + } + } + } + else { + // JeÅ›li kolizje sÄ… wyłączone, aktualizujemy wszystko bez sprawdzania + Sides = newSides; + Foward = newFoward; + Rotation += rotationVelocity; + if (Rotation >= 360.0f) Rotation -= 360.0f; + if (Rotation < 0.0f) Rotation += 360.0f; + } } + +std::vector fences = { + {-10.0f, 3.0f, 45.0f, 130.0f, 4.0f, 0}, + { 50.0f, 3.0f, -20.0f, 120.0f, 4.0f, 1}, + {110.0f, 3.0f, 45.0f, 130.0f, 4.0f, 0}, + { 50.0f, 3.0f, 110.0f, 120.0f, 4.0f, 1} +}; + // Change viewing volume and viewport. Called when window is resized void ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 100.0f; @@ -683,7 +765,7 @@ void plot(GLfloat xc, GLfloat yc, GLfloat zc, GLfloat length, GLfloat gruboscY, //GLuint programID, VertexArrayID, MatrixID; lazik user(10.0f, 0.0f, 0.0f, "res/models/lazik4.obj"); // obiekty eksportujemy z Forward Axis Z, Up Axis Y. -plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3"); +plane mapa( 0.0f, 0.0f, 0.0f, "res/models/mapka3_nofence_noplatform.obj"); void SetupRC() { // Light values and coordinates @@ -817,7 +899,7 @@ void RenderScene(void) { Foward, 0.0f, Sides, // Punkt, na który patrzy kamera (Å‚azik) 0.0f, 1.0f, 0.0f // Wektor "góry" ); - + // Rysowanie mapy (nie porusza siÄ™) glPushMatrix(); glColor3f(0.0, 1.0, 0.0); // Zielony kolor dla mapy @@ -827,12 +909,13 @@ void RenderScene(void) { // Rysowanie Å‚azika (porusza siÄ™ i obraca) glPushMatrix(); - + glTranslatef(Foward, 0.0f, Sides); // Translacja Å‚azika na jego pozycjÄ™ glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót Å‚azika wokół wÅ‚asnej osi glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla Å‚azika + user.draw(); - UpdateRover(); + UpdateRover(fences); glPopMatrix(); //skrzynka(50); @@ -1266,6 +1349,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) polygonmode = !polygonmode; if (polygonmode) timestampedCout("Uwaga! Tryb wireframe jest niewydajny i powinien sluzyc tylko do debugowania!"); break; + case 'K': + Kolizja = !Kolizja; + break; case 'W': keyWPressed = true; From bea13b98f32d9a1a81d5a036002ca64eeeffb2ab Mon Sep 17 00:00:00 2001 From: Pc Date: Thu, 16 Jan 2025 23:59:40 +0100 Subject: [PATCH 3/3] Fixed Fps limit --- FPSCounter.cpp | 1 + main.cpp | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/FPSCounter.cpp b/FPSCounter.cpp index 61144c3..5fd25eb 100644 --- a/FPSCounter.cpp +++ b/FPSCounter.cpp @@ -10,6 +10,7 @@ public: auto currentTime = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = currentTime - lastTime; + // Aktualizujemy FPS co 1 sekundê if (elapsed.count() >= 1.0) { double fps = frameCount / elapsed.count(); std::cout << "FPS: " << fps << std::endl; diff --git a/main.cpp b/main.cpp index 6f94d21..8f2c5e7 100644 --- a/main.cpp +++ b/main.cpp @@ -85,19 +85,24 @@ std::time_t monitormodehelper; FPSCounter fpsCounter; static const int targetFPS = 144; // Celowany FPS //Fps counter + void LimitFPS(int targetFPS) { - static auto lastTime = std::chrono::high_resolution_clock::now(); - auto currentTime = std::chrono::high_resolution_clock::now(); + static auto lastTime = std::chrono::steady_clock::now(); + auto currentTime = std::chrono::steady_clock::now(); std::chrono::duration elapsed = currentTime - lastTime; - // JeÅ›li upÅ‚ynęło za maÅ‚o czasu, aby osiÄ…gnąć target FPS, czekamy + // Obliczamy czas na jednÄ… klatkÄ™ double frameTime = 1.0 / targetFPS; // Czas na jednÄ… klatkÄ™ w sekundach - if (elapsed.count() < frameTime) { - std::this_thread::sleep_for(std::chrono::duration(frameTime - elapsed.count())); + double timeToWait = frameTime - elapsed.count(); // Obliczamy czas do czekania + + if (timeToWait > 0.0) { + // JeÅ›li czas do czekania jest wiÄ™kszy niż 0, to Å›pimy przez tÄ™ wartość + std::this_thread::sleep_for(std::chrono::duration(timeToWait)); } - lastTime = std::chrono::high_resolution_clock::now(); + lastTime = currentTime; // Zaktualizuj czas dla nastÄ™pnej iteracji } + bool Kolizja = false; bool keyWPressed = false; bool keySPressed = false; @@ -851,6 +856,7 @@ void SetupRC() { void RenderScene(void) { + //float normal[3]; // Storage for calculated surface normal // Save the matrix state and do the rotations @@ -913,7 +919,7 @@ void RenderScene(void) { glTranslatef(Foward, 0.0f, Sides); // Translacja Å‚azika na jego pozycjÄ™ glRotatef(Rotation, 0.0f, 1.0f, 0.0f); // Obrót Å‚azika wokół wÅ‚asnej osi glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla Å‚azika - + fpsCounter.update(); user.draw(); UpdateRover(fences); glPopMatrix(); @@ -933,7 +939,7 @@ void RenderScene(void) { //glColor3f(0.0, 1.0, 0.0); //mapa.draw(); //glColor3f(0.0, 0.0, 0.0); - fpsCounter.update(); + // Zamiana buforów (double buffering) @@ -1243,11 +1249,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //break; // Limit FPS - LimitFPS(targetFPS); + // Uaktualniaj FPS + LimitFPS(targetFPS); // Ogranicz FPS - // Update FPS counter - if (monitormode) fpsCounter.update(); - break; + case WM_QUERYNEWPALETTE: // If the palette was created.