diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 1838b0f..e8b9e47 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -39,10 +39,8 @@ enum GameState { MAIN_MENU, SPLASH, - OPTIONS, - SETTINGS, + OPTIONS, QUIT, - NEWG, PLAY, PAUSE }; diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index e040e15..d7b675a 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -249,247 +249,7 @@ void Engine::LoadResource() { void Engine::UnloadResource() {} -void Engine::Render(float elapsedTime) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (m_gamestate == GameState::SPLASH) { - if (m_splashTime > 0.0f) { - DisplaySplashScreen(); - } - else { - m_gamestate = GameState::MAIN_MENU; - } - - m_splashTime -= elapsedTime; - return; - } - - if (m_gamestate == GameState::MAIN_MENU) { - DisplayMainMenu(); - return; - } - - if (m_gamestate == GameState::OPTIONS) { - DisplayOptionsMenu(); - return; - } - - if (m_gamestate == GameState::PAUSE) { - DisplayPauseMenu(); - return; - } - - if (m_gamestate == GameState::PLAY) { - HideCursor(); - CenterMouse(); //D�placement de centermouse dans l'action de jouer - - //static float gameTime = elapsedTime; - static irrklang::ISound* step; // Pour les sons de pas. - static float pollTime = 0; - static float bulletTime = 0; - static float gameTime = 0; - static BlockType bloc = 1; - - if (elapsedTime > 0.1f) return; - - //gameTime += elapsedTime; - pollTime += elapsedTime; - - Transformation all; - Transformation skybox; - Transformation remotePlayer; - - Vector3f vstep; - - // Transformations initiales - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (bulletTime > 0.f) bulletTime -= elapsedTime; - if (bulletTime < 0.f) bulletTime = 0.f; - - static bool leftright = false; - if (pollTime >= .005f) { - Player::Sound snd = m_player.ApplyPhysics(m_player.GetInput(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, (bloc == BTYPE_LAST && bulletTime <= 0.f && m_mouseL), elapsedTime), &m_world, elapsedTime); - switch (snd) { - case Player::Sound::STEP: - if (leftright) - vstep = Vector3f(m_player.GetPosition().x + m_player.GetDirection().z, m_player.GetPosition().y - 1.7f, m_player.GetPosition().z + m_player.GetDirection().x); - else vstep = Vector3f(m_player.GetPosition().x - m_player.GetDirection().z, m_player.GetPosition().y - 1.7f, m_player.GetPosition().z - m_player.GetDirection().x); - m_audio.Create3DAudioObj(step, AUDIO_PATH "step.wav", vstep, m_player.GetVelocity(), false, .8f); - leftright = !leftright; - break; - case Player::Sound::FALL: - m_audio.Create3DAudioObj(step, AUDIO_PATH "hit.wav", m_player.GetPosition(), m_player.GetVelocity(), false, 1.f); - break; - default: break; - } - m_audio.Update3DAudio(m_player.GetPOV(), m_player.GetDirection(), m_player.GetVelocity()); // Ajustement du positionnement 3D avec les coordonnees du joueur et - // son vecteur de velocite (pour l'effet Doppler) - pollTime = 0; - } - - m_player.ApplyTransformation(all); - - m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation - // (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!). - - m_player.ApplyTransformation(remotePlayer, true, false); - - if (m_key1) bloc++; - else if (m_key2) bloc--; - - if (m_mouseWU) bloc++; - else if (m_mouseWD) bloc--; - if (bloc == BTYPE_LAST + 1) bloc = BTYPE_AIR + 1; - else if (bloc == BTYPE_AIR) bloc = BTYPE_LAST; // La selection de BTYPE_LAST �quipe l'arme. - m_mouseWU = m_mouseWD = m_key1 = m_key2 = false; - - if (m_mouseL) { - if (bloc != BTYPE_LAST) - m_world.ChangeBlockAtCursor(bloc, m_player.GetPosition(), m_player.GetDirection(), m_block); - else if (bulletTime <= 0.f) { - for (int x = 0; x < MAX_BULLETS; ++x) // Ajouter une balle dans l'array (aussi connu sous le nom de "faire pow pow"). - if (!m_bullets[x]) { - m_bullets[x] = new Bullet(m_player.GetPOV() + m_player.GetDirection(), m_player.GetDirection()); - break; - } - else if (x == MAX_BULLETS - 1) { // S'il y a pas d'espace dans l'array, prendre la place de la première balle de l'array. - m_bullets[0]->~Bullet(); - m_bullets[0] = new Bullet(m_player.GetPOV() + m_player.GetDirection(), m_player.GetDirection()); - } - bulletTime = BULLET_TIME; - m_audio.Create3DAudioObj(m_powpow, AUDIO_PATH "pow.wav", m_player.GetPOV(), m_player.GetDirection() * 10, false, .5f); - if (m_flash) { // Coupe le rendering et affiche un frame blanc, pour simuler un flash. - glClearColor(.8f, .8f, .8f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glClearColor(0.f, 0.f, 0.f, 1.f); - return; - } - } - } - else if (m_mouseR) - m_world.ChangeBlockAtCursor(BTYPE_AIR, m_player.GetPosition(), m_player.GetDirection(), m_block); - - for (int x = 0; x < MAX_BULLETS; ++x) { // Array de bullets en jeu. - if (m_bullets[x]) { - for (int b = 0; b < BULLET_UPDATES_PER_FRAME; ++b) { - if (m_bullets[x]->Update(&m_world, elapsedTime, BULLET_UPDATES_PER_FRAME, m_players)) { - m_bullets[x]->~Bullet(); - if (m_whoosh[x]) - m_whoosh[x]->drop(); - m_bullets[x] = nullptr; - m_whoosh[x] = nullptr; - break; - } - else if (!m_whoosh[x]) { - m_whoosh[x] = m_audio.Create3DAudioObj(m_whoosh[x], AUDIO_PATH "noise.wav", m_bullets[x]->getPos(), m_bullets[x]->getVel(), true, (m_bullets[x]->getPos() - m_player.GetPosition()).Length()); - } - else { - Vector3f pos = m_bullets[x]->getPos(), vel = m_bullets[x]->getVel(); - m_audio.Render3DAudioObj(m_whoosh[x], pos, vel, 5 - (m_bullets[x]->getPos() - m_player.GetPosition()).Length()); - } - } - } - } - - gameTime += elapsedTime * 10; - - Vector3f dance = Vector3f(sin(gameTime), 0, cos(-gameTime)); - dance.Normalize(); - m_remotePlayer.ApplyPhysics(dance, &m_world, elapsedTime); - m_world.Update(m_bullets, m_player.GetPosition(), m_blockinfo); - m_renderer.UpdateMesh(&m_world, m_player.GetPosition(), m_blockinfo); - m_remotePlayer.Render(m_animeAtlas, m_shader01, all, elapsedTime); - m_booster.RenderBillboard({ 195,16,195 }, m_textureAtlas, m_shader01, all); - - if (m_isSkybox) m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); - - //glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - //m_remotePlayer.Render(m_textureAtlas, m_shader01, all, elapsedTime); - - m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); - - if (m_isSkybox) m_skybox.Render(skybox); - - DrawHud(elapsedTime, bloc); - DisplayPovGun(); - ProcessNotificationQueue(); - if (m_damage) { - InstantDamage(); - } - static bool fell = false; - if (m_player.GetPosition().y < 1.7f && !fell) { - m_audio.Create3DAudioObj(m_scream, AUDIO_PATH "scream.wav", m_player.GetPOV(), m_player.GetVelocity(), false, 1.f); - fell = true; - } - else if (m_player.GetPosition().y < -20.f) { - m_player = Player(Vector3f(.5f, CHUNK_SIZE_Y + 1.8f, .5f)); // Respawn si le bonho- joueur tombe en bas du monde. - fell = false; - } - - if (m_networkgame) { // Pour se gerer le paquet. - using namespace std::chrono; - using namespace netprot; - Timestamp tstamp = duration_cast(high_resolution_clock::now() - m_startTime).count(); - Input input; - Sync sync; - uint64_t id = m_conn.getId(); - static std::vector lsPck; - - if (false) { // TODO: Faire un checkup pour chaque ~1000ms. - sync.sid = id; - sync.timestamp = tstamp; - sync.position = m_player.GetPosition(); - sync.hp = m_player.GetHP(); - // TODO: Garrocher ca quelque-part. - } - - input.sid = id; - input.direction = m_player.GetDirection(); - input.timestamp = tstamp; - input.keys.forward = m_keyW; - input.keys.backward = m_keyS; - input.keys.left = m_keyA; - input.keys.right = m_keyD; - input.keys.jump = m_keySpace; - input.keys.block = m_mouseR; - input.keys.shoot = m_mouseL; - - sendPackTo(m_conn.m_sock_udp, &input, &m_bufout, &m_conn.m_srvsockaddr); - - lsPck = recvPacks(m_conn.m_sock_udp, &m_buf); - char* prevptr = nullptr; - for (auto& pck : lsPck) { // We could make a few threads out of this. - Sync sync; - Output out; - if (!prevptr) - prevptr = m_buf.ptr; - uint32_t bsize = m_buf.len - (pck - prevptr); - prevptr = pck; - switch (getType(pck, 1)) { - using enum PACKET_TYPE; - case SYNC: - if (Deserialize(&sync, pck, &bsize)) { - if (sync.sid != m_conn.getId()) - break; - // TODO: Vérifier si les positions concordent au sync local. - } - break; - case OUTPUT: - if (Deserialize(&out, pck, &bsize)) { - RemotePlayer* r = (RemotePlayer*)m_players[out.id]; - r->Feed(out); - } - break; - default: - break; - } - } - lsPck.clear(); - } - } -} void Engine::InstantDamage() { m_player.InflictDamage(0.10f); @@ -1370,6 +1130,248 @@ void Engine::DisplayGraphicsMenu(float centerX, float centerY) { glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } +void Engine::Render(float elapsedTime) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + if (m_gamestate == GameState::SPLASH) { + if (m_splashTime > 0.0f) { + DisplaySplashScreen(); + } + else { + m_gamestate = GameState::MAIN_MENU; + } + + m_splashTime -= elapsedTime; + return; + } + + if (m_gamestate == GameState::MAIN_MENU) { + DisplayMainMenu(); + return; + } + + if (m_gamestate == GameState::OPTIONS) { + DisplayOptionsMenu(); + return; + } + + if (m_gamestate == GameState::PAUSE) { + DisplayPauseMenu(); + return; + } + + if (m_gamestate == GameState::PLAY) { + HideCursor(); + CenterMouse(); //D�placement de centermouse dans l'action de jouer + + //static float gameTime = elapsedTime; + static irrklang::ISound* step; // Pour les sons de pas. + static float pollTime = 0; + static float bulletTime = 0; + static float gameTime = 0; + static BlockType bloc = 1; + + if (elapsedTime > 0.1f) return; + + //gameTime += elapsedTime; + pollTime += elapsedTime; + + Transformation all; + Transformation skybox; + Transformation remotePlayer; + + Vector3f vstep; + + // Transformations initiales + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (bulletTime > 0.f) bulletTime -= elapsedTime; + if (bulletTime < 0.f) bulletTime = 0.f; + + static bool leftright = false; + if (pollTime >= .005f) { + Player::Sound snd = m_player.ApplyPhysics(m_player.GetInput(m_keyW, m_keyS, m_keyA, m_keyD, m_keySpace, (bloc == BTYPE_LAST && bulletTime <= 0.f && m_mouseL), elapsedTime), &m_world, elapsedTime); + switch (snd) { + case Player::Sound::STEP: + if (leftright) + vstep = Vector3f(m_player.GetPosition().x + m_player.GetDirection().z, m_player.GetPosition().y - 1.7f, m_player.GetPosition().z + m_player.GetDirection().x); + else vstep = Vector3f(m_player.GetPosition().x - m_player.GetDirection().z, m_player.GetPosition().y - 1.7f, m_player.GetPosition().z - m_player.GetDirection().x); + m_audio.Create3DAudioObj(step, AUDIO_PATH "step.wav", vstep, m_player.GetVelocity(), false, .8f); + leftright = !leftright; + break; + case Player::Sound::FALL: + m_audio.Create3DAudioObj(step, AUDIO_PATH "hit.wav", m_player.GetPosition(), m_player.GetVelocity(), false, 1.f); + break; + default: break; + } + m_audio.Update3DAudio(m_player.GetPOV(), m_player.GetDirection(), m_player.GetVelocity()); // Ajustement du positionnement 3D avec les coordonnees du joueur et + // son vecteur de velocite (pour l'effet Doppler) + pollTime = 0; + } + + m_player.ApplyTransformation(all); + + m_player.ApplyTransformation(skybox, false); // Version d'ApplyTransformation qui ne tient compte que de la rotation + // (donc l'objet ne bouge pas relativement au joueur, ce qui est pratique pour une skybox!). + + m_player.ApplyTransformation(remotePlayer, true, false); + + if (m_key1) bloc++; + else if (m_key2) bloc--; + + if (m_mouseWU) bloc++; + else if (m_mouseWD) bloc--; + if (bloc == BTYPE_LAST + 1) bloc = BTYPE_AIR + 1; + else if (bloc == BTYPE_AIR) bloc = BTYPE_LAST; // La selection de BTYPE_LAST �quipe l'arme. + m_mouseWU = m_mouseWD = m_key1 = m_key2 = false; + + if (m_mouseL) { + if (bloc != BTYPE_LAST) + m_world.ChangeBlockAtCursor(bloc, m_player.GetPosition(), m_player.GetDirection(), m_block); + else if (bulletTime <= 0.f) { + for (int x = 0; x < MAX_BULLETS; ++x) // Ajouter une balle dans l'array (aussi connu sous le nom de "faire pow pow"). + if (!m_bullets[x]) { + m_bullets[x] = new Bullet(m_player.GetPOV() + m_player.GetDirection(), m_player.GetDirection()); + break; + } + else if (x == MAX_BULLETS - 1) { // S'il y a pas d'espace dans l'array, prendre la place de la première balle de l'array. + m_bullets[0]->~Bullet(); + m_bullets[0] = new Bullet(m_player.GetPOV() + m_player.GetDirection(), m_player.GetDirection()); + } + bulletTime = BULLET_TIME; + m_audio.Create3DAudioObj(m_powpow, AUDIO_PATH "pow.wav", m_player.GetPOV(), m_player.GetDirection() * 10, false, .5f); + if (m_flash) { // Coupe le rendering et affiche un frame blanc, pour simuler un flash. + glClearColor(.8f, .8f, .8f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glClearColor(0.f, 0.f, 0.f, 1.f); + return; + } + } + } + else if (m_mouseR) + m_world.ChangeBlockAtCursor(BTYPE_AIR, m_player.GetPosition(), m_player.GetDirection(), m_block); + + for (int x = 0; x < MAX_BULLETS; ++x) { // Array de bullets en jeu. + if (m_bullets[x]) { + for (int b = 0; b < BULLET_UPDATES_PER_FRAME; ++b) { + if (m_bullets[x]->Update(&m_world, elapsedTime, BULLET_UPDATES_PER_FRAME, m_players)) { + m_bullets[x]->~Bullet(); + if (m_whoosh[x]) + m_whoosh[x]->drop(); + m_bullets[x] = nullptr; + m_whoosh[x] = nullptr; + break; + } + else if (!m_whoosh[x]) { + m_whoosh[x] = m_audio.Create3DAudioObj(m_whoosh[x], AUDIO_PATH "noise.wav", m_bullets[x]->getPos(), m_bullets[x]->getVel(), true, (m_bullets[x]->getPos() - m_player.GetPosition()).Length()); + } + else { + Vector3f pos = m_bullets[x]->getPos(), vel = m_bullets[x]->getVel(); + m_audio.Render3DAudioObj(m_whoosh[x], pos, vel, 5 - (m_bullets[x]->getPos() - m_player.GetPosition()).Length()); + } + } + } + } + + gameTime += elapsedTime * 10; + + Vector3f dance = Vector3f(sin(gameTime), 0, cos(-gameTime)); + dance.Normalize(); + m_remotePlayer.ApplyPhysics(dance, &m_world, elapsedTime); + m_world.Update(m_bullets, m_player.GetPosition(), m_blockinfo); + m_renderer.UpdateMesh(&m_world, m_player.GetPosition(), m_blockinfo); + m_remotePlayer.Render(m_animeAtlas, m_shader01, all, elapsedTime); + m_booster.RenderBillboard({ 195,16,195 }, m_textureAtlas, m_shader01, all); + + if (m_isSkybox) m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); + + //glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + //m_remotePlayer.Render(m_textureAtlas, m_shader01, all, elapsedTime); + + m_renderer.RenderWorld(&m_world, m_renderCount, m_player.GetPosition(), m_player.GetDirection(), all, m_shader01, m_textureAtlas); + + if (m_isSkybox) m_skybox.Render(skybox); + + DrawHud(elapsedTime, bloc); + DisplayPovGun(); + ProcessNotificationQueue(); + if (m_damage) { + InstantDamage(); + } + static bool fell = false; + if (m_player.GetPosition().y < 1.7f && !fell) { + m_audio.Create3DAudioObj(m_scream, AUDIO_PATH "scream.wav", m_player.GetPOV(), m_player.GetVelocity(), false, 1.f); + fell = true; + } + else if (m_player.GetPosition().y < -20.f) { + m_player = Player(Vector3f(.5f, CHUNK_SIZE_Y + 1.8f, .5f)); // Respawn si le bonho- joueur tombe en bas du monde. + fell = false; + } + + if (m_networkgame) { // Pour se gerer le paquet. + using namespace std::chrono; + using namespace netprot; + Timestamp tstamp = duration_cast(high_resolution_clock::now() - m_startTime).count(); + Input input; + Sync sync; + uint64_t id = m_conn.getId(); + static std::vector lsPck; + + if (false) { // TODO: Faire un checkup pour chaque ~1000ms. + sync.sid = id; + sync.timestamp = tstamp; + sync.position = m_player.GetPosition(); + sync.hp = m_player.GetHP(); + // TODO: Garrocher ca quelque-part. + } + + input.sid = id; + input.direction = m_player.GetDirection(); + input.timestamp = tstamp; + input.keys.forward = m_keyW; + input.keys.backward = m_keyS; + input.keys.left = m_keyA; + input.keys.right = m_keyD; + input.keys.jump = m_keySpace; + input.keys.block = m_mouseR; + input.keys.shoot = m_mouseL; + + sendPackTo(m_conn.m_sock_udp, &input, &m_bufout, &m_conn.m_srvsockaddr); + + lsPck = recvPacks(m_conn.m_sock_udp, &m_buf); + char* prevptr = nullptr; + for (auto& pck : lsPck) { // We could make a few threads out of this. + Sync sync; + Output out; + if (!prevptr) + prevptr = m_buf.ptr; + uint32_t bsize = m_buf.len - (pck - prevptr); + prevptr = pck; + switch (getType(pck, 1)) { + using enum PACKET_TYPE; + case SYNC: + if (Deserialize(&sync, pck, &bsize)) { + if (sync.sid != m_conn.getId()) + break; + // TODO: Vérifier si les positions concordent au sync local. + } + break; + case OUTPUT: + if (Deserialize(&out, pck, &bsize)) { + RemotePlayer* r = (RemotePlayer*)m_players[out.id]; + r->Feed(out); + } + break; + default: + break; + } + } + lsPck.clear(); + } + } +} + void Engine::DisplayGameplayMenu(float centerX, float centerY) { float minBar = centerX - Width() * 0.15; float maxBar = centerX + Width() * 0.3;