基本问题:
在使用Pygame开发设计小游戏程序时,基本开发框架是引入pygame,初始化、进行无限循环(监听事件、对事件进行响应、刷新屏幕)。
如果你要实现网络联机游戏,那还需要一个无限循环:就是不断的监听接收数据,并根据接收的数据进行响应。
而这两个循环如果不使用Thread线程,将导致程序进行无法响应状态,无法正常运行。
解决方法:
首先单独写一个循环接收数据的函数,函数并对收的数据进行处理响应。确保游戏双方游戏屏幕的的同步刷新。
第二步,建立一个线程,实现数据接收函数的调用。
第三步,并将线程在游戏开始之前运行(.start())
第四步,运行游戏的主程序,进行无限循环(监听事件、对事件进行响应、刷新屏幕),实现游戏双方的同步效果。
部分代码:
连接服务器函数:
def __init__(self):
"""定义基数连接参数"""
filename='serveradd.txt'
with open(filename,encoding='utf-8') as f: #读取文件中地址和端口号
serveradd = f.readlines()
self.HOST = (serveradd[0].rstrip())
self.PORT = int(serveradd[1])
self.ADDRESS = (self.HOST, self.PORT) # 绑定地址
self.BUFFSIZE = 3000 # 接收数据的最大字节数
self.ENCODING = 'utf-8' # 解码格式
def call_server(self):
"""进行服务连接,与监听数据"""
self.netsok = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) # 创建 socket 对象
try:
self.netsok.connect(self.ADDRESS) # 建立链接服务器
except ConnectionRefusedError:
return '服务器链接失败!'
else:
return '服务器链接成功!'
获取数据函数(#无限循环):
def get_data(self):
while True: #无限循环
tempdata = self.netwk.resv_data()
# print(len(tempdata))
if tempdata == '目前未有匹配对手,请等待!':
#print(tempdata)
self.net_successed = True #用于调用显示提示信息按钮
self.heiqi_move=False
self.baiqi_move=False
elif tempdata=='服务器出现故障!':
#print(tempdata)
self.server_failure=True
self.heiqi_move = False
self.baiqi_move = False
self.net_opponent_leaved = False
elif tempdata == 'baise':
#print("游戏配对成功,开始游戏,您为白色棋手!")
self.net_opponent =True #用于调用显示提示信息“游戏配对成功,开始游戏,您为白色棋手!”
self.net_successed = False #匹配对手成功后,就不再显示等待匹配信息
self.net_opponent_leaved = False
self.myqcolor = tempdata
self.baiqi_move = True
self.heiqi_move = False
#print(self.myqcolor)
elif tempdata == 'heise':
#print("游戏配对成功,开始游戏,您为黑色棋手!")
self.net_opponent = True # 用于调用显示提示信息“游戏配对成功,开始游戏,您为黑色棋手!”
self.net_successed = False #匹配对手成功后,就不再显示等待匹配信息
self.net_opponent_leaved= False
self.myqcolor = tempdata
self.baiqi_move = False
self.heiqi_move = False
#print(self.myqcolor)
elif tempdata == '对方已退出游戏,请重新等待棋手!':
#print(tempdata)
self.net_opponent_leaved=True # 用于调用显示提示信息“对方已退出游戏,是否重新等待新棋手?” 还要显示“是”“否”,并相应的事件
self.baiqi_move = False
self.heiqi_move = False
self.numb = 1
self._restart_game() #重新绘置棋盘和棋子以备用
else: #下面数据正常接收后相应的操作
if len(tempdata) % 30 != 0:
# 如果接收到数据不为30的整数倍,将与下次数据连接分析
self.rdata = self.rdata + tempdata
else:
self.rdata = tempdata
if len(self.rdata) % 30 == 0:
n = int(len(self.rdata) / 30)
for i in range(0, n):
tdata = self.rdata[i * 30:(i + 1) * 30]
if tdata[6:8] == 'MD':
self._rget_init_pos(tdata[:5], tdata[11:20]) # 传递接收到对方的棋色和坐标值
if tdata[6:8] == 'MM': # 说明对方是移动鼠标事件qcolor+MMOS(x,y)(x,y)
self._rcheck_qi_pos(tdata[:5], tdata[11:20], tdata[21:])
if tdata[6:8] == 'MU':
self._rjiaozhen_pos(tdata[:5], tdata[11:20], tdata[21:])
线程调用(避免数据接收与事件监测双循环导致的无法响应):
def init_network(self):
"""首次运行初始化网络包括:联接服务器,向服务器发送随机数,接收服务器第一次返回数据"""
netstr = self.netwk.call_server() #链接服务器
if netstr == '服务器链接失败!':
print(netstr)
sys.exit() #退出系统,或者考虑用图片的方式提示情况,进行再次链接
if netstr == '服务器链接成功!':
self.netwk.send_sjs() #发送随机数
thread = Thread(target=self.get_data) #发送数据后,就进行接收数据的循环线程中
thread.setDaemon(True)
thread.start() #启动线程



