summaryrefslogtreecommitdiff
path: root/jeu-test/tetris_lan_src/_LISEZMOI.txt
blob: 82d8bf068e6375c3fa91be5de8bd1dbaebc999c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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--