mirror of
https://github.com/BreizhHardware/bloubloulespoissons.git
synced 2026-03-18 21:50:32 +01:00
Merge branch 'online' into gawr-gura
This commit is contained in:
12
display.cpp
12
display.cpp
@@ -11,7 +11,7 @@ double calculateDistance(int x1, int y1, int x2, int y2) {
|
||||
void displayNearbyPlayers(SDL_Renderer* renderer, TTF_Font* font, Player& currentPlayer, std::vector<Player>& players, double threshold) {
|
||||
int currentX = currentPlayer.getUnifiedX();
|
||||
int currentY = currentPlayer.getUnifiedY();
|
||||
int offsetY = 90; // Starting Y position for displaying nearby players
|
||||
int offsetY = 90;
|
||||
|
||||
for (auto& player : players) {
|
||||
if (&player == ¤tPlayer) continue; // Skip the current player
|
||||
@@ -19,8 +19,7 @@ void displayNearbyPlayers(SDL_Renderer* renderer, TTF_Font* font, Player& curren
|
||||
int playerX = player.getUnifiedX();
|
||||
int playerY = player.getUnifiedY();
|
||||
double distance = calculateDistance(currentX, currentY, playerX, playerY);
|
||||
|
||||
if (distance < threshold) {
|
||||
if (distance <= threshold) {
|
||||
std::string nearbyPlayerText = "Nearby Player: (" + std::to_string(playerX) + ", " + std::to_string(playerY) + ")";
|
||||
SDL_Color textColor = {0, 255, 0};
|
||||
SDL_Surface* textSurface = TTF_RenderText_Solid(font, nearbyPlayerText.c_str(), textColor);
|
||||
@@ -30,7 +29,12 @@ void displayNearbyPlayers(SDL_Renderer* renderer, TTF_Font* font, Player& curren
|
||||
SDL_FreeSurface(textSurface);
|
||||
SDL_DestroyTexture(textTexture);
|
||||
|
||||
offsetY += 20; // Move down for the next player
|
||||
// Affiche la 1ère image de playerV2-full.png
|
||||
SDL_Rect playerRect = {69, 73, 112, 117};
|
||||
SDL_Rect playerPosForRender = {playerX, playerY, 112, 117};
|
||||
SDL_RenderCopy(renderer, player.getTexture(), &playerRect, &playerPosForRender);
|
||||
|
||||
offsetY += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
env.cpp
3
env.cpp
@@ -18,8 +18,11 @@ int fishCount = 0;
|
||||
int FISH_NUMBER = 2500;
|
||||
std::vector<SDL_Texture*> texturesVector;
|
||||
std::atomic<bool> running(true);
|
||||
std::atomic<bool> game_running(false);
|
||||
std::atomic<bool> isPlayingOnline(false);
|
||||
std::atomic<bool> messageThreadRunning(false);
|
||||
std::atomic<bool> isHost(false);
|
||||
|
||||
|
||||
bool initEnvironment(SDL_Renderer* renderer) {
|
||||
SDL_Surface* backgroundSurface = IMG_Load("../img/background.png");
|
||||
|
||||
3
env.h
3
env.h
@@ -30,9 +30,12 @@ extern int fishCount;
|
||||
extern int FISH_NUMBER;
|
||||
extern std::vector<SDL_Texture*> texturesVector;
|
||||
extern std::atomic<bool> running;
|
||||
extern std::atomic<bool> game_running;
|
||||
extern std::atomic<bool> isPlayingOnline;
|
||||
extern std::atomic<bool> messageThreadRunning;
|
||||
extern std::vector<Player> players;
|
||||
extern std::vector<Player> players_server;
|
||||
extern std::atomic<bool> isHost;
|
||||
|
||||
bool initEnvironment(SDL_Renderer* renderer);
|
||||
std::vector<SDL_Texture*> initTexture(SDL_Renderer* renderer);
|
||||
|
||||
256
main.cpp
256
main.cpp
@@ -10,6 +10,7 @@
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
|
||||
#include "fish.h"
|
||||
#include "decors.h"
|
||||
@@ -23,6 +24,8 @@
|
||||
#include "shark.h"
|
||||
|
||||
|
||||
#include <system_error>
|
||||
|
||||
std::mutex mtx;
|
||||
std::atomic<bool> menuRunning(true);
|
||||
|
||||
@@ -31,14 +34,57 @@ SDL_Texture* playerTexture = nullptr;
|
||||
SDL_Texture* fishTextures[100]; // Adjust the size as needed
|
||||
std::vector<Fish> school;
|
||||
std::vector<Player> players;
|
||||
std::vector<Player> players_server;
|
||||
|
||||
struct ThreadInfo {
|
||||
std::thread::id id;
|
||||
std::string functionName;
|
||||
};
|
||||
|
||||
std::vector<ThreadInfo> threadInfos;
|
||||
|
||||
bool initSDL();
|
||||
void handleQuit();
|
||||
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons(int argc, char* args[]);
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(int argc, char* args);
|
||||
void renderScene(std::vector<Player>& players, const std::vector<Kelp>& kelps, const std::vector<Rock>& rocks, const std::vector<Coral>& corals,Shark& shark );
|
||||
|
||||
void cleanup();
|
||||
void closeGame();
|
||||
void displayFPS(SDL_Renderer* renderer, TTF_Font* font, int fps);
|
||||
void displayPlayerCoord(SDL_Renderer* renderer, TTF_Font* font, int playerX, int playerY);
|
||||
void displayUnifiedPlayerCoord(SDL_Renderer* renderer, TTF_Font* font, int unifiedX, int unifiedY);
|
||||
void displayPlayerCount(SDL_Renderer* renderer, TTF_Font* font, int playerCount);
|
||||
void playerMovementThread(Player& player);
|
||||
void handleClientMessages(Player& player);
|
||||
void handleQuitThread();
|
||||
void HandleMenuClick(Menu& menu);
|
||||
void updateFishRange(std::vector<Fish>& school, int start, int end);
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons(int argc, char* args[]);
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(int argc, std::string args);
|
||||
|
||||
template <typename Function, typename... Args>
|
||||
std::thread createThread(std::string key, Function&& func, Args&&... args) {
|
||||
try {
|
||||
std::cout << "Creating thread: " << key << std::endl;
|
||||
std::thread thread([key, func = std::forward<Function>(func), ...args = std::forward<Args>(args)]() mutable {
|
||||
ThreadInfo info;
|
||||
info.id = std::this_thread::get_id();
|
||||
info.functionName = key;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
threadInfos.push_back(info);
|
||||
}
|
||||
func(std::forward<Args>(args)...);
|
||||
std::cout << "ThreadID = " << info.id << " ThreadFunction = " << info.functionName << std::endl;
|
||||
});
|
||||
return thread;
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Failed to create thread: " << e.what() << std::endl;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void displayFPS(SDL_Renderer* renderer, TTF_Font* font, int fps) {
|
||||
std::string fpsText = "FPS: " + std::to_string(fps);
|
||||
@@ -167,13 +213,16 @@ bool initSDL() {
|
||||
}
|
||||
|
||||
void playerMovementThread(Player& player) {
|
||||
int pId = player.getPlayerId();
|
||||
std::cout << "starting playerMovementThread for player " << pId << "..." << std::endl;
|
||||
while (running) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
player.handlePlayerMovement(ENV_WIDTH, ENV_HEIGHT, windowWidth, windowHeight);
|
||||
try {
|
||||
std::cout << "Starting playerMovementThread for player " << player.getPlayerId() << std::endl;
|
||||
while (game_running) {
|
||||
player.handlePlayerMovement(ENV_WIDTH, ENV_HEIGHT, windowWidth, windowHeight);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(16)); // 60 FPS
|
||||
}
|
||||
std::cout << "Exiting playerMovementThread for player " << player.getPlayerId() << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception in playerMovementThread: " << e.what() << std::endl;
|
||||
}
|
||||
std::cout << "playerMovementThread for player " << pId << " ended" << std::endl;
|
||||
}
|
||||
|
||||
void handleClientMessages(Player& player) {
|
||||
@@ -186,7 +235,7 @@ void handleClientMessages(Player& player) {
|
||||
|
||||
void handleQuitThread() {
|
||||
std::cout << "handleQuitThread..." << std::endl;
|
||||
while (running) {
|
||||
while (game_running) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
handleQuit();
|
||||
}
|
||||
@@ -200,7 +249,7 @@ void HandleMenuClick(Menu& menu){
|
||||
}
|
||||
|
||||
void updateFishRange(std::vector<Fish>& school, int start, int end){
|
||||
while (running) {
|
||||
while (game_running) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
@@ -251,7 +300,7 @@ int main(int argc, char* args[]) {
|
||||
menu.addPage("Multi-Join");
|
||||
menu.changePage("Main");
|
||||
|
||||
std::thread menu_thread(HandleMenuClick, std::ref(menu));
|
||||
std::thread menu_thread = createThread("Menu thread", HandleMenuClick, std::ref(menu));
|
||||
|
||||
menu.addText("Main", (windowWidth/2) - 300, 50, 600, 100, "BloubBloub les poissons", 1024);
|
||||
|
||||
@@ -264,7 +313,7 @@ int main(int argc, char* args[]) {
|
||||
|
||||
});
|
||||
|
||||
menu.addButton("Main", (windowWidth/2) - 100, (windowHeight/2 + 75) - 25, 200, 50, "Multi", 1024, [&menu](){
|
||||
menu.addButton("Main", (windowWidth/2) - 100, (windowHeight/2 + 75) - 25, 200, 50, "Multi (WIP)", 1024, [&menu](){
|
||||
std::cout << "Multi" << std::endl;
|
||||
menu.changePage("Multi");
|
||||
});
|
||||
@@ -273,7 +322,7 @@ int main(int argc, char* args[]) {
|
||||
std::cout << "Host" << std::endl;
|
||||
isPlayingOnline = true;
|
||||
menuRunning = false;
|
||||
pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(0, nullptr);
|
||||
pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(0, "");
|
||||
});
|
||||
|
||||
menu.addButton("Multi", (windowWidth/2) - 100, (windowHeight/2 + 75) - 25, 200, 50, "Join", 1024, [&menu](){
|
||||
@@ -285,19 +334,19 @@ int main(int argc, char* args[]) {
|
||||
// });
|
||||
|
||||
menu.addButton("Multi-Join", (windowWidth/2) - 100, windowHeight/2 - 25, 200, 50, "", 24, [](){
|
||||
std::cout << "Text input button clicked" << std::endl;
|
||||
std::cout << "IP input button clicked" << std::endl;
|
||||
}, true);
|
||||
|
||||
menu.addButton("Multi-Join", (windowWidth/2) - 100, (windowHeight/2 + 75) - 25, 200, 50, "", 24, [](){
|
||||
std::cout << "Text input button clicked" << std::endl;
|
||||
}, true);
|
||||
|
||||
menu.addButton("Multi-Join", (windowWidth/2) - 100, (windowHeight/2 + 125) - 25, 200, 50, "Join", 1024, [&menu](){
|
||||
menu.addButton("Multi-Join", (windowWidth/2) - 100, (windowHeight/2 + 75) - 25, 200, 50, "Join !", 1024, [&menu](){
|
||||
std::cout << "Join" << std::endl;
|
||||
isPlayingOnline = true;
|
||||
menuRunning = false;
|
||||
int port = 1234;
|
||||
char* ip = "100.93.105.98";
|
||||
//char* ip = "10.30.42.206";
|
||||
// Pour l'ip récupère l'interieur du bouton IP input
|
||||
std::vector<Button> buttons = menu.getButtons();
|
||||
std::string ip = buttons[0].inputText;
|
||||
std::cout << ip << std::endl;
|
||||
pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(port, ip);
|
||||
});
|
||||
|
||||
@@ -309,7 +358,7 @@ int main(int argc, char* args[]) {
|
||||
});
|
||||
|
||||
//menu.addButton((windowWidth/2) - 100, (windowHeight/2 + 25) + 50, 200, 50, "Multi", 1024);
|
||||
//std::thread quit_thread(handleQuitThread);
|
||||
std::thread quit_thread(handleQuitThread);
|
||||
|
||||
while (running) {
|
||||
|
||||
@@ -327,8 +376,9 @@ int main(int argc, char* args[]) {
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Exception caught: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
if (!isPlayingOnline) {
|
||||
cleanup();
|
||||
}
|
||||
//pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons(argc, args);
|
||||
return 0;
|
||||
}
|
||||
@@ -340,6 +390,8 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
game_running = true;
|
||||
|
||||
std::vector<Kelp> kelps;
|
||||
std::vector<Rock> rocks;
|
||||
std::vector<Coral> corals;
|
||||
@@ -355,22 +407,23 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
std::vector<std::thread> fish_threads;
|
||||
int fishPerThread = school.size() / std::thread::hardware_concurrency();
|
||||
for (int i = 0; i < school.size(); i += fishPerThread) {
|
||||
fish_threads.emplace_back(updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size())));
|
||||
fish_threads.emplace_back(createThread("Fish thread", updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size()))));
|
||||
}
|
||||
std::thread quit_thread(handleQuitThread);
|
||||
std::thread quit_thread = createThread("Quit thread", handleQuitThread);
|
||||
|
||||
// Offline
|
||||
players.emplace_back(Player(windowWidth / 2, windowHeight / 2, 5, renderer, 0));
|
||||
std::thread player_thread(playerMovementThread, std::ref(players[0]));
|
||||
std::thread player_thread = createThread("Player thread", playerMovementThread, std::ref(players[0]));
|
||||
|
||||
|
||||
Shark shark(0, 0, 0.1, 0.1,0, 150, 150, renderer,players);
|
||||
std::thread shark_thread(updateShark, std::ref(shark));
|
||||
|
||||
while (running) {
|
||||
renderScene(players, kelps, rocks, corals, shark);
|
||||
handleQuit();
|
||||
while (game_running) {
|
||||
renderScene(players, kelps, rocks, corals);
|
||||
//handleQuit();
|
||||
|
||||
}
|
||||
running = false;
|
||||
try{
|
||||
if(player_thread.joinable())
|
||||
player_thread.join();
|
||||
@@ -391,21 +444,23 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Exception caught 4: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
if (shark_thread.joinable())
|
||||
shark_thread.join();
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Exception caught 5: " << e.what() << std::endl;
|
||||
}
|
||||
running = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(int argc, char* args) {
|
||||
int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mais_une_des_fonctions_principale_meme_primordiale_du_projet_denomme_bloubloulespoissons_mais_celle_ci_elle_lance_en_multijoueur(int argc, std::string args) {
|
||||
// if (!initSDL()) {
|
||||
// std::cerr << "Failed to initialize!" << std::endl;
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
game_running = true;
|
||||
std::vector<Kelp> kelps;
|
||||
std::vector<Rock> rocks;
|
||||
std::vector<Coral> corals;
|
||||
@@ -419,7 +474,7 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
int fishPerThread = school.size() / std::thread::hardware_concurrency();
|
||||
int thread_id = 0;
|
||||
for (int i = 0; i < school.size(); i += fishPerThread) {
|
||||
threads.emplace_back(updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size())));
|
||||
threads.emplace_back(createThread("Fish thread", updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size()))));
|
||||
}
|
||||
|
||||
Shark shark(rand() % ENV_WIDTH, rand() % ENV_HEIGHT, 0.1, 0.1,0, 150, 150, renderer,players);
|
||||
@@ -429,34 +484,34 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
freopen("CON", "w", stderr);
|
||||
|
||||
if (isPlayingOnline) {
|
||||
if (argc == 0 && args == nullptr) {
|
||||
if (argc == 0 && args == "") {
|
||||
if (!initServer()) {
|
||||
std::cerr << "Failed to initialize server!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::thread acceptThread(acceptClients);
|
||||
acceptThread.detach();
|
||||
isHost = true;
|
||||
std::cout << "isHost: " << isHost << std::endl;
|
||||
std::thread acceptThread = createThread("Accept thread", acceptClients);
|
||||
IPaddress ip;
|
||||
if (!initClient(ip, "localhost", 1234)) {
|
||||
std::cerr << "Failed to initialize client!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
players.emplace_back(Player(windowWidth / 2, windowHeight / 2, 5, renderer, 1));
|
||||
players.emplace_back(Player(windowWidth / 2, windowHeight / 2, 5, renderer, 0));
|
||||
std::ranges::sort(school, Fish::SortByX);
|
||||
std::vector<std::thread> fish_threads;
|
||||
int fishPerThread = school.size() / std::thread::hardware_concurrency();
|
||||
for (int i = 0; i < school.size(); i += fishPerThread) {
|
||||
fish_threads.emplace_back(updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size())));
|
||||
fish_threads.emplace_back(createThread("Fish thread", updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size()))));
|
||||
}
|
||||
messageThreadRunning = true;
|
||||
std::thread messageThread(handleClientMessages, std::ref(players[0]));
|
||||
std::thread playerThread(playerMovementThread, std::ref(players[0]));
|
||||
std::thread messageThread = createThread("Message thread", handleClientMessages, std::ref(players[0]));
|
||||
std::thread playerThread = createThread("Player thread", playerMovementThread, std::ref(players[0]));
|
||||
|
||||
while (running) {
|
||||
renderScene(players, kelps, rocks, corals,shark);
|
||||
SDL_Delay(10);
|
||||
}
|
||||
running = false;
|
||||
messageThreadRunning = false;
|
||||
try{
|
||||
//if(playerThread.joinable())
|
||||
@@ -502,30 +557,38 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Exception caught 5: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
running = false;
|
||||
}
|
||||
else if (argc > 0 && argc < 65535 && args != nullptr) {
|
||||
int port = atoi(args);
|
||||
char* host = args;
|
||||
if (!initClient(ip, host, 1234)) {
|
||||
else if (argc > 0 && argc < 65535 && args != "") {
|
||||
int port = 1234;
|
||||
std::string host = args;
|
||||
if (!initClient(ip, host.c_str(), 1234)) {
|
||||
std::cerr << "Failed to initialize client!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> disX(0, ENV_WIDTH);
|
||||
std::uniform_int_distribution<> disY(0, ENV_HEIGHT);
|
||||
players.emplace_back(Player(disX(gen), disY(gen), 5, renderer, 1));
|
||||
*/
|
||||
players.emplace_back(Player(windowWidth / 2, windowHeight / 2, 5, renderer, 1));
|
||||
std::ranges::sort(school, Fish::SortByX);
|
||||
std::vector<std::thread> fish_threads;
|
||||
int fishPerThread = school.size() / std::thread::hardware_concurrency();
|
||||
for (int i = 0; i < school.size(); i += fishPerThread) {
|
||||
fish_threads.emplace_back(updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size())));
|
||||
fish_threads.emplace_back(createThread("Fish thread", updateFishRange, std::ref(school), i, std::min(i + fishPerThread, static_cast<int>(school.size()))));
|
||||
}
|
||||
messageThreadRunning = true;
|
||||
std::thread messageThread(handleClientMessages, std::ref(players[0]));
|
||||
std::thread playerThread(playerMovementThread, std::ref(players[0]));
|
||||
std::thread messageThread = createThread("Message thread", handleClientMessages, std::ref(players[0]));
|
||||
std::thread playerThread = createThread("Player thread", playerMovementThread, std::ref(players[0]));
|
||||
|
||||
while (running) {
|
||||
renderScene(players, kelps, rocks, corals,shark);
|
||||
SDL_Delay(10);
|
||||
}
|
||||
running = false;
|
||||
messageThreadRunning = false;
|
||||
try{
|
||||
//if(playerThread.joinable())
|
||||
@@ -562,6 +625,7 @@ int pas_la_fontion_main_enfin_ce_nest_pas_la_fontion_principale_du_programme_mai
|
||||
} catch (const std::system_error& e) {
|
||||
std::cerr << "Exception caught 4: " << e.what() << std::endl;
|
||||
}
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,12 +639,18 @@ void handleQuit() {
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
running = false;
|
||||
if (isPlayingOnline && isHost) {
|
||||
closeServer();
|
||||
}
|
||||
game_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (keystate[SDL_SCANCODE_ESCAPE]) {
|
||||
running = false;
|
||||
if (isPlayingOnline && isHost) {
|
||||
closeServer();
|
||||
}
|
||||
game_running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,6 +658,7 @@ void renderScene(std::vector<Player>& players, const std::vector<Kelp>& kelps, c
|
||||
static Uint32 lastTime = 0;
|
||||
static int frameCount = 0;
|
||||
static int fps = 0;
|
||||
//std::cout << "renderScene for " << players.size() << " players" << std::endl;
|
||||
|
||||
const Uint32 currentTime = SDL_GetTicks64();
|
||||
frameCount++;
|
||||
@@ -630,29 +701,88 @@ void renderScene(std::vector<Player>& players, const std::vector<Kelp>& kelps, c
|
||||
for (auto& player : players) {
|
||||
auto [playerX, playerY] = player.getPlayerPos();
|
||||
displayPlayerCoord(renderer, font, playerX, playerY);
|
||||
int unifiedX = player.getUnifiedX();
|
||||
int unifiedY = player.getUnifiedY();
|
||||
}
|
||||
|
||||
for (auto& player_server : players_server) {
|
||||
int unifiedX = player_server.getUnifiedX();
|
||||
int unifiedY = player_server.getUnifiedY();
|
||||
displayUnifiedPlayerCoord(renderer, font, unifiedX, unifiedY);
|
||||
displayNearbyPlayers(renderer, font, player, players, 500.0);
|
||||
displayNearbyPlayers(renderer, font, player_server, players_server, 500.0);
|
||||
}
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
TTF_CloseFont(font);
|
||||
TTF_Quit();
|
||||
SDL_DestroyTexture(backgroundTexture);
|
||||
try {
|
||||
if (font != nullptr) {
|
||||
TTF_CloseFont(font);
|
||||
font = nullptr;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for CloseFont: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
TTF_Quit();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for TTF_Quit: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
if (playerTexture != nullptr) {
|
||||
SDL_DestroyTexture(playerTexture);
|
||||
playerTexture = nullptr;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for DestroyTexture (playerTexture): " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fishCount; ++i) {
|
||||
SDL_DestroyTexture(fishTextures[i]);
|
||||
try {
|
||||
if (fishTextures[i] != nullptr) {
|
||||
SDL_DestroyTexture(fishTextures[i]);
|
||||
fishTextures[i] = nullptr;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for DestroyTexture (fishTextures[" << i << "]): " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
if (renderer != nullptr) {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
|
||||
try {
|
||||
if (renderer != nullptr) {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
renderer = nullptr;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for DestroyRenderer: " << e.what() << std::endl;
|
||||
}
|
||||
if (window != nullptr) {
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
try {
|
||||
if (window != nullptr) {
|
||||
SDL_DestroyWindow(window);
|
||||
window = nullptr;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for DestroyWindow: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
SDL_Quit();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for SDL_Quit: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
IMG_Quit();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for IMG_Quit: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
SDLNet_Quit();
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Exception caught for SDLNet_Quit: " << e.what() << std::endl;
|
||||
}
|
||||
IMG_Quit();
|
||||
SDLNet_Quit();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
|
||||
5
menu.cpp
5
menu.cpp
@@ -163,3 +163,8 @@ void Menu::addPage(std::string title){
|
||||
page.title = title;
|
||||
pages.push_back(page);
|
||||
}
|
||||
|
||||
|
||||
std::vector<Button> Menu::getButtons(){
|
||||
return pages[currentPage].buttons;
|
||||
}
|
||||
2
menu.h
2
menu.h
@@ -75,6 +75,8 @@ class Menu {
|
||||
void addText(std::string page, int x, int y, int w, int h, std::string text, int size);
|
||||
|
||||
void addPage(std::string title);
|
||||
|
||||
std::vector<Button> getButtons();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -23,26 +23,30 @@ bool initServer() {
|
||||
}
|
||||
|
||||
void acceptClients() {
|
||||
while (running) {
|
||||
while (game_running) {
|
||||
TCPsocket clientSocket = SDLNet_TCP_Accept(server);
|
||||
if (clientSocket) {
|
||||
clients.push_back(clientSocket);
|
||||
int clientId = clients.size() - 1;
|
||||
createNewPlayer(clientId);
|
||||
updateKeepAlive(clientId);
|
||||
startKeepAlive(clientId);
|
||||
std::thread clientThread([clientSocket, clientId]() {
|
||||
std::thread keepAliveThread(sendKeepAlive, clientSocket);
|
||||
keepAliveThread.detach();
|
||||
while (running) {
|
||||
std::string message = receiveMessage(clientSocket);
|
||||
if (!message.empty()) {
|
||||
std::cout << "Server received: " << message << std::endl;
|
||||
if (message.find(";move;") != std::string::npos) {
|
||||
if (message == "keepalive") {
|
||||
updateKeepAlive(clientId);
|
||||
} else if (message.find(";move;") != std::string::npos) {
|
||||
char direction[20];
|
||||
sscanf(message.c_str(), "%d;move;%s", &clientId, &direction);
|
||||
|
||||
int newX = 0, newY = 0, newUnifedX = 0, newUnifedY = 0;
|
||||
std::cout << "Client " << clientId << " moved " << direction << std::endl;
|
||||
int newX = 0, newY = 0;
|
||||
std::tie(newX, newY) = updatePlayerPosition(clientId, direction);
|
||||
// Mettre à jour la position du joueur
|
||||
players_server[clientId].updatePosition(newX, newY);
|
||||
std::string updatedMessage = std::to_string(clientId) + ";moved;" + std::to_string(newX) + "," + std::to_string(newY);
|
||||
for (TCPsocket client : clients) {
|
||||
sendMessage(client, updatedMessage);
|
||||
@@ -124,18 +128,18 @@ std::pair<int, int> updatePlayerPosition(int clientId, const std::string& direct
|
||||
}
|
||||
|
||||
void createNewPlayer(int clientId) {
|
||||
if (clientId <= 0) {
|
||||
if (clientId < 0) {
|
||||
std::cerr << "Invalid client ID: " << clientId << std::endl;
|
||||
return;
|
||||
}
|
||||
// Create a new player at a default position (e.g., 0, 0)
|
||||
Player newPlayer(0, 0, 5, renderer, clientId);
|
||||
players.push_back(newPlayer);
|
||||
players_server.push_back(newPlayer);
|
||||
playerPositions[clientId] = {0, 0}; // Initialize player position
|
||||
|
||||
// Send the list of existing players to the new client
|
||||
std::string playerListMessage = "playerList;";
|
||||
for (auto& player : players) {
|
||||
for (auto& player : players_server) {
|
||||
auto [x, y] = player.getPlayerPos();
|
||||
playerListMessage += std::to_string(player.getPlayerId()) + "," + std::to_string(x) + "," + std::to_string(y) + ";";
|
||||
}
|
||||
@@ -159,10 +163,45 @@ void checkClientAlive() {
|
||||
std::cerr << "Client " << it->first << " is not responding. Removing..." << std::endl;
|
||||
SDLNet_TCP_Close(clients[it->first]);
|
||||
clients.erase(clients.begin() + it->first);
|
||||
playerPositions.erase(it->first); // Supprimer la position du joueur
|
||||
it = lastKeepAlive.erase(it);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void closeServer() {
|
||||
std::string quitMessage = "host;quit";
|
||||
for (TCPsocket client : clients) {
|
||||
sendMessage(client, quitMessage);
|
||||
}
|
||||
// Fermer les sockets et nettoyer les ressources
|
||||
for (TCPsocket client : clients) {
|
||||
SDLNet_TCP_Close(client);
|
||||
}
|
||||
clients.clear();
|
||||
SDLNet_TCP_Close(server);
|
||||
}
|
||||
|
||||
void handleServerMessages() {
|
||||
std::string message = receiveMessage(server);
|
||||
if (!message.empty()) {
|
||||
std::cout << "Server received: " << message << std::endl;
|
||||
if (message.find(";moved;") != std::string::npos) {
|
||||
int clientId, x, y;
|
||||
sscanf(message.c_str(), "%d;moved;%d,%d", &clientId, &x, &y);
|
||||
// Mettre à jour la position du joueur dans players_server
|
||||
for (auto& player : players_server) {
|
||||
std::cout << "Player ID: " << player.getPlayerId() << std::endl;
|
||||
std::cout << "Client ID: " << clientId << std::endl;
|
||||
std::cout << "PlayerId == ClientId: " << (player.getPlayerId() == clientId) << std::endl;
|
||||
if (player.getPlayerId() == clientId) {
|
||||
player.updatePosition(x, y);
|
||||
std::cout << "Player " << clientId << " moved to " << player.getUnifiedX() << ", " << player.getUnifiedY() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,5 +21,7 @@ std::pair<int, int> updatePlayerPosition(int clientId, const std::string& direct
|
||||
void createNewPlayer(int clientId);
|
||||
void updateKeepAlive(int clientId);
|
||||
void checkClientAlive();
|
||||
void closeServer();
|
||||
void handleServerMessages();
|
||||
|
||||
#endif //NETWORKING_H
|
||||
@@ -37,6 +37,8 @@ void sendMessage(TCPsocket socket, const std::string& message) {
|
||||
int result = SDLNet_TCP_Send(socket, &len, sizeof(len));
|
||||
if (result < sizeof(len)) {
|
||||
std::cerr << "SDLNet_TCP_Send failed: " << SDLNet_GetError() << std::endl;
|
||||
std::cerr << "Closing the game ..." << std::endl;
|
||||
game_running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,15 +126,18 @@ void handleClientMessage(Player& player) {
|
||||
}
|
||||
}
|
||||
|
||||
void sendKeepAlive(int clientId) {
|
||||
std::string message = std::to_string(clientId) + ";still_alive";
|
||||
sendMessage(client, message);
|
||||
void sendKeepAlive(TCPsocket serverSocket) {
|
||||
while (game_running) {
|
||||
std::string keepAliveMessage = "keepalive";
|
||||
sendMessage(serverSocket, keepAliveMessage);
|
||||
SDL_Delay(3000); // Envoyer un message de keepalive toutes les 3 secondes
|
||||
}
|
||||
}
|
||||
|
||||
void startKeepAlive(int clientId) {
|
||||
std::thread([clientId] () {
|
||||
void startKeepAlive(TCPsocket serverSocket) {
|
||||
std::thread([serverSocket] () {
|
||||
while (messageThreadRunning) {
|
||||
sendKeepAlive(clientId);
|
||||
sendKeepAlive(serverSocket);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
||||
}
|
||||
}).detach();
|
||||
|
||||
@@ -21,8 +21,7 @@ void closeClient();
|
||||
void sendMessage(TCPsocket socket, const std::string& message);
|
||||
std::string receiveMessage(TCPsocket socket);
|
||||
void handleClientMessage(Player& player);
|
||||
void sendKeepAlive(int clientId);
|
||||
void startKeepAlive(int clientId);
|
||||
|
||||
void sendKeepAlive(TCPsocket serverSocket);
|
||||
void startKeepAlive(TCPsocket serverSocket);
|
||||
|
||||
#endif //NETWORKING_CLIENT_H
|
||||
|
||||
28
player.cpp
28
player.cpp
@@ -49,6 +49,7 @@ void Player::draw(SDL_Renderer* renderer) {
|
||||
SDL_RenderCopyEx(renderer, this->playerTexture, &this->playerRect[this->currentSprite], &this->playerPosForRender, 0, nullptr, this->currentFlip);
|
||||
|
||||
this->drawEnergyBar(renderer);
|
||||
|
||||
};
|
||||
|
||||
void Player::handlePlayerMovement(int ENV_WIDTH, int ENV_HEIGHT, int windowWidth, int windowHeight) {
|
||||
@@ -67,7 +68,9 @@ void Player::handlePlayerMovement(int ENV_WIDTH, int ENV_HEIGHT, int windowWidth
|
||||
bool moved = false;
|
||||
if (this->energy != 0) {
|
||||
if (isPlayingOnline) {
|
||||
moved = onlineMovement();
|
||||
if (keystate[SDL_SCANCODE_W] || keystate[SDL_SCANCODE_S] || keystate[SDL_SCANCODE_A] || keystate[SDL_SCANCODE_D]) {
|
||||
moved = onlineMovement();
|
||||
}
|
||||
} else {
|
||||
if (keystate[SDL_SCANCODE_W]) {
|
||||
if (camera.getY() > 0 && tempY == this->playerBaseY) {
|
||||
@@ -144,7 +147,11 @@ void Player::handlePlayerMovement(int ENV_WIDTH, int ENV_HEIGHT, int windowWidth
|
||||
} else {
|
||||
Uint32 currentTime = SDL_GetTicks();
|
||||
if (currentTime - lastMoveTime >= 5000) {
|
||||
this->energy += 0.2f;
|
||||
if (this->energy > 50.0f) {
|
||||
this->energy += 0.4f; // Récupération plus rapide si l'énergie est élevée
|
||||
} else {
|
||||
this->energy += 0.2f; // Récupération plus lente si l'énergie est faible
|
||||
}
|
||||
if (this->energy > 100.0f) {
|
||||
this->energy = 100.0f;
|
||||
}
|
||||
@@ -180,11 +187,15 @@ void Player::handleClientMessages() {
|
||||
std::string message = receiveMessage(client);
|
||||
if (!message.empty()) {
|
||||
std::cout << "Client received: " << message << std::endl;
|
||||
if (message == "host;quit") {
|
||||
std::cout << "Host has quit. Closing client..." << std::endl;
|
||||
game_running = false;
|
||||
return;
|
||||
}
|
||||
if (message.find(";moved;") != std::string::npos) {
|
||||
int clientId, UnifiedX, UnifiedY, xCam, yCam;
|
||||
int clientId, xCam, yCam;
|
||||
sscanf(message.c_str(), "%d;moved;%d,%d", &clientId, &xCam, &yCam);
|
||||
// Update the player's position
|
||||
if (clientId == this->playerId) {
|
||||
if (clientId == playerId) {
|
||||
this->setPlayerPos(750, 400);
|
||||
Camera& camera = Camera::getInstance();
|
||||
if (xCam >= 0 && xCam <= ENV_WIDTH - windowWidth) {
|
||||
@@ -200,10 +211,9 @@ void Player::handleClientMessages() {
|
||||
|
||||
bool Player::onlineMovement() {
|
||||
const Uint8* keystate = SDL_GetKeyboardState(NULL);
|
||||
std::string message = std::to_string(this->playerId) + ";move;";
|
||||
std::string message = std::to_string(getPlayerId()) + ";move;";
|
||||
bool moved = false;
|
||||
if (keystate[SDL_SCANCODE_W]) {
|
||||
//std::string message = std::to_string(this->playerId) + ";move;up";
|
||||
message += "up-";
|
||||
moved = true;
|
||||
}
|
||||
@@ -229,8 +239,8 @@ bool Player::onlineMovement() {
|
||||
void Player::updatePosition(int x, int y) {
|
||||
int camX = x + windowWidth / 2;
|
||||
int camY = y + windowHeight / 2;
|
||||
this->unifiedX = camX;
|
||||
this->unifiedY = camY;
|
||||
unifiedX = camX;
|
||||
unifiedY = camY;
|
||||
}
|
||||
|
||||
int Player::getUnifiedX() {
|
||||
|
||||
Reference in New Issue
Block a user