栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

关于解决python中使用pygame开发联机游戏中鼠标、键盘事件监测无限循环和数据不间断接收导致游戏无法响应问题。

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于解决python中使用pygame开发联机游戏中鼠标、键盘事件监测无限循环和数据不间断接收导致游戏无法响应问题。

基本问题:

在使用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()  #启动线程
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/969385.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号