问题描述
我正在尝试使用 pygame 制作多客户端游戏。我正在尝试测试客户端向服务器发送数据和服务器发送广播消息的功能,以便所有客户端都可以看到精灵位置。我实现了一个较小的测试样本,其中一些方块移动,这个样本的目的是测试客户端更新从服务器接收的数据(屏幕上方块的位置)。背后的想法是客户端从初始位置发送更改位置,服务器处理数据并将其发送回单个消息,如 |1|100|100|2|200|200|3|300|300 等等是当时位置 100 和 100 的第一个客户,2 是第二个客户,依此类推。 我将离开测试样本:
server.py:
import socket,time,threading
playersNo = 0
counter = 0
message = ""
messageList = {}
def on_new_client(clientsocket,addr):
global message,counter,playersNo,messageList
while True:
time.sleep(0.016)
counter +=1
changeX = clientsocket.recv(1024).decode()
splitChange=changeX.split()
#process the data
toSendY,toSendX=processData(splitChange[1],splitChange[0],splitChange[2],splitChange[3])
#Send message
message=str(toSendY)+"|"+str(toSendX)+"|"
if ( counter >= (playersNo+1) ):
counter = 1
messageList[str(counter)]=message
changesBackToClient = str(toSendY)+' ' + str(toSendX)
clientsocket.send(changesBackToClient.encode())
clientsocket.close()
def broadcast_message(messageList):
server = socket.socket(socket.AF_INET,socket.soCK_DGRAM,socket.IPPROTO_UDP)
server.setsockopt(socket.soL_SOCKET,socket.so_REUSEADDR,1)
server.setsockopt(socket.soL_SOCKET,socket.so_broADCAST,1)
server.settimeout(0.2)
while True:
message=""
for k,v in messageList.items():
message+= k +"|"+v+"|"
message = bytes(message,'utf-8')
server.sendto(message,('<broadcast>',37020))
time.sleep(0.015)
def tcp_socket():
global playersNo,messageList
host = socket.gethostname()
port = 5000
server_socket = socket.socket()
server_socket.bind((host,port))
server_socket.listen(4)
server_socket.settimeout(0.1)
while True:
try:
conn,address = server_socket.accept()
playersNo+=1
t = threading.Thread(target = on_new_client,args =(conn,address,))
t.start()
except socket.timeout:
continue
server_socket.close()
def processData(changeX,changeY,initialValX,initialValY):
dataY = int(initialValY) + int(changeY)
datax = int(initialValX) + int(changeX)
return dataY,datax
if __name__ == '__main__':
thrd = threading.Thread(target=broadcast_message,args = (messageList,))
thrd.start()
tcp_socket()
client.py:
import pygame,socket,threading,random
data=" "
screen_width = 1280
screen_heigth = 960
sqXChange = 0
sqYChange = 0
class Square:
def __init__(self,color,left,top ):
self.color= color
self.left = left
self.top = top
def draw(self):
pygame.draw.rect(screen,self.color,(self.left,self.top,50,50))
sq1 = Square((255,40,0),random.randint(0,1000),800))
def gameLoop():
global sqXChange,sqYChange,sq1
running = True
while running:
screen.fill((255,255,255))
sq1.draw()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
sqYChange -=5
elif event.key == pygame.K_RIGHT:
sqYChange +=5
elif event.key == pygame.K_UP:
sqXChange -=5
elif event.key == pygame.K_DOWN:
sqXChange +=5
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
sqXChange=0
sqYChange=0
pygame.display.flip()
clock.tick(60)
def tcp_socket():
global sqXChange,sq1,data
host = socket.gethostname()
port = 5000
client_socket = socket.socket()
client_socket.connect((host,port))
while True:
time.sleep(0.016)
changes = str(sqXChange)+' '+str(sqYChange) +' ' + str(sq1.left) +' ' + str(sq1.top)
client_socket.send(changes.encode())
changeFromServer = client_socket.recv(1024).decode().strip().split()
print(data)
sq1.top = int(changeFromServer[0])
sq1.left = int(changeFromServer[1])
client_socket.close()
def broadcast_message():
global data
client = socket.socket(socket.AF_INET,socket.IPPROTO_UDP) # UDP
client.setsockopt(socket.soL_SOCKET,1)
client.setsockopt(socket.soL_SOCKET,1)
client.bind(("",37020))
while True:
time.sleep(0.016)
data,addr = client.recvfrom(2048)
data.decode()
if __name__ =="__main__":
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((screen_width,screen_heigth))
t1 = threading.Thread(target = broadcast_message)
t2 = threading.Thread(target = tcp_socket)
t1.setDaemon(True)
t2.setDaemon(True)
t2.start()
t1.start()
gameLoop()
我是 pygame 和线程的新手,所以代码可能有点乱。我此时的问题是数据有时由 1|100|100|2|200|200(好位置)发送,有时它会根据线程写入 1|200|200|2|100|100(错误位置)在那一刻写作。我该如何解决?提前致谢
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)