- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 pygame
在 Python 中创建一个简单的多人游戏和 socket
模块。它只是由两个圆圈组成,由两台不同计算机的 W、A、S、D 键控制。
起初我用 recv()
创建了一个客户端。在 pygame 循环的中间。它运行良好,但 recv()
阻塞了循环,所以圆圈的运动并不顺畅,我不得不将速度增加到 6(在设置为 0.6 之前)才能获得正常速度。这是代码(我已经总结了一下):
客户端第一版
#import modules
def main(sock):
pygame.init()
#Display screen and set initial me_x and me_y
vel = 0.6
while True:
keys_pressed = pygame.key.get_pressed()
#Change me_x and me_y (with A, D, W, S keys)
#Make sure me_x and me_y don't get off the screen
screen.fill(color)
if other_x and other_y:
pygame.draw.circle(screen, colorMe, (other_x, other_y), radi)
pygame.draw.circle(screen, colorOther, (int(me_x), int(me_y)), radi)
pygame.display.flip()
sock.send(int(me_x).to_bytes(3, byteorder = 'big') + int(me_y).to_bytes(3, byteorder = 'big'))
otherPos = sock.recv(BUFSIZ)
other_x = int.from_bytes(otherPos[:3], byteorder = 'big')
other_y = int.from_bytes(otherPos[3:], byteorder = 'big')
print(other_x, other_y)
#CONNECT TO TCP SOCKET
other_x = None
other_y = None
main(client_socket)
然后,我试着把
recv()
在线程中停止阻塞循环:
#import modules
def main(sock):
pygame.init()
#Display screen and set initial me_x and me_y
vel = 0.6
while True:
for i in range(30):
keys_pressed = pygame.key.get_pressed()
#Change me_x and me_y (with A, D, W, S keys)
#Make sure me_x and me_y don't get off the screen
screen.fill(color)
if other_x and other_y:
pygame.draw.circle(screen, colorOther, (other_x, other_y), 15)
pygame.draw.circle(screen, colorMe, (int(me_x), int(me_y)), 15)
pygame.display.flip()
msg = int(me_x).to_bytes(3, byteorder = 'big') + int(me_y).to_bytes(3, byteorder = 'big')
sock.send(msg)
def recv_pos(sock):
while True:
other_pos = sock.recv(BUFSIZ)
other_x = int.from_bytes(other_pos[:3], byteorder = 'big')
other_y = int.from_bytes(other_pos[3:], byteorder = 'big')
print(other_x, other_y)
#CONNECT TO TCP SOCKET
other_x = None
other_y = None
receive_thread = threading.Thread(target = recv_pos, args = (client_socket,))
receive_thread.daemon = True
receive_thread.start()
main(client_socket)
但是,当我在两台不同的计算机上启动客户端 2 的 2 个实例时,它给了我一个
OverflowError
:
OverflowError: Python int too large to convert to C long
for i in range(30):
因为我认为服务器正在崩溃,因为同时发送的消息太多。输出是相同的:大约 3 秒后,程序崩溃并给出
OverflowError
.
print()
recv()
之后的两个版本中的语句查看我收到的 x 和 y 的值。在第一个版本中,它们都在宽度和高度范围内。但是,在第 2 版中,收到的消息中有 1/5 是一个很大的数字,例如
124381473265
。 .如果这个数字更大,它给出
OverflowError
.我不明白为什么会这样:我在两个版本中都以相同的方式编码和解码消息,但是一个有效,另一个无效。
最佳答案
将您的套接字代码放入线程中,或使用 select.select()
用于非阻塞套接字读取。然后当数据报从服务器到达时,将自定义事件消息发布回主循环。
import pygame
import enum
class NetworkEvents( enum.IntEnum ):
EVENT_HANGUP = pygame.USEREVENT + 1
EVENT_MESSAGE = pygame.USEREVENT + 2
pickle
模块来封装这些数据,但首先,我会使用简单的字符串数据进行预测试。更容易调试。然后,一旦传输代码全部完成并经过测试,如有必要,请更改为二进制。
select()
无论如何,在我的套接字代码中。它对套接字发生的事情提供了细粒度的控制。
import threading
import pygame
import random
import enum
import socket
import select
import time
class ConversationHandlerThread( threading.Thread ):
""" A thread that handles a conversation with a single remote server.
Accepts commands of 'close', 'red', 'green' or 'blue', and posts messages
to the main PyGame thread for processing """
def __init__( self, server_address, server_port ):
threading.Thread.__init__(self)
self.server_address = server_address
self.server_port = server_port
self.server_socket = None
self.data_buffer = ''
self.daemon = True # exit with parent
self.done = False
def stop( self ):
self.done = True
def connect( self ):
self.server_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
while True:
try:
self.server_socket.connect( ( self.server_address, self.server_port ) )
print( "Connected to %s:%d" % ( self.server_address, self.server_port ) )
break;
except:
print( "Failed to connect %s:%d" % ( self.server_address, self.server_port ) )
time.sleep( 12 )
print( "Retrying..." )
def run( self ):
""" Connects to Server, then Loops until the server hangs-up """
self.connect()
# Now we're connected, start reading commands
read_events_on = [ self.server_socket ]
while ( not self.done ):
# Wait for incoming data, or errors, or 0.3 seconds
(read_list, write_list, except_list) = select.select( read_events_on, [], [], 0.5 )
if ( len( read_list ) > 0 ):
# New data arrived, read it
incoming = self.server_socket.recv( 8192 )
if ( len(incoming) == 0):
# Socket has closed
new_event = pygame.event.Event( NetworkEvents.EVENT_HANGUP, { "address" : self.server_address } )
pygame.event.post( new_event )
self.server_socket.close()
self.done = True
else:
# Data has arrived
try:
new_str = incoming.decode('utf-8')
self.data_buffer += new_str
except:
pass # don't understand buffer
# Parse incoming message (trivial parser, not high quality)
# commands are '\n' separated
if (self.data_buffer.find('\n') != -1 ):
for line in self.data_buffer.split('\n'):
line = line.strip()
# client disconnect command
if ( line == 'close' ):
new_event = pygame.event.Event( NetworkEvents.EVENT_HANGUP, { "address" : self.server_address } )
pygame.event.post( new_event )
self.server_socket.close()
self.done = True
# only make events for valid commands
elif ( line in ( 'red', 'green', 'blue' ) ):
new_event = pygame.event.Event( NetworkEvents.EVENT_MESSAGE, { "address" : self.server_address, "message" : line } )
pygame.event.post( new_event )
self.data_buffer = '' # all used-up
# Start the network-handler thread
thread1 = ConversationHandlerThread( '127.0.0.1', 5555 )
thread1.start()
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == NetworkEvents.EVENT_HANGUP ):
print(" CLIENT DISCONNECTED %s " % ( str(event.address) ) )
elif ( event.type == NetworkEvents.EVENT_MESSAGE ):
print(" CLIENT MESSAGE FROM %s - %s " % ( str(event.address), event.message ) )
if ( event.message == 'red' ):
new_sprite = AlienSprite( RED )
SPRITES.add( new_sprite )
关于python - 多人游戏中的 Pygame 和套接字 : OverflowError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60884259/
我刚开始学习用 Python 编写代码。我正在尝试编写一些代码来回答这个欧拉项目问题: 13195 的质因数是 5、7、13 和 29。 数 600851475143 的最大质因数是多少? 我的程序适
根据python文档 exception OverflowError Raised when the result of an arithmetic operation is too larg
当我尝试这个计算时,我得到一个溢出错误,但我不知道为什么。 1-math.exp(-4*1000000*-0.0641515994108) 最佳答案 您要求 math.exp 计算的数字(十进制)超过
最后一天,解决另一个Project Euler我在管理 big for i in range(n) 循环时遇到了麻烦。 我观察到 python 会抛出不同的错误,取决于 x 变量有多大。 这是一个mc
我有一个返回 log10 值的函数。在将它们转换为正常数字时,出现溢出错误。 OverflowError: (34, 'Numerical result out of range') 我检查了日志值,
我正在使用 cartopy 绘制一些 map 。在某些情况下,在我的轴上调用 .set_extent() 时,出现此错误: Traceback (most recent call last): F
我正在尝试使用 pygame 在 Python 中创建一个简单的多人游戏和 socket模块。它只是由两个圆圈组成,由两台不同计算机的 W、A、S、D 键控制。 起初我用 recv() 创建了一个客户
我想模拟一个 OverflowError 因为我想在引发异常之后测试变量的值。但是,我不知道如何使用我正在使用的库复制 OverflowError。我在此特定测试中使用的库是 pysolar.sola
尝试在您的 Python 3.3.2 IDLE 中输入这个,希望我不是唯一想知道并且愿意理解为什么会发生这种情况的人。 >>> n = 331 >>> d = 165.0 # float number
我是 Python 的新手,我遇到了这个问题: 追溯(最近的调用最后): b = 1-exp(n)*erfc(n**0.5) OverflowError:数学范围错误 我需要为不断增加的“n”值计算“
我为一个板设置了一个简单的 MDP,它有 4 种可能的状态和 4 种可能的操作。棋盘和奖励设置如下: 这里,S4 是目标状态,S2 是吸收状态。我在编写的代码中定义了转移概率矩阵和奖励矩阵,以获得该
我正在尝试将大小为 n 位的 int 转换为字节。这将返回溢出错误 尝试将 int 转换为字节以便稍后通过 TCP 使用 def diffie_hellman(): global a,g,n
x=float(raw_input('Enter a number to show its square root')) precise = 0.01 g=x/2.0 while abs(g**2-x
我想找出这里的模式: >>> 1e300 ** 2 OverflowError: (34, 'Result too large') >>> 1e300j ** 2 OverflowError: com
对于一项作业,我们被要求创建一个返回反函数的函数。基本问题是从平方函数创建平方根函数。我想出了一个使用二进制搜索的解决方案和另一个使用牛顿法的解决方案。我的解决方案似乎适用于立方根和平方根,但不适用于
在发这个问题之前,我检查了所有可能重复的问题,尝试了所有的方法仍然无法解决问题。 我在 matplotlib 中有一个简单的绘图。当我注释掉调用 plt.fill_between() 的行时,代码可以
我想写一个函数来计算 (1/n!) * (1! + 2! + 3! + ... + n!) ,其中 n 作为函数的参数,结果也被截断为6 位小数(不四舍五入)。下面是我的代码: def going(n
我正在尝试通过以下代码行在 64 位 Windows 系统上的 Python 2.7 中生成随机数: random_state=numpy_rng.random_integers(1e10) 但我收到
我正在尝试序列化一个大型 python 对象,该对象由使用 pickle/cPickle 和 gzip 的 numpy 数组元组组成。该过程适用于特定大小的数据,之后我收到以下错误: --> 121
我想做什么 我正在使用 PyArrow读取一些 CSV 并将它们转换为 Parquet。我阅读的一些文件有很多列并且占用大量内存(足以使运行该作业的机器崩溃),因此我正在分块读取文件。 这就是我用来生
我是一名优秀的程序员,十分优秀!