Bonjour,
Dans le cadre d'un projet scolaire, on essaye de programmer un Jeu dans le style d'un Pacman, sauf que les trois fantômes seraient contrôlés chacun par un joueur différent.
Donc pour l'instant, on a fait 2 Fantômes, et un "pacman"
Comment on s'y est pris :
1 Serveur qui gère les déplacements de 3 clients (2 pour les fantômes et 1 pour le "pacman")
Serveur :
3 Clients :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 #!/usr/bin/env python3 # -*- coding: utf-8 -*- ##### SERVEUR TCP - Multi-clients ##### import socket import tkinter as tk from tkinter import * import select HOTE = 'localhost' # quelconque PORT = 12345 TAILLE_MAX_PAQUET = 1024 recu = '' sSrv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sSrv.bind((HOTE, PORT)) sSrv.listen(4) # Nbre maxi acceptés "en parallèle" print("Le serveur écoute à présent sur le port", PORT) ######### LISTE ######## clients_connectes = [] #liste des clients connectés liste_des_mecs = [] #liste des clients connectés + leur ip et leur port piongentil=[] #liste coordonnées du pion gentil (x et y) pionmechant1=[] #liste coordonnées du pion mechant1 pionmechant2=[] #liste coordonnées du pion mechant2 coopion=[] #liste coordonnées des tous les pions ########### VARIABLE ############# i=0 # prend la valeur du nombre de client connectés lip="" # l'ip de l'envoyeur lport="" # le port de l'envoyeur serveur_ecoute = True dx = 0 dy = 0 x=245 #variable gestion coordonnées des pions y=12 x1=232 y1=217 x2=257 y2=217 ############ CREATION FENETRE PRINCIPALE ################## root2 = Tk() fenetre_plateau=Canvas(root2, width="487", height="359") photo = PhotoImage(file="mapcouper.gif") fenetre_plateau.create_image(243.5, 179.5, image=photo) fenetre_plateau.pack() root2.title("Serveur") ########### FONCTIONS ################ def move(event): x = fenetre_plateau.canvasx(event.x) y = fenetre_plateau.canvasy(event.y) #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]): def cercle(x, y, r,couleur,nom): #fonction création de cercle "Trace le cercle de centre (x,y) et de rayon r" fenetre_plateau.create_oval((x-r, y-r, x+r, y+r), fill=couleur,tag=nom) def quibouge(gentiloumechant): #fonction pour faire bouger 1 des pions fenetre_plateau.move(gentiloumechant, dx,dy) fenetre_plateau.update() fenetre_plateau.after(1) ######### CODE PRINCIPALE ############### cercle(245,12,8,"purple","gentil") #creation des 3 pions cercle(232,217,8,"red","mechant1") cercle(257,217,8,"orange","mechant2") while serveur_ecoute: # Boucle d'écoute du serveur # (1) On vérifie si des nouveaux clients demandent à se connecter # => on écoute le serveur, maxi pendant 0.05 sec. connexions_demandees, wlist, xlist = select.select([sSrv], [], [], 0.05) # en_ecoute, en_ecriture, en_except., pour select.select for connexion in connexions_demandees: sCli, infos_connexion = connexion.accept() # On ajoute le socket connecté à la liste des clients connectés clients_connectes.append(sCli) nb_clients_connectes=len(clients_connectes) while i<nb_clients_connectes: #associe le client à son ip+port+donne un nom de joueur client = [clients_connectes[i],sCli.getpeername()[0],sCli.getpeername()[1],"joueur"+str(i)] liste_des_mecs.append(client) i=i+1 # (2) Maintenant, on écoute la liste des clients *connectés* liste_sCli_a_lire = [] try: # sinon, exception levée si la liste des clients est vide liste_sCli_a_lire, wlist, xlist = select.select(clients_connectes, [], [], 0.05) except select.error: pass # Ne rien faire s'il n'y en a pas else: # On parcourt la liste des clients à lire for sCli in liste_sCli_a_lire: msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc recu = str(msg_recu, encoding="utf-8") # à encoder... lip=sCli.getpeername()[0] # met l'ip de l'envoyeur dans cette variable lport=sCli.getpeername()[1] # met le port de l'envoyeur dans cette variable if recu == 'UP': #si "UP" alors on va en haut sCli.send(bytes(""+recu+"", encoding="utf-8")) dx = 0 dy = -3 if recu == 'DOWN': #si "DOWN" alors on va en bas sCli.send(bytes(""+recu+"", encoding="utf-8")) dx = 0 dy = 3 if recu == 'LEFT': #si "LEFT" alors on va à gauche sCli.send(bytes(""+recu+"", encoding="utf-8")) dx = -3 dy = 0 if recu == 'RIGHT': #si "RIGHT" alors on va à droite sCli.send(bytes(""+recu+"", encoding="utf-8")) dx = 3 dy = 0 fenetre_plateau.update() #on actualise la fenêtre fenetre_plateau.after(1) if recu: if lip==liste_des_mecs[0][1] and lport==liste_des_mecs[0][2]: #regarde si l'ip de l'envoyeur et celle du premier client (joueur0) quibouge("gentil") #fait bouger le pion violet (gentil) x=x+dx #permet de savoir les coordonnées x du pion gentil y=y+dy #permet de savoir les coordonnées y du pion gentil piongentil=[x,y] if i>=2: #regarde si il y a un deuxieme client if lip==liste_des_mecs[1][1] and lport==liste_des_mecs[1][2]: #regarde si l'ip de l'envoyeur et celle du deuxieme client (joueur1) quibouge("mechant1") #fait bouger le pion rouge (mechant1) x1=x1+dx y1=y1+dy pionmechant1=[x1,y1] if i==3: #regarde si il y a un troisieme client if lip==liste_des_mecs[2][1] and lport==liste_des_mecs[2][2]: #regarde si l'ip de l'envoyeur et celle du troisieme client (joueur2) quibouge("mechant2") #fait bouger le pion orange (mechant2) x2=x2+dx y2=y2+dy pionmechant2=[x2,y2] coopion=[piongentil,pionmechant1,pionmechant2] recu='' dx = 0 dy = 0 print("Fermeture des connexions au serveur") for sCli in clients_connectes: sCli.close() sSrv.close()
1 :2 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 #!/usr/bin/env python3 # -*- coding: utf-8 -*- ##### CLIENT TCP ##### import socket import tkinter as tk HOTE = 'localhost' PORT = 12345 TAILLE_MAX_PAQUET = 100 up = False down = False left = False right = False msg_a_envoyer = '' sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sCli.connect((HOTE, PORT)) print("Connexion établie avec le serveur sur le port", PORT) ############################################# from tkinter import * root2 = Tk() fenetre_plateau=Canvas(root2, width="487", height="359") photo = PhotoImage(file="mapcouper.gif") fenetre_plateau.create_image(243.5, 179.5, image=photo) fenetre_plateau.pack() root2.title("Client 1") carrebleu = [[11,94], [53,94], [11,207], [53,207]] carrebleu2 = [[438,92], [478,92], [438,206], [478,206]] x = 240 y = 145 r = 8 dx = 0 dy = 0 couleur="red" msg_a_envoyer = None recu = '' def move(event): x = fenetre_plateau.canvasx(event.x) y = fenetre_plateau.canvasy(event.y) #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]): def cercle(x, y, r,couleur,nom): #fonction création de cercle "Trace le cercle de centre (x,y) et de rayon r" fenetre_plateau.create_oval((x-r, y-r, x+r, y+r), fill=couleur,tag=nom) def up (event=None): global msg_a_envoyer msg_a_envoyer = 'UP' def down (event=None): global msg_a_envoyer msg_a_envoyer = 'DOWN' def left (event=None): global msg_a_envoyer msg_a_envoyer = 'LEFT' def right (event=None): global msg_a_envoyer msg_a_envoyer = 'RIGHT' def up2 (event=None): global dx global dy dx = 0 dy = -3 def down2(event=None): global dx global dy dx = 0 dy = 3 def left2(event=None): global dx global dy dx = -3 dy = 0 def right2(event=None): global dx global dy dx = 3 dy = 0 cercle(245,12,8,"purple","gentil") #creation des 3 pions cercle(232,217,8,"red","mechant1") cercle(257,217,8,"orange","mechant2") root2.bind('<1>', move) root2.bind('<Up>', up) root2.bind('<Down>', down) root2.bind('<Left>', left) root2.bind('<Right>', right) ################################################### while 1: # Saisie du message # Envoi du message if msg_a_envoyer in ('UP', 'DOWN', 'LEFT', 'RIGHT'): envoi = bytes(msg_a_envoyer, encoding="utf-8") sCli.send(envoi) msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc recu = str(msg_recu, encoding="utf-8") # à encoder... #print(recu) msg_a_envoyer = '' if recu == "UP": up2() if recu == "DOWN": down2() if recu == "LEFT": left2() if recu == "RIGHT": right2() fenetre_plateau.move("gentil", dx,dy) fenetre_plateau.update() fenetre_plateau.after(1) dx = 0 dy = 0 ######################################################### fen.mainloop()3 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 #!/usr/bin/env python3 # -*- coding: utf-8 -*- ##### CLIENT TCP ##### import socket import tkinter as tk HOTE = 'localhost' PORT = 12345 TAILLE_MAX_PAQUET = 100 up = False down = False left = False right = False msg_a_envoyer = '' sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sCli.connect((HOTE, PORT)) print("Connexion établie avec le serveur sur le port", PORT) ############################################# from tkinter import * root2 = Tk() fenetre_plateau=Canvas(root2, width="487", height="359") photo = PhotoImage(file="mapcouper.gif") fenetre_plateau.create_image(243.5, 179.5, image=photo) fenetre_plateau.pack() root2.title("Client 2") carrebleu = [[11,94], [53,94], [11,207], [53,207]] carrebleu2 = [[438,92], [478,92], [438,206], [478,206]] x = 240 y = 145 r = 8 dx = 0 dy = 0 couleur="red" msg_a_envoyer = None recu = '' def move(event): x = fenetre_plateau.canvasx(event.x) y = fenetre_plateau.canvasy(event.y) #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]): def cercle(x, y, r,couleur,nom): #fonction création de cercle "Trace le cercle de centre (x,y) et de rayon r" fenetre_plateau.create_oval((x-r, y-r, x+r, y+r), fill=couleur,tag=nom) def up (event=None): global msg_a_envoyer msg_a_envoyer = 'UP' def down (event=None): global msg_a_envoyer msg_a_envoyer = 'DOWN' def left (event=None): global msg_a_envoyer msg_a_envoyer = 'LEFT' def right (event=None): global msg_a_envoyer msg_a_envoyer = 'RIGHT' def up2 (event=None): global dx global dy dx = 0 dy = -3 def down2(event=None): global dx global dy dx = 0 dy = 3 def left2(event=None): global dx global dy dx = -3 dy = 0 def right2(event=None): global dx global dy dx = 3 dy = 0 cercle(245,12,8,"purple","gentil") #creation des 3 pions cercle(232,217,8,"red","mechant1") cercle(257,217,8,"orange","mechant2") root2.bind('<1>', move) root2.bind('<Up>', up) root2.bind('<Down>', down) root2.bind('<Left>', left) root2.bind('<Right>', right) ################################################### while 1: # Saisie du message # Envoi du message if msg_a_envoyer in ('UP', 'DOWN', 'LEFT', 'RIGHT'): envoi = bytes(msg_a_envoyer, encoding="utf-8") sCli.send(envoi) msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc recu = str(msg_recu, encoding="utf-8") # à encoder... #print(recu) msg_a_envoyer = '' if recu == "UP": up2() if recu == "DOWN": down2() if recu == "LEFT": left2() if recu == "RIGHT": right2() fenetre_plateau.move("mechant1", dx,dy) fenetre_plateau.update() fenetre_plateau.after(1) dx = 0 dy = 0 ######################################################### fen.mainloop()Donc quand on bouge tel ou tel pion (A l'aide des flèches), les informations arrivent bien au serveur, le pion X bouge bien sur le serveur et sur le Client dont vient l'informaton, mais on n'arrive pas a faire en sorte que les pions bougent sur les autres Clients.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 #!/usr/bin/env python3 # -*- coding: utf-8 -*- ##### CLIENT TCP ##### import socket import tkinter as tk HOTE = 'localhost' PORT = 12345 TAILLE_MAX_PAQUET = 100 up = False down = False left = False right = False msg_a_envoyer = '' sCli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sCli.connect((HOTE, PORT)) print("Connexion établie avec le serveur sur le port", PORT) ############################################# from tkinter import * root2 = Tk() fenetre_plateau=Canvas(root2, width="487", height="359") photo = PhotoImage(file="mapcouper.gif") fenetre_plateau.create_image(243.5, 179.5, image=photo) fenetre_plateau.pack() root2.title("Client 3") carrebleu = [[11,94], [53,94], [11,207], [53,207]] carrebleu2 = [[438,92], [478,92], [438,206], [478,206]] x = 240 y = 145 r = 8 dx = 0 dy = 0 couleur="red" msg_a_envoyer = None recu = '' def move(event): x = fenetre_plateau.canvasx(event.x) y = fenetre_plateau.canvasy(event.y) #if (carrebleu2[0][0] < event.x < carrebleu2[1][0] and carrebleu2[0][1] < event.y < carrebleu2[2][1]) or (carrebleu[0][0] < event.x < carrebleu[1][0] and carrebleu[0][1] < event.y < carrebleu[2][1]): def cercle(x, y, r,couleur,nom): #fonction création de cercle "Trace le cercle de centre (x,y) et de rayon r" fenetre_plateau.create_oval((x-r, y-r, x+r, y+r), fill=couleur,tag=nom) def up (event=None): global msg_a_envoyer msg_a_envoyer = 'UP' def down (event=None): global msg_a_envoyer msg_a_envoyer = 'DOWN' def left (event=None): global msg_a_envoyer msg_a_envoyer = 'LEFT' def right (event=None): global msg_a_envoyer msg_a_envoyer = 'RIGHT' def up2 (event=None): global dx global dy dx = 0 dy = -3 def down2(event=None): global dx global dy dx = 0 dy = 3 def left2(event=None): global dx global dy dx = -3 dy = 0 def right2(event=None): global dx global dy dx = 3 dy = 0 cercle(245,12,8,"purple","gentil") #creation des 3 pions cercle(232,217,8,"red","mechant1") cercle(257,217,8,"orange","mechant2") root2.bind('<1>', move) root2.bind('<Up>', up) root2.bind('<Down>', down) root2.bind('<Left>', left) root2.bind('<Right>', right) ################################################### while 1: # Saisie du message # Envoi du message if msg_a_envoyer in ('UP', 'DOWN', 'LEFT', 'RIGHT'): envoi = bytes(msg_a_envoyer, encoding="utf-8") sCli.send(envoi) msg_recu = sCli.recv(TAILLE_MAX_PAQUET) # octets, donc recu = str(msg_recu, encoding="utf-8") # à encoder... #print(recu) msg_a_envoyer = '' if recu == "UP": up2() if recu == "DOWN": down2() if recu == "LEFT": left2() if recu == "RIGHT": right2() fenetre_plateau.move("mechant2", dx,dy) fenetre_plateau.update() fenetre_plateau.after(1) dx = 0 dy = 0 ######################################################### fen.mainloop()
On essaye de mettre en place la gestion des coordonnées de chaque pion pour ensuite gérer le déplacement sur TOUT les clients grâce a l'envoi des coordonnées de chaque pions a tout les serveurs pour actualiser leurs position, et par la suite gérer la collision sur les obstacles de la map.
On a un peu du mal, vous auriez des idées ?
On tiens par contre a rester avec les modules utilisés.
Si vous voulez la Map :
http://www.casimages.com/img.php?i=1...3950672744.gif
Partager