diff --git a/SQCSim-common/SQCSim-common.vcxproj b/SQCSim-common/SQCSim-common.vcxproj index 991cd1d..5f319ac 100644 --- a/SQCSim-common/SQCSim-common.vcxproj +++ b/SQCSim-common/SQCSim-common.vcxproj @@ -131,6 +131,7 @@ + @@ -144,6 +145,7 @@ + diff --git a/SQCSim-common/SQCSim-common.vcxproj.filters b/SQCSim-common/SQCSim-common.vcxproj.filters index 26c6c05..45814cf 100644 --- a/SQCSim-common/SQCSim-common.vcxproj.filters +++ b/SQCSim-common/SQCSim-common.vcxproj.filters @@ -54,6 +54,9 @@ Fichiers d%27en-tête + + Fichiers d%27en-tête + @@ -80,5 +83,8 @@ Fichiers sources + + Fichiers sources + \ No newline at end of file diff --git a/SQCSim-common/boostinfo.cpp b/SQCSim-common/boostinfo.cpp new file mode 100644 index 0000000..9b54626 --- /dev/null +++ b/SQCSim-common/boostinfo.cpp @@ -0,0 +1,32 @@ +#include "boostinfo.h" +#include + +BoostInfo::BoostInfo(BoostType type, const std::string& name, float u, float v, float s, int dur) : m_type(type), m_name(name), m_u(u), m_v(v), m_s(s), m_durability(dur) +{ +} + +BoostInfo::~BoostInfo() +{ +} + +BoostType BoostInfo::GetType() const +{ + return m_type; +} + +void BoostInfo::GetTexture(float& u, float& v, float& s) +{ + u = m_u; + v = m_v; + s = m_s; +} + +void BoostInfo::Show() const +{ + std::cout << "Type: " << m_type << std::endl; + std::cout << "Nom: " << m_name << std::endl; + std::cout << "Durabilite: " << m_durability << std::endl; + std::cout << "Coordonnees Texture: " << m_u << ", " << m_v << ", " << m_s << std::endl; +} + + diff --git a/SQCSim-common/boostinfo.h b/SQCSim-common/boostinfo.h new file mode 100644 index 0000000..e76d1ed --- /dev/null +++ b/SQCSim-common/boostinfo.h @@ -0,0 +1,29 @@ +#ifndef BOOSTINFO_H__ +#define BOOSTINFO_H__ + +#include +#include "define.h" + +class BoostInfo +{ +public: + BoostInfo(BoostType type, const std::string& name, float u, float v, float s, int dur); + ~BoostInfo(); + + BoostType GetType() const; + + void GetTexture(float& u, float& v, float& s); + + void Show() const; + +private: + BoostType m_type; + float m_u; + float m_v; + float m_s; + std::string m_name; + int m_durability; + +}; + +#endif // BOOSTINFO_H__ diff --git a/SQCSim-common/define.h b/SQCSim-common/define.h index f65bc2b..337a9be 100644 --- a/SQCSim-common/define.h +++ b/SQCSim-common/define.h @@ -29,8 +29,15 @@ #define TEXTURE_SIZE 512 #define MAX_BULLETS 512 +#define TIME_SPEED_BOOST 10 //secondes +#define TIME_DAMAGE_BOOST 10 //secondes +#define TIME_INVINCIBLE_BOOST 4 //secondes +#define STRENGTH_SPEED_BOOST 10 //Pourcentage + typedef uint8_t BlockType; +typedef uint8_t BoostType; enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_LAST }; +enum BOOST_TYPE { BTYPE_SPEED, BTYPE_HEAL, BTYPE_DAMAGE, BTYPE_INVINCIBLE }; typedef uint64_t Timestamp; #ifdef _WIN32 diff --git a/SQCSim-common/player.cpp b/SQCSim-common/player.cpp index 9fe810c..66b6c0a 100644 --- a/SQCSim-common/player.cpp +++ b/SQCSim-common/player.cpp @@ -59,6 +59,11 @@ Vector3f Player::GetInput(bool front, bool back, bool left, bool right, bool jum delta.y += jump? .32f: shoot? .1f : 0.f; m_airborne = true; } + if (boostspeed) + { + delta.x += STRENGTH_SPEED_BOOST / 100 * delta.x; + delta.z += STRENGTH_SPEED_BOOST / 100 * delta.z; + } if (shoot) // Recoil! TurnTopBottom(-1); @@ -180,7 +185,7 @@ Player::Sound Player::ApplyPhysics(Vector3f input, World* world, float elapsedTi else isStep = false; m_POV = m_position.y; m_POV += m_airborne ? 0 : (sin(bobbingtime) - 0.5f) * (abs(m_velocity.x) + abs(m_velocity.z)) * .2f; - + RemoveBooster(elapsedTime); return snd; } @@ -190,6 +195,50 @@ void Player::ApplyTransformation(Transformation& transformation, bool rel) const if (rel) transformation.ApplyTranslation(-GetPOV()); } +void Player::GetBooster(Booster boosttype) +{ + if (boosttype == SPEED) + { + boostspeed = true; + timeboostspeed = 0; + } + if (boosttype == HEAL) + { + m_hp = 100; + } + if (boosttype == DAMAGE) + { + boostdamage = true; + timeboostdamage = 0; + } + if (boosttype == INVINCIBLE) + { + boostinvincible = true; + boostinvincible = 0; + } +} +void Player::RemoveBooster(float elapsedtime) +{ + if (boostspeed) + { + timeboostspeed += elapsedtime; + if (timeboostspeed >= TIME_SPEED_BOOST) + boostspeed = false; + } + if (boostdamage) + { + timeboostdamage += elapsedtime; + if (timeboostdamage >= TIME_DAMAGE_BOOST) + boostdamage = false; + } + if (boostinvincible) + { + timeboostinvincible += elapsedtime; + if (timeboostinvincible >= TIME_INVINCIBLE_BOOST) + boostinvincible = false; + } +} + Vector3f Player::GetPosition() const { return Vector3f(m_position.x + CHUNK_SIZE_X * WORLD_SIZE_X / 2, m_position.y, m_position.z + CHUNK_SIZE_Z * WORLD_SIZE_Y / 2); } Vector3f Player::GetVelocity() const { return m_velocity; } diff --git a/SQCSim-common/player.h b/SQCSim-common/player.h index e439fa2..1a98d6d 100644 --- a/SQCSim-common/player.h +++ b/SQCSim-common/player.h @@ -10,6 +10,7 @@ class World; class Player { public: enum Sound { NOSOUND, STEP, FALL }; + enum Booster { SPEED, HEAL, DAMAGE, INVINCIBLE }; Player(const Vector3f& position, float rotX = 0, float rotY = 0); void TurnLeftRight(float value); @@ -17,7 +18,8 @@ public: Vector3f GetInput(bool front, bool back, bool left, bool right, bool jump, bool dash, float elapsedTime); Sound ApplyPhysics(Vector3f input, World* world, float elapsedTime); void ApplyTransformation(Transformation& transformation, bool rel = true) const; - + void GetBooster(Booster boosttype); + void RemoveBooster(float elapsedtime); Vector3f GetPosition() const; Vector3f GetDirection() const; Vector3f GetVelocity() const; @@ -36,10 +38,16 @@ private: float m_rotX = 0; float m_rotY = 0; float m_POV; + float timeboostspeed; + float timeboostdamage; + float timeboostinvincible; float m_hp; bool m_airborne; + bool boostspeed; + bool boostdamage; + bool boostinvincible; }; #endif //_PLAYER_H__ diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 67c49c3..2abfe0c 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -35,5 +35,6 @@ #define AUDIO_PATH "./media/audio/" #define CHUNK_PATH "./media/chunks/" #define MENU_ITEM_PATH "./media/menu_items/" +#define BOOSTER_TEXTURE_PATH "./media/textures/Booster" #endif // DEFINE_H__ diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index a5939e6..bacea3b 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -5,8 +5,6 @@ #include #include - - // Define a structure to represent notifications struct Notification { std::string message; @@ -28,6 +26,56 @@ Engine::~Engine() { m_world.GetChunks().Get(x, y)->~Chunk(); } +void Engine::DrawSplachScreen() +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + + // Définir la matrice de projection en mode orthographique + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(-Width() / 2, Width() / 2, -Height() / 2, Height() / 2, -1, 1); + + // Définir la matrice de modèle-vue + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // L'image sera centrée autour de l'origine (0, 0, 0) + int imageWidth = Width(); // Remplacez par la largeur de votre image + int imageHeight = Height(); // Remplacez par la hauteur de votre image + + // Texture + SplachScreenTexture.Bind(); + + // Dessiner un quadrilatère centré + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2i(-imageWidth / 2, -imageHeight / 2); + glTexCoord2f(1, 0); + glVertex2i(imageWidth / 2, -imageHeight / 2); + glTexCoord2f(1, 1); + glVertex2i(imageWidth / 2, imageHeight / 2); + glTexCoord2f(0, 1); + glVertex2i(-imageWidth / 2, imageHeight / 2); + glEnd(); + + // Activer la transparence + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glEnable(GL_BLEND); + + // Restaurer les matrices précédentes + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + + + void Engine::DrawMenu() { static const int sTitle = 400; @@ -223,6 +271,8 @@ void Engine::DrawMenu() } void Engine::Init() { + + GLenum glewErr = glewInit(); if (glewErr != GLEW_OK) { std::cerr << " ERREUR GLEW : " << glewGetErrorString(glewErr) << std::endl; @@ -230,7 +280,7 @@ void Engine::Init() { } glDisable(GL_FRAMEBUFFER_SRGB); - glEnable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); glEnable(GL_POINT_SMOOTH); glEnable(GL_BLEND); @@ -294,10 +344,14 @@ void Engine::LoadResource() { LoadTexture(m_skybox.GetTexture(), TEXTURE_PATH "skybox.png", true); LoadTexture(m_textureCrosshair, TEXTURE_PATH "cross.bmp", true); LoadTexture(m_textureFont, TEXTURE_PATH "font.bmp", true); - LoadTexture(m_textureGun, TEXTURE_PATH "gun01.png", true); + LoadTexture(m_textureGun, TEXTURE_PATH "gun01.png", false); + LoadTexture(m_texturePovGun, TEXTURE_PATH "GUN.png", false); + LoadTexture(m_textureSoloMultiMenu, TEXTURE_PATH "single_multi.png", false); + LoadTexture(m_textureTitle, TEXTURE_PATH "title.png", false); LoadTexture(MenuTitleTexture, MENU_ITEM_PATH "test.png"); LoadTexture(MenuBGTexture, MENU_ITEM_PATH "test.png"); + LoadTexture(SplachScreenTexture, TEXTURE_PATH "sc2.png"); LoadTexture(MenuQuitTexture, MENU_ITEM_PATH "BasicQuit.png"); LoadTexture(MenuOptionsTexture, MENU_ITEM_PATH "test.png"); LoadTexture(MenuStartTexture, MENU_ITEM_PATH "BasicPlay.png"); @@ -305,6 +359,10 @@ void Engine::LoadResource() { TextureAtlas::TextureIndex texIceIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "metal2.png"); TextureAtlas::TextureIndex texGrassIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "grass.png"); TextureAtlas::TextureIndex texMetalIndex = m_textureAtlas.AddTexture(TEXTURE_PATH "dirt.png"); + TextureAtlas::TextureIndex texBoostHeal = m_textureAtlas.AddTexture(BOOSTER_TEXTURE_PATH "BoosterMauve.png"); + TextureAtlas::TextureIndex texBoostDmg = m_textureAtlas.AddTexture(BOOSTER_TEXTURE_PATH "BoosterRouge.png"); + TextureAtlas::TextureIndex texBoostSpd = m_textureAtlas.AddTexture(BOOSTER_TEXTURE_PATH "BoosterBleu.png"); + TextureAtlas::TextureIndex texBoostInv = m_textureAtlas.AddTexture(BOOSTER_TEXTURE_PATH "BoosterJaune.png"); if (!m_textureAtlas.Generate(TEXTURE_SIZE, false)) { std::cout << " Unable to generate texture atlas ..." << std::endl; @@ -350,7 +408,6 @@ void Engine::KillNotification(Player killer, Player killed) { DisplayNotification(message); } - void Engine::DisplayNotification(std::string message) { if (message.length() > 45) { @@ -360,23 +417,28 @@ void Engine::DisplayNotification(std::string message) { Notification newNotification; newNotification.message = message; newNotification.displayStartTime = m_time; - + notifications.push_back(newNotification); } // Add a method to process the notification queue void Engine::ProcessNotificationQueue() { - m_textureFont.Bind(); - float scale = GetScale(); - unsigned int xOffset = Width() - Width() * 0.26; - unsigned int yOffset = Height() - (Height() / 2.2); + //PrintText(fPosX, fUsernamePosY, ss.str(), 1.5f); + //float fPosX = (Width() / 100.0f) * scaleX; + //float fPosY = Height() - (Height() * 0.05) * scaleY; + + m_textureFont.Bind(); + + auto [scaleX, scaleY] = GetScale(); + + float xOffset = (Width() / 1.5f) * scaleX; + float yOffset = (Height() / 1.2f) * scaleY; - // Iterate through the notifications and display them for (auto it = notifications.begin(); it != notifications.end(); ) { float timeSinceDisplay = m_time - it->displayStartTime; - // Display the notification message with vertical offset - unsigned int y = yOffset - (static_cast(scale * 20) * (it - notifications.begin())); + float y = yOffset - (20.0f * scaleX * (it - notifications.begin())); + glDisable(GL_STENCIL_TEST); glDisable(GL_DEPTH_TEST); @@ -391,8 +453,8 @@ void Engine::ProcessNotificationQueue() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); - - PrintText(xOffset, y, scale, it->message); + + PrintText(xOffset, y, it->message); glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); glBlendEquation(GL_FUNC_SUBTRACT); @@ -402,39 +464,89 @@ void Engine::ProcessNotificationQueue() { glMatrixMode(GL_PROJECTION); glPopMatrix(); - glMatrixMode(GL_MODELVIEW); glPopMatrix(); - // Check if it's time to remove the notification (display for 2 seconds) + if (timeSinceDisplay >= 4.0f) { - it = notifications.erase(it); // Remove the notification + it = notifications.erase(it); } else { ++it; } } - } - - void Engine::DisplayCrosshair() { 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); - glVertex2i(0, 0); - glTexCoord2f(1, 0); - glVertex2i(crossSize, 0); - glTexCoord2f(1, 1); - glVertex2i(crossSize, crossSize); - glTexCoord2f(0, 1); - glVertex2i(0, crossSize); + glTexCoord2f(0, 0); + glVertex2i(0, 0); + glTexCoord2f(1, 0); + glVertex2i(crossSize, 0); + glTexCoord2f(1, 1); + glVertex2i(crossSize, crossSize); + glTexCoord2f(0, 1); + glVertex2i(0, crossSize); glEnd(); } +void Engine::DisplayPovGun() { + // Setter le blend function, tout ce qui sera noir sera transparent + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + glOrtho(0, Width(), 0, Height(), -1, 1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + float scaleX = (Width()) / BASE_WIDTH; + float scaleY = (Height()) / BASE_HEIGHT; + float baseXOffset = 0.4958 * BASE_WIDTH; + float baseWidth = 0.4688 * BASE_WIDTH; + float baseHeight = 0.5787 * BASE_HEIGHT; + float xTranslation = baseXOffset * scaleX; + float quadWidth = baseWidth * scaleX; + float quadHeight = baseHeight * scaleY; + + m_texturePovGun.Bind(); + glLoadIdentity(); + glTranslated(xTranslation, 0, 0); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2i(0, 0); + glTexCoord2f(1, 0); + glVertex2i(quadWidth, 0); + glTexCoord2f(1, 1); + glVertex2i(quadWidth, quadHeight); + glTexCoord2f(0, 1); + glVertex2i(0, quadHeight); + glEnd(); + + // Reset du blend function + glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); + glBlendEquation(GL_FUNC_SUBTRACT); + + glEnable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + void Engine::DisplayCurrentItem() { } @@ -442,55 +554,66 @@ void Engine::DisplayCurrentItem() { void Engine::DisplayHud(int timer) { glBindTexture(GL_TEXTURE_2D, 0); glLoadIdentity(); - glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + auto [scaleX, scaleY] = GetScale(); + + float fBackPosX = (Width() / 25.0f) * scaleX; + float fBackPosY = (Height() - (Height() * 0.815) * scaleY); + float fBackWidth = (Width() / 4.0f) * scaleX; + float fBackHeight = (Height() / 5.5f) * scaleY; + + glColor4f(1.0f, 1.0f, 1.0f, 0.2f); + glBegin(GL_QUADS); + glVertex2f(fBackPosX, fBackPosY); + glVertex2f(fBackPosX + fBackWidth, fBackPosY); + glVertex2f(fBackPosX + fBackWidth, fBackPosY + fBackHeight); + glVertex2f(fBackPosX, fBackPosY + fBackHeight); + glEnd(); + + // HP Bar + float fBarWidth = (Width() / 4.0f) * scaleX; + float fBarHeight = (Height() / 25.0f) * scaleY; + float fPosX = (Width() / 25.0f) * scaleX; + float fBarPosY = (Height() - (Height() * 0.775) * scaleY); - // Barre HP - float fBarWidth = Width() / 4; - float fBarHeight = Height() / 25; - float fPosX = Width() / 20; - float fPosY = Height() - (Height() - (fBarHeight * 4)); float playerHp = m_player.GetHP(); float facteurOmbrage = m_displayInfo ? 0.5f : 1.0f; - // Arri�re-plan (Barre HP) + // HP Bar Background glColor3f(1.0f * facteurOmbrage, 1.0f * facteurOmbrage, 1.0f * facteurOmbrage); glBegin(GL_QUADS); - glVertex2f(fPosX, fPosY - fBarHeight); // Bas-Gauche - glVertex2f(fPosX + fBarWidth, fPosY - fBarHeight); // Bas-Droite - glVertex2f(fPosX + fBarWidth, fPosY); // Haut-Droite - glVertex2f(fPosX, fPosY); // Haut-Gauche + glVertex2f(fPosX, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth, fBarPosY); + glVertex2f(fPosX, fBarPosY); glEnd(); - //TODO: Associer avec m�chanique de vie du joueur - - // Barre HP + // Current HP glColor3f(0.0f * facteurOmbrage, 1.0f * facteurOmbrage, 0.0f * facteurOmbrage); glBegin(GL_QUADS); - glVertex2f(fPosX, fPosY - fBarHeight); // Bas-Gauche - glVertex2f(fPosX + fBarWidth * playerHp, fPosY - fBarHeight); // Bas-Droite - glVertex2f(fPosX + fBarWidth * playerHp, fPosY); // Haut-Droite - glVertex2f(fPosX, fPosY); // Haut-Gauche + glVertex2f(fPosX, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth * playerHp, fBarPosY - fBarHeight); + glVertex2f(fPosX + fBarWidth * playerHp, fBarPosY); + glVertex2f(fPosX, fBarPosY); glEnd(); - // Barre �quip + // Equip Bar glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor3f(1.0f * facteurOmbrage, 1.0f * facteurOmbrage, 1.0f * facteurOmbrage); + + float fEquipWidth = (Width() * 0.175f) * scaleX; + float fEquipHeight = (fEquipWidth / 2.5) * scaleY; + float fEquipPosY = (Height() - (Height() * 0.765) * scaleY); + + glTranslatef(fPosX, fEquipPosY, 0); + m_textureGun.Bind(); - - float margin = Width() * 0.05; - float itemWidth = Width() * 0.33; - float itemHeight = itemWidth / 2.208; - float startX = Width() - itemWidth - margin; - float startY = margin; - - glTranslated(startX, startY, 0); - glBegin(GL_QUADS); - glTexCoord2f(1, 0); glVertex2i(0, 0); - glTexCoord2f(0, 0); glVertex2i(itemWidth, 0); - glTexCoord2f(0, 1); glVertex2i(itemWidth, itemHeight); - glTexCoord2f(1, 1); glVertex2i(0, itemHeight); + glTexCoord2f(0, 0); glVertex2i(0, 0); + glTexCoord2f(1, 0); glVertex2i(fEquipWidth, 0); + glTexCoord2f(1, 1); glVertex2i(fEquipWidth, fEquipHeight); + glTexCoord2f(0, 1); glVertex2i(0, fEquipHeight); glEnd(); //glDisable(GL_BLEND); @@ -498,54 +621,161 @@ void Engine::DisplayHud(int timer) { // Username glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor3f(1.0f, 1.0f, 1.0f); - float scale = GetScale(); + m_textureFont.Bind(); std::ostringstream ss; - ss << m_player.GetUsername(); - PrintText(fPosX, fPosY, scale, ss.str()); + float fUsernamePosY = fBarPosY - (fBarHeight * 2) * scaleY; - //Countdown + ss.str(""); + ss << m_player.GetUsername(); + PrintText(fPosX, fUsernamePosY, ss.str(), 1.5f); + + ss.str(""); + ss << m_player.GetHP() * 100 << "%"; + PrintText(fPosX * 6.25, fUsernamePosY, ss.str(), 1.5f); + + // Countdown ss.str(""); ss << "Time: " << (int)(timer / 60) << ":" << std::setw(2) << std::setfill('0') << timer % 60; - PrintText(Width() - Width() * 0.15, Height() - (Height() / 19.2), scale, ss.str()); - + PrintText(Width() - (Width() * 0.2f) * scaleX, Height() - (Height() * 0.1) * scaleY, ss.str(), 2.0f); } void Engine::DisplayInfo(float elapsedTime, BlockType bloc) { - // Bind de la texture pour le font m_textureFont.Bind(); std::ostringstream ss; - float scale = GetScale(); - unsigned int x = Width() / 25; + auto [scaleX, scaleY] = GetScale(); + + float fPosX = (Width() / 100.0f) * scaleX; + float fPosY = Height() - (Height() * 0.05) * scaleY; + float charSize = 20 + (24 - 20) * (Width() - 1600) / (1920 - 1600); ss << " Fps : " << GetFps(elapsedTime); - PrintText(x, Height() - (Height() / 19.2), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Rendered Chunks : " << m_renderCount; - PrintText(x, Height() - (Height() / 13.7), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " To-Be-Deleted Chunks : " << m_world.GettbDeleted(); - PrintText(x, Height() - (Height() / 10.7), scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); - ss << " Velocity : " << m_player.GetVelocity(); // IMPORTANT : on utilise l � operateur << pour afficher la position - PrintText(x, Height() / 48, scale, ss.str()); + fPosY -= charSize; + + float fPosYJump = ((Height() - (Height() * 0.9f)) * scaleY); + fPosY = fPosYJump; + fPosY -= charSize; + + ss << " Velocity : " << m_player.GetVelocity(); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Direction : " << m_player.GetDirection(); - PrintText(x, Height() / 24, scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Position : " << m_player.GetPosition(); - PrintText(x, Height() / 16, scale, ss.str()); + PrintText(fPosX, fPosY, ss.str()); ss.str(""); + fPosY -= charSize; + ss << " Block : "; - if (bloc == BTYPE_LAST) - ss << "Weapon."; - else ss << (int)bloc; + ss << "Weapon"; + else + ss << (int)bloc; + PrintText(fPosX, fPosYJump, ss.str()); +} - PrintText(x, Height() / 12, scale, ss.str()); +void Engine::DisplaySingleOrMultiplayerMenu() { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + + glDisable(GL_STENCIL_TEST); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + glLoadIdentity(); + glOrtho(0, Width(), 0, Height(), -1, 1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + auto [scaleX, scaleY] = GetScale(); + float fBackPosX = 0.0f; + float fBackPosY = 0.0f; + float fBackWidth = Width(); + float fBackHeight = Height(); + + m_textureSoloMultiMenu.Bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(fBackPosX, fBackPosY); + glTexCoord2f(1.0f, 0.0f); glVertex2f(fBackWidth, fBackPosY); + glTexCoord2f(1.0f, 1.0f); glVertex2f(fBackWidth, fBackHeight); + glTexCoord2f(0.0f, 1.0f); glVertex2f(fBackPosX, fBackHeight); + glEnd(); + + float centerX = (Width() / 2.0f); + float centerY = (Height() / 2.0f); + float titleWidth = (centerX * 1.85f) * scaleX; + float titleHeight = (centerY * 1.85f) * scaleY; + + // Solo game indicator + m_textureTitle.Bind(); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(centerX, centerY); + glTexCoord2f(1.0f, 0.0f); glVertex2f(titleWidth, centerY); + glTexCoord2f(1.0f, 1.0f); glVertex2f(titleWidth, titleHeight); + glTexCoord2f(0.0f, 1.0f); glVertex2f(centerX, titleHeight); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + + // Solo game indicator + float fPosX = (centerX * 1.1f) * scaleX; + float fPosXWidth = (centerX * 1.75f) * scaleX; + float soloPosY = (centerY * 0.75f) * scaleY; + float soloHeight = (centerY * 0.9f) * scaleY; + + glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(fPosX, soloPosY); + glTexCoord2f(1.0f, 0.0f); glVertex2f(fPosXWidth, soloPosY); + glTexCoord2f(1.0f, 1.0f); glVertex2f(fPosXWidth, soloHeight); + glTexCoord2f(0.0f, 1.0f); glVertex2f(fPosX, soloHeight); + glEnd(); + + // Multiplayer game indicator + float multiPosY = (centerY * 0.5f) * scaleY; + float multiHeight = (centerY * 0.65f) * scaleY; + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(fPosX, multiPosY); + glTexCoord2f(1.0f, 0.0f); glVertex2f(fPosXWidth, multiPosY); + glTexCoord2f(1.0f, 1.0f); glVertex2f(fPosXWidth, multiHeight); + glTexCoord2f(0.0f, 1.0f); glVertex2f(fPosX, multiHeight); + glEnd(); + + // TODO: Add SOLO / MULTIPLAYER text with font + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + glEnable(GL_STENCIL_TEST); + glEnable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } void Engine::DrawHud(float elapsedTime, BlockType bloc) { @@ -568,13 +798,12 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { int timer = GetCountdown(elapsedTime); - // Appel de la fonction pour l'affichage de notifications if (m_keyK) { SystemNotification(m_messageNotification); m_keyK = false; } if (m_keyL) { - + KillNotification(m_player, m_player); m_keyL = false; } @@ -591,7 +820,6 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { DisplayCrosshair(); } - // Reset du blend function glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR); glBlendEquation(GL_FUNC_SUBTRACT); @@ -605,31 +833,36 @@ void Engine::DrawHud(float elapsedTime, BlockType bloc) { glPopMatrix(); } -void Engine::PrintText(float x, float y, float scale, const std::string& t) { +void Engine::PrintText(float x, float y, const std::string& t, float charSizeMultiplier) { + auto [scaleX, scaleY] = GetScale(); + float scale = std::min(scaleX, scaleY); + + float baseCharSize = 20 + (24 - 20) * (Width() - 1600) / (1920 - 1600); + float charSize = baseCharSize * charSizeMultiplier; + glLoadIdentity(); glTranslated(x, y, 0); for (unsigned int i = 0; i < t.length(); ++i) { float left = (float)((t[i] - 32) % 16) / 16.f; float top = (float)((t[i] - 32) / 16) / 16.f; - top += .5f; + top += 0.5f; glBegin(GL_QUADS); - glTexCoord2f(left, 1.f - top - .0625f); glVertex2f(0, 0); - glTexCoord2f(left + .0625f, 1.f - top - .0625f); glVertex2f(12 * scale, 0); - glTexCoord2f(left + .0625f, 1.f - top); glVertex2f(12 * scale, 12 * scale); - glTexCoord2f(left, 1.f - top); glVertex2f(0, 12 * scale); + glTexCoord2f(left, 1.f - top - .0625f); glVertex2f(0, 0); + glTexCoord2f(left + .0625f, 1.f - top - .0625f); glVertex2f(charSize * scale, 0); + glTexCoord2f(left + .0625f, 1.f - top); glVertex2f(charSize * scale, charSize * scale); + glTexCoord2f(left, 1.f - top); glVertex2f(0, charSize * scale); glEnd(); - glTranslated(8 * scale, 0, 0); + glTranslated(0.5555f * charSize * scale, 0, 0); } } -float Engine::GetScale() const { - float widthRatio = Width() / BASE_WIDTH; - float heightRatio = Height() / BASE_HEIGHT; - - return (widthRatio + heightRatio) / 2.0f; +std::pair Engine::GetScale() const { + float widthRatio = static_cast(Width()) / BASE_WIDTH; + float heightRatio = static_cast(Height()) / BASE_HEIGHT; + return { widthRatio, heightRatio }; } int Engine::GetFps(float elapsedTime) const { return 1 / elapsedTime; } @@ -641,7 +874,7 @@ int Engine::GetCountdown(float elapsedTime) { } if (m_countdown < m_time) Stop(); - if(!m_stopcountdown) + if (!m_stopcountdown) m_time += elapsedTime; return m_countdown - (int)m_time; } @@ -649,7 +882,10 @@ int Engine::GetCountdown(float elapsedTime) { void Engine::Render(float elapsedTime) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (m_gamestate == GameState::PLAY) + m_time_SplashScreen += elapsedTime; + if(m_time_SplashScreen < 2) + DrawSplachScreen(); + else if (m_gamestate == GameState::PLAY) { HideCursor(); CenterMouse(); //D�placement de centermouse dans l'action de jouer @@ -684,11 +920,11 @@ void Engine::Render(float elapsedTime) { 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(), .8f); + 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(), 1.f); + m_audio.Create3DAudioObj(step, AUDIO_PATH "hit.wav", m_player.GetPosition(), m_player.GetVelocity(), false,1.f); break; default: break; } @@ -750,12 +986,13 @@ void Engine::Render(float elapsedTime) { if (m_isSkybox) m_skybox.Render(skybox); - ProcessNotificationQueue(); DrawHud(elapsedTime, bloc); + DisplayPovGun(); + ProcessNotificationQueue(); 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(), 1.f); + 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) { @@ -831,7 +1068,7 @@ void Engine::KeyPressEvent(unsigned char key) { case 17: // R - Ignorer break; case 19: // T - Ignorer - break; + break; case 24: // Y - Ignorer break; case 255: // Fn - Ignorer diff --git a/SQCSim2021/engine.h b/SQCSim2021/engine.h index 57b4e2e..0ed8b39 100644 --- a/SQCSim2021/engine.h +++ b/SQCSim2021/engine.h @@ -25,6 +25,7 @@ public: Engine(); virtual ~Engine(); virtual void DrawMenu(); + virtual void DrawSplachScreen(); virtual void Init(); virtual void DeInit(); virtual void LoadResource(); @@ -37,7 +38,7 @@ public: virtual void MouseReleaseEvent(const MOUSE_BUTTON &button, int x, int y); private: - float GetScale() const; + std::pair GetScale() const; int GetFps(float elapsedTime) const; int GetCountdown(float elapsedTime); @@ -49,11 +50,13 @@ private: void DisplayNotification(std::string message); void ProcessNotificationQueue(); void DisplayCrosshair(); + void DisplayPovGun(); void DisplayCurrentItem(); void DisplayHud(int timer); void DisplayInfo(float elapsedTime, BlockType bloc); + void DisplaySingleOrMultiplayerMenu(); void DrawHud(float elapsedTime, BlockType bloc); - void PrintText(float x, float y, float scale, const std::string& t); + void PrintText(float x, float y, const std::string& t, float charSizeMultiplier = 1.0f); Connector m_conn; Shader m_shader01; @@ -63,10 +66,13 @@ private: World m_world = World(); WorldRenderer m_wrenderer = WorldRenderer(); - Texture m_textureSkybox; - Texture m_textureFont; Texture m_textureCrosshair; + Texture m_textureFont; Texture m_textureGun; + Texture m_texturePovGun; + Texture m_textureSkybox; + Texture m_textureSoloMultiMenu; + Texture m_textureTitle; Skybox m_skybox; Audio m_audio = Audio(AUDIO_PATH "start.wav"); @@ -87,9 +93,13 @@ private: Texture MenuStartTexture; Texture MenuQuitTexture; Texture MenuOptionsTexture; + Texture SplachScreenTexture; float m_scale; float m_time = 0; + float m_time_SplashScreen = 0; + float m_Width = 0; + float m_Height = 0; int m_renderCount = 0; int m_countdown = COUNTDOWN; @@ -102,6 +112,7 @@ private: bool m_displayHud = true; bool m_displayInfo = false; bool m_resetcountdown = false; + bool m_soloMultiChoiceMade = true; bool m_stopcountdown = false; bool m_keyK = false; diff --git a/SQCSim2021/media/textures/BrouillonbackgroundMenu.png b/SQCSim2021/media/textures/BrouillonbackgroundMenu.png new file mode 100644 index 0000000..ba8631c Binary files /dev/null and b/SQCSim2021/media/textures/BrouillonbackgroundMenu.png differ diff --git a/SQCSim2021/media/textures/sc2.png b/SQCSim2021/media/textures/sc2.png new file mode 100644 index 0000000..daff7ea Binary files /dev/null and b/SQCSim2021/media/textures/sc2.png differ diff --git a/SQCSim2021/media/textures/single_multi.png b/SQCSim2021/media/textures/single_multi.png new file mode 100644 index 0000000..ef0d7b1 Binary files /dev/null and b/SQCSim2021/media/textures/single_multi.png differ diff --git a/SQCSim2021/media/textures/skybox2.png b/SQCSim2021/media/textures/skybox2.png new file mode 100644 index 0000000..4cefbc0 Binary files /dev/null and b/SQCSim2021/media/textures/skybox2.png differ diff --git a/SQCSim2021/media/textures/title.png b/SQCSim2021/media/textures/title.png new file mode 100644 index 0000000..4a58469 Binary files /dev/null and b/SQCSim2021/media/textures/title.png differ diff --git a/SQCSim2021/openglcontext.cpp b/SQCSim2021/openglcontext.cpp index 3820003..7a61b07 100644 --- a/SQCSim2021/openglcontext.cpp +++ b/SQCSim2021/openglcontext.cpp @@ -9,6 +9,7 @@ OpenglContext::~OpenglContext() { } + bool OpenglContext::Start(const std::string& title, int width, int height, bool fullscreen) { m_title = title; @@ -22,13 +23,14 @@ bool OpenglContext::Start(const std::string& title, int width, int height, bool while (m_app.isOpen()) { - clock.restart(); - sf::Event Event; - while (m_app.pollEvent(Event)) - { - switch(Event.type) + clock.restart(); + + sf::Event Event; + while (m_app.pollEvent(Event)) { + switch (Event.type) + { case sf::Event::Closed: m_app.close(); break; @@ -51,29 +53,29 @@ bool OpenglContext::Start(const std::string& title, int width, int height, bool MouseReleaseEvent(ConvertMouseButton(Event.mouseButton.button), Event.mouseButton.x, Event.mouseButton.y); break; case sf::Event::MouseWheelMoved: - if(Event.mouseWheel.delta > 0) + if (Event.mouseWheel.delta > 0) MousePressEvent(MOUSE_BUTTON_WHEEL_UP, Event.mouseButton.x, Event.mouseButton.y); else MousePressEvent(MOUSE_BUTTON_WHEEL_DOWN, Event.mouseButton.x, Event.mouseButton.y); break; default: break; + } } - } - m_app.setActive(); - Render(m_lastFrameTime); - m_app.display(); - - m_lastFrameTime = clock.getElapsedTime().asSeconds(); - - // Handle ourself frame rate limit, sf::Window::setFramerateLimit doesn't seems to work - float waitTime = (1.f / m_maxFps) - m_lastFrameTime; - if(waitTime > 0) - { - sf::sleep(sf::seconds(waitTime)); + m_app.setActive(); + Render(m_lastFrameTime); + m_app.display(); m_lastFrameTime = clock.getElapsedTime().asSeconds(); - } + + // Handle ourself frame rate limit, sf::Window::setFramerateLimit doesn't seems to work + float waitTime = (1.f / m_maxFps) - m_lastFrameTime; + if (waitTime > 0) + { + sf::sleep(sf::seconds(waitTime)); + + m_lastFrameTime = clock.getElapsedTime().asSeconds(); + } } UnloadResource(); diff --git a/SQCSim2021/openglcontext.h b/SQCSim2021/openglcontext.h index b82c683..3825b26 100644 --- a/SQCSim2021/openglcontext.h +++ b/SQCSim2021/openglcontext.h @@ -4,6 +4,7 @@ #include #include #include "define.h" +#include "texture.h" // Documentation de SFML: http://www.sfml-dev.org/documentation/index-fr.php class OpenglContext @@ -31,7 +32,6 @@ public: virtual void MousePressEvent(const MOUSE_BUTTON &button, int x, int y) = 0; virtual void MouseReleaseEvent(const MOUSE_BUTTON &button, int x, int y) = 0; - bool Start(const std::string& title, int width, int height, bool fullscreen); bool Stop(); diff --git a/SQCSim2021/skybox.cpp b/SQCSim2021/skybox.cpp index a024ae7..538e51f 100644 --- a/SQCSim2021/skybox.cpp +++ b/SQCSim2021/skybox.cpp @@ -8,30 +8,30 @@ void Skybox::Init(float size){ int count = 0; VertexBuffer::VertexData* vd = new VertexBuffer::VertexData[24]; - vd[count++] = VertexBuffer::VertexData(size, -size, size, 1.f, 1.f, 1.f, 0.f, .5f); - vd[count++] = VertexBuffer::VertexData(-size, -size, size, 1.f, 1.f, 1.f, .25f, .5f); + vd[count++] = VertexBuffer::VertexData(-size, -size, size, 1.f, 1.f, 1.f, .25f, .5f); + vd[count++] = VertexBuffer::VertexData(-size, size, size, 1.f, 1.f, 1.f, .25f, .75f); + vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, 0.f, .75f); + vd[count++] = VertexBuffer::VertexData(size, -size, size, 1.f, 1.f, 1.f, 0.f, .5f); + + vd[count++] = VertexBuffer::VertexData(-size, -size, -size, 1.f, 1.f, 1.f, .5f, .5f); + vd[count++] = VertexBuffer::VertexData(-size, size, -size, 1.f, 1.f, 1.f, .5f, .75f); + vd[count++] = VertexBuffer::VertexData(-size, size, size, 1.f, 1.f, 1.f, .25f, .75f); + vd[count++] = VertexBuffer::VertexData(-size, -size, size, 1.f, 1.f, 1.f, .25f, .5f); + + vd[count++] = VertexBuffer::VertexData(size, -size, -size, 1.f, 1.f, 1.f, .75f, .5f); + vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .75f, .75f); + vd[count++] = VertexBuffer::VertexData(-size, size, -size, 1.f, 1.f, 1.f, .5f, .75f); + vd[count++] = VertexBuffer::VertexData(-size, -size, -size, 1.f, 1.f, 1.f, .5f, .5f); + + vd[count++] = VertexBuffer::VertexData(size, -size, size, 1.f, 1.f, 1.f, 1.f, .5f); + vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, 1.f, .75f); + vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .75f, .75f); + vd[count++] = VertexBuffer::VertexData(size, -size, -size, 1.f, 1.f, 1.f, .75f, .5f); + + vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, .25f, 1.f); vd[count++] = VertexBuffer::VertexData(-size, size, size, 1.f, 1.f, 1.f, .25f, .75f); - vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, 0.f, .75f); - - vd[count++] = VertexBuffer::VertexData(-size, -size, size, 1.f, 1.f, 1.f, .25f, .5f); - vd[count++] = VertexBuffer::VertexData(-size, -size, -size, 1.f, 1.f, 1.f, .5f, .5f); vd[count++] = VertexBuffer::VertexData(-size, size, -size, 1.f, 1.f, 1.f, .5f, .75f); - vd[count++] = VertexBuffer::VertexData(-size, size, size, 1.f, 1.f, 1.f, .25f, .75f); - - vd[count++] = VertexBuffer::VertexData(-size, -size, -size, 1.f, 1.f, 1.f, .5f, .5f); - vd[count++] = VertexBuffer::VertexData(size, -size, -size, 1.f, 1.f, 1.f, .75f, .5f); - vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .75f, .75f); - vd[count++] = VertexBuffer::VertexData(-size, size, -size, 1.f, 1.f, 1.f, .5f, .75f); - - vd[count++] = VertexBuffer::VertexData(size, -size, -size, 1.f, 1.f, 1.f, .75f, .5f); - vd[count++] = VertexBuffer::VertexData(size, -size, size, 1.f, 1.f, 1.f, 1.f, .5f); - vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, 1.f, .75f); - vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .75f, .75f); - - vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .25f, 1.f); - vd[count++] = VertexBuffer::VertexData(size, size, size, 1.f, 1.f, 1.f, .5f, 1.f); - vd[count++] = VertexBuffer::VertexData(-size, size, size, 1.f, 1.f, 1.f, .5f, .75f); - vd[count++] = VertexBuffer::VertexData(-size, size, -size, 1.f, 1.f, 1.f, .25f, .75f); + vd[count++] = VertexBuffer::VertexData(size, size, -size, 1.f, 1.f, 1.f, .5f, 1.f); vd[count++] = VertexBuffer::VertexData(-size, -size, size, 1.f, 1.f, 1.f, .5f, .25f); vd[count++] = VertexBuffer::VertexData(size, -size, size, 1.f, 1.f, 1.f, .75f, .25f);