diff --git a/SQCSim2021/SQCSim2021.vcxproj b/SQCSim2021/SQCSim2021.vcxproj index c79a090..e88b06c 100644 --- a/SQCSim2021/SQCSim2021.vcxproj +++ b/SQCSim2021/SQCSim2021.vcxproj @@ -37,6 +37,7 @@ + @@ -53,6 +54,7 @@ + {A21FD938-1FEA-4687-AB86-0EABAC30877B} diff --git a/SQCSim2021/SQCSim2021.vcxproj.filters b/SQCSim2021/SQCSim2021.vcxproj.filters index 353069b..6b161c0 100644 --- a/SQCSim2021/SQCSim2021.vcxproj.filters +++ b/SQCSim2021/SQCSim2021.vcxproj.filters @@ -65,6 +65,9 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + @@ -109,5 +112,8 @@ Fichiers sources + + Fichiers sources + \ No newline at end of file diff --git a/SQCSim2021/chunk.cpp b/SQCSim2021/chunk.cpp index 8bd383a..17884ae 100644 --- a/SQCSim2021/chunk.cpp +++ b/SQCSim2021/chunk.cpp @@ -50,45 +50,45 @@ void Chunk::AddBlockToMesh(VertexBuffer::VertexData* vd, int& count, BlockType b int x, int y, int z, float u, float v, float s) { if (x == CHUNK_SIZE_X - 1 || GetBlock(x + 1, y, z) == BTYPE_AIR) { // x - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .9f, .9f, .9f, u, v); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .9f, .9f, .9f, u, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .9f, .9f, .9f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .9f, .9f, .9f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z, .9f, .9f, .9f, u, v); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z, .9f, .9f, .9f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z + 1.f, .9f, .9f, .9f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, .9f, .9f, .9f, u + s, v); } if (x == 0 || GetBlock(x - 1, y, z) == BTYPE_AIR) { // -x - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .9f, .9f, .9f, u, v + s); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .9f, .9f, .9f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .9f, .9f, .9f, u + s, v); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .9f, .9f, .9f, u, v); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, .9f, .9f, .9f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z, .9f, .9f, .9f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x, y, z, .9f, .9f, .9f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .9f, .9f, .9f, u, v); } if (y == CHUNK_SIZE_Y - 1 || GetBlock(x, y + 1, z) == BTYPE_AIR) { // y - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, .8f, .8f, .8f, u, v); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, .8f, .8f, .8f, u, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, .8f, .8f, .8f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, .8f, .8f, .8f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z, .8f, .8f, .8f, u, v); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, .8f, .8f, .8f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z + 1.f, .8f, .8f, .8f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z, .8f, .8f, .8f, u + s, v); } - + if (y == 0 || GetBlock(x, y - 1, z) == BTYPE_AIR) { // -y - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, .8f, .8f, .8f, u, v); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, .8f, .8f, .8f, u, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, .8f, .8f, .8f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, .8f, .8f, .8f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, .8f, .8f, .8f, u, v); + vd[count++] = VertexBuffer::VertexData(x, y, z, .8f, .8f, .8f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z, .8f, .8f, .8f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, .8f, .8f, .8f, u + s, v); } if (z == CHUNK_SIZE_Z - 1 || GetBlock(x, y, z + 1) == BTYPE_AIR) { // z - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, u, v); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z + .5f, 1.f, 1.f, 1.f, u + s, v); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z + .5f, 1.f, 1.f, 1.f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x, y, z + 1.f, 1.f, 1.f, 1.f, u, v); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z + 1.f, 1.f, 1.f, 1.f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z + 1.f, 1.f, 1.f, 1.f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z + 1.f, 1.f, 1.f, 1.f, u, v + s); } if (z == 0 || GetBlock(x, y, z - 1) == BTYPE_AIR) { // -z - vd[count++] = VertexBuffer::VertexData(x - .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, u, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y + .5f, z - .5f, 1.f, 1.f, 1.f, u + s, v + s); - vd[count++] = VertexBuffer::VertexData(x + .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, u + s, v); - vd[count++] = VertexBuffer::VertexData(x - .5f, y - .5f, z - .5f, 1.f, 1.f, 1.f, u, v); + vd[count++] = VertexBuffer::VertexData(x, y + 1.f, z, 1.f, 1.f, 1.f, u, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y + 1.f, z, 1.f, 1.f, 1.f, u + s, v + s); + vd[count++] = VertexBuffer::VertexData(x + 1.f, y, z, 1.f, 1.f, 1.f, u + s, v); + vd[count++] = VertexBuffer::VertexData(x, y, z, 1.f, 1.f, 1.f, u, v); } } diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index ab35a31..6815f1d 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -45,26 +45,90 @@ void Engine::Init() m_skybox.Init(0.00013f); // Objet de musique! - //m_audio.ToggleMusicState(); + m_audio.ToggleMusicState(); + for (int x = 0; x < CHUNK_SIZE_X; ++x) + for (int z = 0; z < CHUNK_SIZE_Z; ++z) + for (int y = 0; y < 32; ++y) + m_copychunk.SetBlock(x, y, z, BTYPE_GRASS); + + m_copychunk.SetBlock(5, 32, 15, BTYPE_GRASS); + m_copychunk.SetBlock(5, 33, 15, BTYPE_GRASS); + m_copychunk.SetBlock(5, 34, 15, BTYPE_GRASS); + m_copychunk.SetBlock(6, 34, 15, BTYPE_GRASS); + m_copychunk.SetBlock(7, 34, 15, BTYPE_GRASS); + m_copychunk.SetBlock(7, 33, 15, BTYPE_GRASS); + m_copychunk.SetBlock(7, 32, 15, BTYPE_GRASS); + m_copychunk.SetBlock(8, 32, 3, BTYPE_GRASS); + m_copychunk.SetBlock(8, 33, 4, BTYPE_GRASS); + m_copychunk.SetBlock(8, 34, 5, BTYPE_GRASS); + m_copychunk.SetBlock(8, 35, 6, BTYPE_GRASS); + m_copychunk.SetBlock(11, 32, 5, BTYPE_GRASS); + m_copychunk.SetBlock(11, 33, 5, BTYPE_GRASS); + m_copychunk.SetBlock(11, 34, 5, BTYPE_GRASS); + m_copychunk.SetBlock(11, 35, 5, BTYPE_GRASS); + m_copychunk.SetBlock(12, 32, 5, BTYPE_GRASS); + m_copychunk.SetBlock(12, 33, 5, BTYPE_GRASS); + m_copychunk.SetBlock(12, 34, 5, BTYPE_GRASS); + m_copychunk.SetBlock(12, 35, 5, BTYPE_GRASS); + m_copychunk.SetBlock(13, 32, 5, BTYPE_GRASS); + m_copychunk.SetBlock(13, 33, 5, BTYPE_GRASS); + m_copychunk.SetBlock(13, 34, 5, BTYPE_GRASS); + m_copychunk.SetBlock(13, 35, 5, BTYPE_GRASS); + m_copychunk.SetBlock(14, 32, 5, BTYPE_GRASS); + m_copychunk.SetBlock(14, 33, 5, BTYPE_GRASS); + m_copychunk.SetBlock(14, 34, 5, BTYPE_GRASS); + m_copychunk.SetBlock(14, 35, 5, BTYPE_GRASS); + + for (int chx = 0; chx < VIEW_DISTANCE; ++chx) + for (int chy = 0; chy < VIEW_DISTANCE; ++chy) + m_world.GetChunks().Set(chx, chy, &m_copychunk); // Init Chunks - for (int chx = 0; chx < VIEW_DISTANCE; ++chx) - for (int chy = 0; chy < VIEW_DISTANCE; ++chy) - m_chunks.Set(chx, chy, new Chunk(chx, chy)); + //for (int chx = 0; chx < VIEW_DISTANCE; ++chx) + // for (int chy = 0; chy < VIEW_DISTANCE; ++chy) + // m_world.GetChunks().Set(chx, chy, new Chunk(chx, chy)); - // Génération Chunks. - for (int chx = 0; chx < VIEW_DISTANCE; ++chx) - for (int chy = 0; chy < VIEW_DISTANCE; ++chy) { + // // Génération Chunks. + // for (int chx = 0; chx < VIEW_DISTANCE; ++chx) + // for (int chy = 0; chy < VIEW_DISTANCE; ++chy) { - for (int x = 0; x < CHUNK_SIZE_X; ++x) - for (int z = 0; z < CHUNK_SIZE_Z; ++z) - for (int y = 0; y < 32; ++y) - m_chunks.Get(chx, chy)->SetBlock(x, y, z, BTYPE_DIRT); + // for (int x = 0; x < CHUNK_SIZE_X; ++x) + // for (int z = 0; z < CHUNK_SIZE_Z; ++z) + // for (int y = 0; y < 32; ++y) + // m_world.GetChunks().Get(chx, chy)->SetBlock(x, y, z, BTYPE_GRASS); - m_chunks.Get(chx, chy)->SetBlock(8, chx + 32, 8, BTYPE_DIRT); + // m_world.GetChunks().Get(chx, chy)->SetBlock(5, 32, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(5, 33, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(5, 34, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(6, 34, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(7, 34, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(7, 33, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(7, 32, 15, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(8, 32, 3, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(8, 33, 4, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(8, 34, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(8, 35, 6, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(11, 32, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(11, 33, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(11, 34, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(11, 35, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(12, 32, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(12, 33, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(12, 34, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(12, 35, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(13, 32, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(13, 33, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(13, 34, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(13, 35, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(14, 32, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(14, 33, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(14, 34, 5, BTYPE_GRASS); + // m_world.GetChunks().Get(chx, chy)->SetBlock(14, 35, 5, BTYPE_GRASS); - } + // //m_world.GetChunks().Get(chx, chy)->SetBlock(8, chx + 32, 8, BTYPE_DIRT); + + // } // Gestion de souris. @@ -111,7 +175,7 @@ void Engine::LoadResource() { } } -void Engine::UnloadResource(){} +void Engine::UnloadResource() {} void Engine::DrawHud(float elapsedTime) { // Setter le blend function , tout ce qui sera noir sera transparent @@ -141,13 +205,16 @@ void Engine::DrawHud(float elapsedTime) { ss.str(""); ss << " Position : " << m_player.GetPosition(); PrintText(10, 30, ss.str()); + ss.str(""); + ss << " Delta : " << m_player.GetPOV(); + PrintText(10, 40, ss.str()); // Affichage du crosshair m_textureCrosshair.Bind(); static const int crossSize = 32; glLoadIdentity(); glTranslated(Width() / 2 - crossSize / 2, Height() / 2 - crossSize / 2, 0); glBegin(GL_QUADS); - glTexCoord2f(0, 0); + glTexCoord2f(0, 0); glVertex2i(0, 0); glTexCoord2f(1, 0); glVertex2i(crossSize, 0); @@ -190,6 +257,7 @@ int Engine::GetFps(float elapsedTime) const { return 1 / elapsedTime; } void Engine::Render(float elapsedTime) { static float gameTime = elapsedTime; + if (elapsedTime > 0.1f) return; gameTime += elapsedTime; @@ -202,7 +270,7 @@ void Engine::Render(float elapsedTime) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - m_player.Move(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, m_keylshift, elapsedTime); + m_player.ApplyPhysics(m_player.GetInput(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, m_keylshift, elapsedTime), m_world, elapsedTime); m_audio.Update3DAudio(m_player.GetPosition(), m_player.GetDirection(), m_player.GetVelocity()); // Ajustement du positionnement 3D avec les coordonnées du joueur et // son vecteur de vélocité (pour l'effet Doppler) m_player.ApplyTransformation(all); @@ -211,8 +279,6 @@ void Engine::Render(float elapsedTime) { glDisable(GL_LIGHT0); m_skybox.Render(skybox); - - // Chunks all.Use(); glEnable(GL_LIGHT0); @@ -220,14 +286,14 @@ void Engine::Render(float elapsedTime) { m_textureAtlas.Bind(); for (int chx = 0; chx < VIEW_DISTANCE; chx++) for (int chy = 0; chy < VIEW_DISTANCE; chy++) { - all.ApplyTranslation(chx * CHUNK_SIZE_X - (VIEW_DISTANCE * CHUNK_SIZE_X / 2), -(CHUNK_SIZE_Y / 2), chy * CHUNK_SIZE_Z - (VIEW_DISTANCE * CHUNK_SIZE_Z / 2)); + all.ApplyTranslation(chx * CHUNK_SIZE_X, 0, chy * CHUNK_SIZE_Z); all.Use(); - if (m_chunks.Get(chx, chy)->IsDirty()) - m_chunks.Get(chx, chy)->Update(m_blockinfo); - m_chunks.Get(chx, chy)->Render(); - all.ApplyTranslation(-(chx * CHUNK_SIZE_X - (VIEW_DISTANCE * CHUNK_SIZE_X / 2)), CHUNK_SIZE_Y / 2, -(chy * CHUNK_SIZE_Z - (VIEW_DISTANCE * CHUNK_SIZE_Z / 2))); + if (m_world.GetChunks().Get(chx, chy)->IsDirty()) + m_world.GetChunks().Get(chx, chy)->Update(m_blockinfo); + m_world.GetChunks().Get(chx, chy)->Render(); + all.ApplyTranslation(-chx * CHUNK_SIZE_X, 0, -chy * CHUNK_SIZE_Z); } - + m_shader01.Disable(); if (m_wireframe) diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index e82f7c2..7c55aa2 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -12,9 +12,9 @@ #include "textureatlas.h" #include "blockinfo.h" #include "array2d.h" +#include "world.h" -class Engine : public OpenglContext -{ +class Engine : public OpenglContext { public: Engine(); virtual ~Engine(); @@ -35,12 +35,12 @@ private: void PrintText(unsigned int x, unsigned int y, const std::string& t); int GetFps(float elapsedTime) const; -private: bool m_wireframe = false; BlockInfo* m_blockinfo[BTYPE_LAST]; TextureAtlas m_textureAtlas = TextureAtlas(BTYPE_LAST); - Array2d m_chunks = Array2d(VIEW_DISTANCE, VIEW_DISTANCE); + World m_world = World(); + Chunk m_copychunk = Chunk(0, 0);; Texture m_textureFloor; Texture m_textureSkybox; @@ -52,7 +52,7 @@ private: Shader m_shader01; Audio m_audio = Audio(AUDIO_PATH "music01.wav"); - Player m_player = Player(Vector3f(0, 0, 0)); + Player m_player = Player(Vector3f(64, 64, 64)); bool m_keyW = false; bool m_keyA = false; @@ -60,6 +60,9 @@ private: bool m_keyD = false; bool m_keylshift = false; bool m_keySpace = false; + + + }; #endif // ENGINE_H__ diff --git a/SQCSim2021/player.cpp b/SQCSim2021/player.cpp index 2f7f80d..2ce8e4b 100644 --- a/SQCSim2021/player.cpp +++ b/SQCSim2021/player.cpp @@ -1,161 +1,236 @@ #include "player.h" -Player::Player(const Vector3f& position, float rotX, float rotY) : m_position(position), m_rotX(rotX), m_rotY(rotY) { +Player::Player(const Vector3f& position, float rotX, float rotY) : m_position(position), m_rotX(rotX), m_rotY(rotY) { m_velocity = Vector3f(0, 0, 0); + m_dbljump = 0; + m_airborne = true; } -void Player::TurnLeftRight(float value) { - m_rotY += value; +void Player::TurnLeftRight(float value) { + m_rotY += value; if (m_rotY > 360) m_rotY = 0; else if (m_rotY < -360) m_rotY = 0; } -void Player::TurnTopBottom(float value) { +void Player::TurnTopBottom(float value) { m_rotX += value; if (m_rotX > 45) m_rotX = 45; else if (m_rotX < -45) m_rotX = -45; } -void Player::Move(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime) { - static float accWS = 0; - static float accAD = 0; - static float accjmp = 0; + +Vector3f Player::GetInput(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime) { static float yrotrad = 0; static float xrotrad = 0; - static bool jumped = true; - static int dbljump = 0; // Peut sauter ou dasher tant que la variable est en dessous de 2. static float dashtimeout = 0; - static float bobbingtime = 0; + + Vector3f delta = Vector3f(0, 0, 0); m_direction = Vector3f(cos(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f), - -sin(m_rotX / 57.2957795056f), + -sin(m_rotX / 57.2957795056f), sin(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f)); - if (bobbingtime <= 360.f) bobbingtime += elapsedTime * m_topspeed / 2; else bobbingtime = 0; + if (m_airborne && !jump) m_airborne = false; // Anti-rebondissement du saut, pour pouvoir rebondir. - if (dashtimeout > 0.f) { + if ((jump || dash) && !m_airborne) { + delta.y += jump ? m_jumpforce : 0.01f; + m_airborne = true; + m_dbljump++; + } + + if (dashtimeout > 0.f) { // Gestion du timeout de dash pour ne pas pouvoir spammer le dash. dash = false; dashtimeout -= elapsedTime; } else dashtimeout = 0; - - if (jumped && !jump) jumped = false; // Anti-rebondissement du saut, pour pouvoir rebondir. - if (dash) dashtimeout = 2; - if (dbljump >= 2) jump = false; - - if ((jump || dash) && !jumped ) { - accjmp += jump? m_jumpforce: 0.1f; - jumped = true; - dbljump++; - } - else if (m_position.y > -0.2f && accjmp != 0) { - if (accjmp > 0.f) { - if (jump) { - accjmp *= 0.95f - accjmp * elapsedTime; - accjmp -= elapsedTime * 1.1; - } - else { - accjmp *= 0.75f - accjmp * elapsedTime; - accjmp -= elapsedTime * 1.1; - } - } - else { - if (jump) accjmp -= elapsedTime * 0.7; - else accjmp -= elapsedTime * 0.9; - } - } - else accjmp = 0; - - if (m_position.y < 0.f) { // Suivi de mouvement pour l'atterrissage. - m_position.y += elapsedTime * 5.f; - if (m_position.y > 0.f) { - dbljump = 0; - m_position.y = 0; - } - } - - if ((dbljump < 1 && ( left || right || front || back)) || - (dash && !(left || right || front || back)) ) { + if ((m_dbljump < 1 && (left || right || front || back)) || + (dash && !(left || right || front || back))) { yrotrad = (m_rotY / 57.2957795056f); // 180/Pi = 57.295... xrotrad = (m_rotX / 57.2957795056f); - if (dash) accWS = m_topspeed; // Pour avoir un boost de vitesse vers l'avant si le dash est appuyé seul. + if (dash) { + delta.x += float(sin(yrotrad)) * elapsedTime; + delta.z += float(-cos(yrotrad)) * elapsedTime; + } } - // Ajoute l'accélération de saut et le view bobbing. - m_velocity.y = accjmp + (sin(bobbingtime) - 0.5f) * ((abs(accWS) + abs(accAD)) / 2.f) / (10.f * m_topspeed); + if (!m_airborne) { + if (front) { + delta.x += float(sin(yrotrad)) * elapsedTime * 10.f; + delta.z += float(-cos(yrotrad)) * elapsedTime * 10.f; + } + else if (back) { + delta.x -= float(-sin(yrotrad)) * elapsedTime * -10.f; + delta.z -= float(cos(yrotrad)) * elapsedTime * -10.f; + } + + if (left) { + delta.x += float(-cos(yrotrad)) * elapsedTime * 10.f; + delta.z += float(-sin(yrotrad)) * elapsedTime * 10.f; + } + else if (right) { + delta.x -= float(cos(yrotrad)) * elapsedTime * -10.f; + delta.z -= float(sin(yrotrad)) * elapsedTime * -10.f; + } + } + + return delta; +} + +// +//Vector3f Player::GetInput(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime) { +// static float accWS = 0; +// static float accAD = 0; +// static float yrotrad = 0; +// static float xrotrad = 0; +// static float dashtimeout = 0; +// +// Vector3f movepos = m_velocity; +// +// m_direction = Vector3f(cos(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f), +// -sin(m_rotX / 57.2957795056f), +// sin(m_rotY / 57.2957795056f) * cos(m_rotX / 57.2957795056f)); +// +// if (dashtimeout > 0.f) { // Gestion du timeout de dash pour ne pas pouvoir spammer le dash. +// dash = false; +// dashtimeout -= elapsedTime; +// } +// else dashtimeout = 0; +// if (dash) dashtimeout = 2; +// +// if (m_airborne && !jump) m_airborne = false; // Anti-rebondissement du saut, pour pouvoir rebondir. +// +// if (m_dbljump >= 2) jump = false; +// +// if ((jump || dash) && !m_airborne ) { +// m_velocity.y += jump? m_jumpforce: 0.1f; +// movepos.y += m_velocity.y; +// m_airborne = true; +// m_dbljump++; +// } +// +// if ((m_dbljump < 1 && ( left || right || front || back)) || +// (dash && !(left || right || front || back)) ) { +// yrotrad = (m_rotY / 57.2957795056f); // 180/Pi = 57.295... +// xrotrad = (m_rotX / 57.2957795056f); +// if (dash) accWS = m_topspeed; // Pour avoir un boost de vitesse vers l'avant si le dash est appuyé seul. +// } +// +// if (front) { +// if (m_dbljump == 0) +// if (accWS < m_topspeed) accWS += elapsedTime * 30; else accWS = m_topspeed; +// if (dash) accWS *= accWS > 0.f ? 3.f : -1.f; +// m_velocity.x = float(sin(yrotrad)) * elapsedTime * accWS; +// movepos.x += m_velocity.x; +// m_velocity.z = float(-cos(yrotrad)) * elapsedTime * accWS; +// movepos.z += m_velocity.z; +// } +// else if (back) { +// if (m_dbljump == 0) +// if (accWS > -m_topspeed) accWS -= elapsedTime * 30; else accWS = -m_topspeed; +// if (dash) accWS *= accWS < 0.f? 3.f: -1.f; +// m_velocity.x = float(-sin(yrotrad)) * elapsedTime * -accWS; +// movepos.x += m_velocity.x; +// m_velocity.z = float(cos(yrotrad)) * elapsedTime * -accWS; +// movepos.z += m_velocity.z; +// } +// else if (accWS != 0) { +// accWS = accWS > 0 ? accWS - elapsedTime * (m_position.y > 0.1f ? 10 : 120) +// : accWS + elapsedTime * (m_position.y > 0.1f ? 10 : 120); +// +// m_velocity.x = float(sin(yrotrad)) * elapsedTime * accWS; +// movepos.x += m_velocity.x; +// m_velocity.z = float(-cos(yrotrad)) * elapsedTime * accWS; +// movepos.z += m_velocity.z; +// if (accWS < 1 && accWS > -1) accWS = 0; +// } +// +// if (left) { +// if (m_dbljump == 0) +// if (accAD < m_topspeed) accAD += elapsedTime * 30; else accAD = m_topspeed; +// if (dash) accAD *= accAD > 0.f? 3.f: -1.f; +// m_velocity.x = float(-cos(yrotrad)) * elapsedTime * accAD; +// movepos.x += m_velocity.x; +// m_velocity.z = float(-sin(yrotrad)) * elapsedTime * accAD; +// movepos.z += m_velocity.z; +// } +// else if (right) { +// if (m_dbljump == 0) +// if (accAD > -m_topspeed) accAD -= elapsedTime * 30; else accAD = -m_topspeed; +// if (dash) accAD *= accAD < 0.f ? 3.f : -1.f; +// m_velocity.x = float(cos(yrotrad)) * elapsedTime * -accAD; +// movepos.x += m_velocity.x; +// m_velocity.z = float(sin(yrotrad)) * elapsedTime * -accAD; +// movepos.z += m_velocity.z; +// } +// else if (accAD != 0) { +// accAD = accAD > 0 ? accAD - elapsedTime * (m_position.y > 0.1f ? 10 : 120) +// : accAD + elapsedTime * (m_position.y > 0.1f ? 10 : 120); +// +// m_velocity.x = float(-cos(yrotrad)) * elapsedTime * accAD; +// movepos.x += m_velocity.x; +// m_velocity.z = float(-sin(yrotrad)) * elapsedTime * accAD; +// movepos.z += m_velocity.z; +// if (accAD < 1.f && accAD > -1.f) accAD = 0; +// } +// +// // Gestion de si le personnage va en diagonale, qu'il n'aille pas plus vite que s'il allait en ligne droite. +// if (abs(accAD) + abs(accWS) > sqrtf(exp2f(m_topspeed) * 2)) { +// accWS *= 0.8f; +// accAD *= 0.8f; +// } +// +// return movepos; +//} + +void Player::ApplyPhysics(Vector3f input, World world, float elapsedTime) { + /* Gestion de collisions */ + + BlockType bt1, bt2, bt3; + + bt1 = world.BlockAt(m_position.x, m_position.y + input.y, m_position.z); + bt2 = world.BlockAt(m_position.x, m_position.y + input.y - 0.9f, m_position.z); + bt3 = world.BlockAt(m_position.x, m_position.y + input.y - 1.7f, m_position.z); + if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + m_dbljump = 0; + if (input.y < 0.f) { + input.y = 0; + } + m_velocity.y = input.y; + if (!m_airborne) m_position.y = (int)m_position.y + .7f; + m_airborne = false; + } + else { + if (abs(m_velocity.y) < 1.1f) m_velocity.y += input.y - 1.1f * elapsedTime; + m_airborne = true; + } + + bt1 = world.BlockAt(m_position.x + input.x, m_position.y, m_position.z); + bt2 = world.BlockAt(m_position.x + input.x, m_position.y - 0.9f, m_position.z); + bt3 = world.BlockAt(m_position.x + input.x, m_position.y - 1.7f, m_position.z); + if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + input.x = 0; + } + + bt1 = world.BlockAt(m_position.x, m_position.y, m_position.z + input.z); + bt2 = world.BlockAt(m_position.x, m_position.y - 0.9f, m_position.z + input.z); + bt3 = world.BlockAt(m_position.x, m_position.y - 1.7f, m_position.z + input.z); + if (bt1 != BTYPE_AIR || bt2 != BTYPE_AIR || bt3 != BTYPE_AIR) { + input.z = 0; + } + + /* Fin gestion de collisions */ + + m_position += input; + m_POV = input; m_position.y += m_velocity.y; - if (front) { - if (dbljump == 0) - if (accWS < m_topspeed) accWS += elapsedTime * 30; else accWS = m_topspeed; - if (dash) accWS *= accWS > 0.f ? 3.f : -1.f; - m_velocity.x = float(sin(yrotrad)) * elapsedTime * accWS; - m_position.x += m_velocity.x; - m_velocity.z = float(-cos(yrotrad)) * elapsedTime * accWS; - m_position.z += m_velocity.z; - - } - else if (back) { - if (dbljump == 0) - if (accWS > -m_topspeed) accWS -= elapsedTime * 30; else accWS = -m_topspeed; - if (dash) accWS *= accWS < 0.f? 3.f: -1.f; - m_velocity.x = float(-sin(yrotrad)) * elapsedTime * -accWS; - m_position.x += m_velocity.x; - m_velocity.z = float(cos(yrotrad)) * elapsedTime * -accWS; - m_position.z += m_velocity.z; - } - else if (accWS != 0) { - accWS = accWS > 0 ? accWS - elapsedTime * (m_position.y > 0.1f ? 10 : 120) - : accWS + elapsedTime * (m_position.y > 0.1f ? 10 : 120); - - m_velocity.x = float(sin(yrotrad)) * elapsedTime * accWS; - m_position.x += m_velocity.x; - m_velocity.z = float(-cos(yrotrad)) * elapsedTime * accWS; - m_position.z += m_velocity.z; - if (accWS < 1 && accWS > -1) accWS = 0; - } - - if (left) { - if (dbljump == 0) - if (accAD < m_topspeed) accAD += elapsedTime * 30; else accAD = m_topspeed; - if (dash) accAD *= accAD > 0.f? 3.f: -1.f; - m_velocity.x = float(-cos(yrotrad)) * elapsedTime * accAD; - m_position.x += m_velocity.x; - m_velocity.z = float(-sin(yrotrad)) * elapsedTime * accAD; - m_position.z += m_velocity.z; - } - else if (right) { - if (dbljump == 0) - if (accAD > -m_topspeed) accAD -= elapsedTime * 30; else accAD = -m_topspeed; - if (dash) accAD *= accAD < 0.f ? 3.f : -1.f; - m_velocity.x = float(cos(yrotrad)) * elapsedTime * -accAD; - m_position.x += m_velocity.x; - m_velocity.z = float(sin(yrotrad)) * elapsedTime * -accAD; - m_position.z += m_velocity.z; - } - else if (accAD != 0) { - accAD = accAD > 0 ? accAD - elapsedTime * (m_position.y > 0.1f ? 10 : 120) - : accAD + elapsedTime * (m_position.y > 0.1f ? 10 : 120); - - m_velocity.x = float(-cos(yrotrad)) * elapsedTime * accAD; - m_position.x += m_velocity.x; - m_velocity.z = float(-sin(yrotrad)) * elapsedTime * accAD; - m_position.z += m_velocity.z; - if (accAD < 1.f && accAD > -1.f) accAD = 0; - } - - // Gestion de si le personnage va en diagonale, qu'il n'aille pas plus vite que s'il allait en ligne droite. - if (abs(accAD) + abs(accWS) > sqrtf(exp2f(m_topspeed) * 2)) { - accWS *= 0.8f; - accAD *= 0.8f; - } - - // Threshold de vélocité. - if (abs(m_velocity.x) < 0.02f) m_velocity.x = 0; - if (abs(m_velocity.y) < 0.02f) m_velocity.y = 0; - if (abs(m_velocity.z) < 0.02f) m_velocity.z = 0; + //static float bobbingtime = 0; // Gestion de la caméra + //if (bobbingtime <= 360.f) bobbingtime += elapsedTime * m_topspeed / 2; else bobbingtime = 0; + //m_POV.x = m_position.x; + //m_POV.z = m_position.z; + //m_POV.y = m_position.y - 1.7f + m_airborne ? 0 : ((sin(bobbingtime) - 0.5f) * (abs(m_velocity.x * 40) + abs(m_velocity.z * 40)) / (10.f * m_topspeed)); } void Player::ApplyTransformation(Transformation& transformation, bool rel) const { @@ -168,4 +243,9 @@ Vector3f Player::GetPosition() const { return m_position; } Vector3f Player::GetVelocity() const { return m_velocity; } +Vector3f Player::GetPOV() const +{ + return m_POV; +} + Vector3f Player::GetDirection() const { return m_direction; } diff --git a/SQCSim2021/player.h b/SQCSim2021/player.h index e482e5d..0ec5ccf 100644 --- a/SQCSim2021/player.h +++ b/SQCSim2021/player.h @@ -2,6 +2,7 @@ #define _PLAYER_H__ #include "vector3.h" #include "transformation.h" +#include "world.h" #include class Player { @@ -9,21 +10,28 @@ public: Player(const Vector3f& position, float rotX = 0, float rotY = 0); void TurnLeftRight(float value); void TurnTopBottom(float value); - void Move(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime); + Vector3f GetInput(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime); + void ApplyPhysics(Vector3f input, World world, float elapsedTime); void ApplyTransformation(Transformation& transformation, bool rel = true) const; Vector3f GetPosition() const; Vector3f GetDirection() const; Vector3f GetVelocity() const; + Vector3f GetPOV() const; private: Vector3f m_position; + Vector3f m_POV; Vector3f m_velocity; Vector3f m_direction; + float m_rotX = 0; float m_rotY = 0; - float m_topspeed = 40; - float m_jumpforce = .9f; + float m_topspeed = 20; + float m_jumpforce = 0.3f; + + bool m_airborne; + int m_dbljump; // Peut sauter ou dasher tant que la variable est en dessous de 2. }; #endif //_PLAYER_H__ diff --git a/SQCSim2021/world.cpp b/SQCSim2021/world.cpp new file mode 100644 index 0000000..ef86ad3 --- /dev/null +++ b/SQCSim2021/world.cpp @@ -0,0 +1,7 @@ +#include "world.h" + +World::World(){} + +World::~World(){} + +Array2d& World::GetChunks() { return m_chunks; } diff --git a/SQCSim2021/world.h b/SQCSim2021/world.h new file mode 100644 index 0000000..19be21e --- /dev/null +++ b/SQCSim2021/world.h @@ -0,0 +1,57 @@ +#ifndef WORLD_H__ +#define WORLD_H__ +#include "define.h" +#include "chunk.h" +#include "array2d.h" +#include "vector3.h" +#include "transformation.h" + +class World { + public: + World(); + ~World(); + + Array2d& GetChunks(); + + template + Chunk* World::ChunkAt(T x, T y, T z) const { + int cx = (int)x / CHUNK_SIZE_X; + int cz = (int)z / CHUNK_SIZE_Z; + + if (cx >= VIEW_DISTANCE || // L'array en ce moment est de VIEW_DISTANCE par VIEW_DISTANCE. + cz >= VIEW_DISTANCE || + cx < 0 || cz < 0) + return 0; + + return m_chunks.Get(cx, cz); + } + + template + Chunk* World::ChunkAt(const Vector3& pos) const { return ChunkAt(pos.x, pos.y, pos.z); } + + template + BlockType World::BlockAt(T x, T y, T z, BlockType defaultBlockType = BTYPE_AIR) const { + Chunk* c = ChunkAt(x, y, z); + + if (!c) + return defaultBlockType; + + int bx = (int)x % CHUNK_SIZE_X; + int by = (int)y % CHUNK_SIZE_Y; + int bz = (int)z % CHUNK_SIZE_Z; + + return c->GetBlock(bx, by, bz); + } + + template + BlockType World::BlockAt(Vector3& pos, BlockType defaultBlockType = BTYPE_AIR) const { + return BlockAt(pos.x, pos.y, pos.z); + } + +private: + Array2d m_chunks = Array2d(VIEW_DISTANCE, VIEW_DISTANCE); + + int m_center[2] = {0, 0}; +}; +#endif +