summaryrefslogtreecommitdiff
path: root/jeu-test/tetris_lan_src/_LISEZMOI.txt
diff options
context:
space:
mode:
Diffstat (limited to 'jeu-test/tetris_lan_src/_LISEZMOI.txt')
-rw-r--r--jeu-test/tetris_lan_src/_LISEZMOI.txt94
1 files changed, 94 insertions, 0 deletions
diff --git a/jeu-test/tetris_lan_src/_LISEZMOI.txt b/jeu-test/tetris_lan_src/_LISEZMOI.txt
new file mode 100644
index 0000000..82d8bf0
--- /dev/null
+++ b/jeu-test/tetris_lan_src/_LISEZMOI.txt
@@ -0,0 +1,94 @@
+
+ Tetris - 2 players LAN.
+ Done by Clément CORDE.
+ Contact : c1702@yahoo.com
+
+
+ Bonjour,
+
+ Je vous laisse récupérer et regarder le lisezmoi.txt du Tetris simple, je me contente de rajouter en plus ici ce que j'ai fait pour la partie "réseau".
+
+ Ceci est mon premier essai d'un jeu en réseau. Ca semble marcher pas trop mal, mais je suis toujours preneur de conseils.
+
+
+> Réseau :
+
+ J'utilise le système des sockets et j'ai pris l'option d'utiliser le protocole TCP/IP.
+
+ C'est un tout petit peu plus lourd que de l'UDP, mais ça simplifiait grandement les choses : En effet, TCP gère lui même les retransmissions et le fait que les paquets arrivent bien dans l'ordre. Avec UDP, il aurait fallu faire ça "à la main".
+
+ J'utilise aussi l'option "TCP_NODELAY". Ce flag coupe le "Nagle algorithm", petit truc utilisé à peu près partout qui fait que les paquets à envoyer, s'ils sont petits, sont bufferisés et envoyés plus tard en une fois, dans le but de ne pas utiliser trop de bande passante (en gros, pour éviter d'envoyer des paquets TCP dans lesquels les headers, adresses, checksums et autres prennent 4 fois plus de place que le message lui même). C'est un truc très utile, sauf dans notre cas, où justement, on veut être averti dès qu'une pièce bouge. Sans ce flag, on reçoit plusieurs messages en une fois, et le résultat est que ça à l'air saccadé, sans pour autant que le jeu ne rame !
+
+ Je me suis basé sur plusieurs tutoriaux pour voir comment fonctionnaient les communications client/serveur. Je citerai les pages de "quantic-storm" sont très bien, car elles donnent les fonctions à utiliser sous Windows et sous Linux, et les différences entre elles. Ensuite, il y a plein de doc sur MSDN, et il y a les man pages.
+
+ Pour jouer à deux, un joueur doit choisir le mode "serveur", l'autre le mode "client".
+
+ Le serveur ouvre une socket d'écoute (voir la variable (structure) gSockListen), et attend qu'un client se connecte. Quand il reçoit une connexion, il ouvre une nouvelle socket pour dialoguer avec ce client (voir la variable gSockCom).
+
+ Le Client, lui, ouvre une socket (gSockCom, mais on exécute le prg depuis une autre machine) avec laquelle il contacte et communique avec le serveur.
+
+ Et bien sûr (s'il était besoin de préciser), on utilise les sockets en mode non bloquant !
+
+ Le truc, c'est qu'il faut appeler les fonctions dans le bon ordre. En résumé :
+- Server: socket / bind / listen / accept / send and-or recv / close
+- Client: socket / connect / send and-or recv / close
+
+
+> Système de jeu et de messages :
+
+ Tout d'abord, il faut préciser que ce système est spécifiquement adapté à un mode 2 joueurs. Il y aurait des choses à revoir pour plus de joueurs simultanés.
+
+ Chaque joueur gère son aire de jeu (celle de gauche) et partielement celle de l'autre joueur. Quand une pièce bouge (déplacement ou rotation) chez nous, on envoie un msg à l'autre machine (e_Msg_PieceMove). On reçoit donc pour le deuxième joueur la position de la pièce en cours, son n°, son angle. On ne gère donc pas la descente ou l'accélération pour le 2ème joueur. Par contre, quand une pièce "pose" (message e_Msg_PiecePose), on teste la disparition des lignes. Le score/niveau/nombre de lignes du joueur 2 est géré localement aussi.
+
+ Le petit truc un peu spécial, ce sont les messages d'envoi de lignes à l'autre joueur. J'ai préféré gérer tout ça avec des messages pour être sûr de ne pas avoir de désynchronisation. Je m'explique : Quand je fais 4 lignes, j'en envoie 3 à l'autre (e_Msg_LinesSend). Quand l'autre les reçoit, il prend ça en compte, et nous renvoie un message de reception (e_Msg_LinesRecv), et à ce moment là, on prend en les lignes pour le joueur 2. Comme ça, on est sûrs de prendre en compte l'addition de lignes au bon moment. Bon, maintenant, il y a peut-être plus simple, mais ça fonctionne apparement pas mal.
+
+ Ah oui, on ne rajoute les lignes malus qu'au moment ou une pièce pose, ce qui évite les problèmes du style la pièce en cours qui est à une ligne de poser, le tableau monte de 3 lignes, et la pièce en cours se retrouve dans les blocs... C'est gérable, mais bon, le malus est déjà suffisament chiant pour qu'en plus, ce ne soit pas nécessaire de gêner le joueur sur sa pièce en cours.
+
+ J'ai aussi réfléchi à la façon de positionner le trou sur les lignes de malus. Soit le Master à mis l'option "LAN RND HOLE" à ON, et la position du trou est décidée en début de partie. Le trou est à la même position pour les deux joueurs. Soit l'option est à OFF, et le trou sera à gauche. La position du trou est indiquée par un '^' sous l'aire de jeu.
+
+ Liste des messages et de leurs paramètres :
+
+- e_Msg_NextPiece = 0, // Next piece : Pièce.
+- e_Msg_PieceMove, // Déplacement d'une pièce : Pièce, x, y, angle.
+- e_Msg_PiecePose, // Une pièce pose > On l'incruste dans le tableau de jeu : Pièce, x, y, angle.
+- e_Msg_LinesSend, // Envoi de x lignes. Celui qui envoie des lignes envoie ce message.
+- e_Msg_LinesRecv, // X lignes reçues. Celui qui reçoit des lignes envoie ce message.
+
+- e_Msg_HolePos, // Position du trou, envoyé en début de partie par le master si nécessaire.
+- e_Msg_PauseOn, // Déclenchement de la pause.
+- e_Msg_PauseOff, // Arrêt de la pause.
+- e_Msg_Dead, // Mort du joueur.
+- e_Msg_StartingLevel, // Level en cours, envoyé en début de partie.
+
+ Du coup, on voit bien si un message est a destination du joueur 2 (la plupart) ou du joueur 1. C'est pour ça que la réception des messages est très simple : Je distribue un message qui arrive en fonction de son type, sans gérer de destinataire.
+
+
+ > Séparation jeu / réseau :
+
+ J'ai fait en sorte que quand on doit envoyer et recevoir des messages, on n'ait pas a se soucier des sockets. Tout ça est isolé dans le fichier "tcpip.c", et je fournis au jeu des fonctions TCP_Send et TCP_Receive.
+
+
+ > Compilation :
+
+ Toujours Code::Blocks sous Windows XP (SP3), avec gcc et SDL. Sur ma Debian 5, c'est aussi gcc, bien sûr !
+
+ Je n'ai pas inclus le fichier projet pour la raison suivante : Comme il y a peu de chances que vos répertoires soient les mêmes que les miens, le projet ne se lirait de toutes façons probablement pas.
+
+ Créez un nouveau projet SDL, copiez tous les fichiers sources ainsi que les répertoires "gfx" et "sfx" dans le répertoire du projet, incluez tous les fichiers sources au projet, et ça devrait fonctionner.
+
+ Options de compilation :
+ -Wall : Voir tous les warnings.
+ -O3 : Optimisation du code pour la vitesse.
+ -DNDEBUG (= #define NDEBUG) : En mode release, pour que les asserts ne soient plus compilés.
+
+ De plus, pour la version windows, il est nécessaire de rajouter la librairie "libws2_32" dans les "link libraries" du "linker settings".
+
+
+> License :
+
+ Je n'ai pas la prétention que ce code soit bon, puissant, ou quoi que ce soit. En revanche, il fonctionne. Je distribue les sources pour que les gens puissent s'en inspirer, peut-être y trouver des astuces, voire réutiliser une partie du code. Dans ce dernier cas, il est bien entendu que celà doit rester dans un cadre non commercial ! Dans le cas contraire, vous êtes priés de me contacter avant.
+
+ Et pour ceux à qui ce code aura été utile, un p'tit greeting quelque part, c'est toujours sympa ! (^_^)
+
+
+--End of file--