Merge: kolizja z płotem pod klawiszem 'k', naprawiony limit FPS

This commit is contained in:
2025-01-17 13:52:25 +01:00
5 changed files with 150 additions and 48 deletions

View File

@@ -10,6 +10,7 @@ public:
auto currentTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = currentTime - lastTime; std::chrono::duration<double> elapsed = currentTime - lastTime;
// Aktualizujemy FPS co 1 sekundê
if (elapsed.count() >= 1.0) { if (elapsed.count() >= 1.0) {
double fps = frameCount / elapsed.count(); double fps = frameCount / elapsed.count();
std::cout << "FPS: " << fps << std::endl; std::cout << "FPS: " << fps << std::endl;

0
Rover.cpp Normal file
View File

View File

@@ -123,6 +123,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="FPSCounter.cpp" /> <ClCompile Include="FPSCounter.cpp" />
<ClCompile Include="glew.c" /> <ClCompile Include="glew.c" />
<ClCompile Include="Rover.cpp" />
<ClCompile Include="lazik.cpp" /> <ClCompile Include="lazik.cpp" />
<ClCompile Include="loadOBJ.cpp" /> <ClCompile Include="loadOBJ.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />

View File

@@ -36,6 +36,15 @@
<ClCompile Include="FPSCounter.cpp"> <ClCompile Include="FPSCounter.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="shader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="texture.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Rover.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="loadOBJ.h"> <ClInclude Include="loadOBJ.h">

177
main.cpp
View File

@@ -85,19 +85,25 @@ std::time_t monitormodehelper;
FPSCounter fpsCounter; FPSCounter fpsCounter;
static const int targetFPS = 144; // Celowany FPS static const int targetFPS = 144; // Celowany FPS
//Fps counter //Fps counter
void LimitFPS(int targetFPS) { void LimitFPS(int targetFPS) {
static auto lastTime = std::chrono::high_resolution_clock::now(); static auto lastTime = std::chrono::steady_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed = currentTime - lastTime; std::chrono::duration<double> 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 double frameTime = 1.0 / targetFPS; // Czas na jedną klatkę w sekundach
if (elapsed.count() < frameTime) { double timeToWait = frameTime - elapsed.count(); // Obliczamy czas do czekania
std::this_thread::sleep_for(std::chrono::duration<double>(frameTime - elapsed.count()));
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<double>(timeToWait));
} }
lastTime = std::chrono::high_resolution_clock::now(); lastTime = currentTime; // Zaktualizuj czas dla następnej iteracji
} }
bool Kolizja = false;
bool keyWPressed = false; bool keyWPressed = false;
bool keySPressed = false; bool keySPressed = false;
bool keyAPressed = false; bool keyAPressed = false;
@@ -112,46 +118,67 @@ float MoveSpeed = 1.0f; // Prędkość poruszania się
float velocity = 0.0f; // Aktualna prędkość łazika 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 maxSpeed = 3.0f; // Maksymalna prędkość łazika
const float acceleration = 0.2f; const float acceleration = 0.2f;
float rotationVelocity = 0.0f; // Prędkość obrotu łazika float rotationVelocity = 0.0f; // Prędkość obrotu łazika
const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu const float rotationAcceleration = 0.1f; // Przyspieszenie obrotu
const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu const float rotationFriction = 0.05f; // Współczynnik tarcia obrotu
const float maxRotationSpeed = 3.0f; // Maksymalna prędkość 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;
// Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu
// Funkcja do poruszania łazikiem if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X
void MoveRover(bool forward) { roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z
// Zamieniamy kąt na radiany return true;
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;
}
// 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;
// Funkcja do obracania łazika wokół osi Y // Sprawdzenie, czy którykolwiek fragment łazika wchodzi w obszar płotu
void RotateRoverAndCamera(float angle) { if (roverXMax >= xMin && roverXMin <= xMax && // Kolizja w osi X
Rotation += angle; roverZMax >= zMin && roverZMin <= zMax) { // Kolizja w osi Z
if (Rotation >= 360.0f) Rotation -= 360.0f; return true;
if (Rotation < 0.0f) Rotation += 360.0f; }
}
return false;
} }
void UpdateRover() { // Funkcja ogólna do sprawdzania kolizji ze wszystkimi płotami
bool CheckAllFencesCollision(float roverXMin, float roverXMax, float roverZMin, float roverZMax, const std::vector<Plot>& 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(const std::vector<Plot>& fences) {
// Przyspieszanie w przód // Przyspieszanie w przód
if (keyWPressed) { if (keyWPressed) {
velocity += acceleration; velocity += acceleration;
@@ -195,16 +222,76 @@ void UpdateRover() {
} }
} }
// Aktualizacja pozycji na podstawie prędkości // Wyliczenie nowej pozycji na podstawie prędkości
float radRotation = Rotation * GL_PI / 180.0f; float radRotation = Rotation * GL_PI / 180.0f; // Przeliczamy rotację na radiany
Sides -= velocity * cos(radRotation); float newSides = Sides - velocity * cos(radRotation); // Nowa pozycja w osi X
Foward -= velocity * sin(radRotation); float newFoward = Foward - velocity * sin(radRotation); // Nowa pozycja w osi Z
// Aktualizacja kąta obrotu // 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; Rotation += rotationVelocity;
if (Rotation >= 360.0f) Rotation -= 360.0f; if (Rotation >= 360.0f) Rotation -= 360.0f;
if (Rotation < 0.0f) Rotation += 360.0f; if (Rotation < 0.0f) Rotation += 360.0f;
} }
}
std::vector<Plot> 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 // Change viewing volume and viewport. Called when window is resized
void ChangeSize(GLsizei w, GLsizei h) { void ChangeSize(GLsizei w, GLsizei h) {
@@ -769,6 +856,7 @@ void SetupRC() {
void RenderScene(void) { void RenderScene(void) {
//float normal[3]; // Storage for calculated surface normal //float normal[3]; // Storage for calculated surface normal
// Save the matrix state and do the rotations // Save the matrix state and do the rotations
@@ -831,8 +919,9 @@ void RenderScene(void) {
glTranslatef(Foward, 0.0f, Sides); // Translacja łazika na jego pozycję 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 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 glColor3f(1.0, 0.0, 0.0); // Czerwony kolor dla łazika
fpsCounter.update();
user.draw(); user.draw();
UpdateRover(); UpdateRover(fences);
glPopMatrix(); glPopMatrix();
//skrzynka(50); //skrzynka(50);
@@ -850,7 +939,7 @@ void RenderScene(void) {
//glColor3f(0.0, 1.0, 0.0); //glColor3f(0.0, 1.0, 0.0);
//mapa.draw(); //mapa.draw();
//glColor3f(0.0, 0.0, 0.0); //glColor3f(0.0, 0.0, 0.0);
fpsCounter.update();
// Zamiana buforów (double buffering) // Zamiana buforów (double buffering)
@@ -1160,11 +1249,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
//break; //break;
// Limit FPS // Limit FPS
LimitFPS(targetFPS); // Uaktualniaj FPS
LimitFPS(targetFPS); // Ogranicz FPS
// Update FPS counter
if (monitormode) fpsCounter.update();
break;
case WM_QUERYNEWPALETTE: case WM_QUERYNEWPALETTE:
// If the palette was created. // If the palette was created.
@@ -1266,6 +1354,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
polygonmode = !polygonmode; polygonmode = !polygonmode;
if (polygonmode) timestampedCout("Uwaga! Tryb wireframe jest niewydajny i powinien sluzyc tylko do debugowania!"); if (polygonmode) timestampedCout("Uwaga! Tryb wireframe jest niewydajny i powinien sluzyc tylko do debugowania!");
break; break;
case 'K':
Kolizja = !Kolizja;
break;
case 'W': case 'W':
keyWPressed = true; keyWPressed = true;