gpt4 book ai didi

python - Pygame:使用 time.sleep 延迟轮询 REST 响应的函数会卡住游戏窗口

转载 作者:行者123 更新时间:2023-12-01 06:30:15 27 4
gpt4 key购买 nike

我实际上正在编写一个多用户 pygame 游戏,其中客户端通过 REST 请求与服务器进行通信。我有一个功能,游戏必须等到另一个玩家进入服务器上的“队列”才能开始新游戏。我通过使用 get-Request (通过请求完成)轮询服务器来完成此操作,中间有 time.sleep-delay 。但这次 time.sleep 也会导致我的游戏循环停止,并在等待时卡住我的游戏窗口。但我想让用户在等待期间离开游戏队列。这是不可能的,因为我的屏幕被卡住并变成“离开队列”对话框未显示,并且用户无法单击此按钮,甚至无法单击右上角的“x”来离开队列。

我已经尝试将轮询功能作为线程启动,但这并不能解决屏幕卡住/游戏循环停止的问题。

最佳答案

关于如何实现这项工作的几个关键点:

  • 在线程中处理所有套接字 I/O
  • 发送 Pygame Events当套接字事件发生时返回主循环
  • 不要休眠或延迟你的主要 pygame 事件循环。曾经。

这是一个 Socket-Listener 线程示例,它将事件发送回主 pygame 线程。我对代码的长度表示歉意,但我想用一些功能完整的东西来回答。

import threading
import pygame
import random
import enum
import socket
import select
import time


### Event types that are sent to the main event loop
class NetworkEvents( enum.IntEnum ):
EVENT_HANGUP = pygame.USEREVENT + 1
EVENT_COMMAND = pygame.USEREVENT + 2


### Socket-listener thread that reads commands from the server
### and does the parsing and posting of commands to the main event-loop
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 ) )
break;
except:
print( "Failed to connect %s:%d, will retry" % ( self.server_address, self.server_port ) )
time.sleep( 12 )

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.5 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 command in self.data_buffer.split('\n'):
command = line.strip()
# client disconnect command
if ( command == '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 ( command in ( 'red', 'green', 'blue' ) ):
new_event = pygame.event.Event( NetworkEvents.EVENT_COMMAND, { "address" : self.server_address, "message" : command } )
pygame.event.post( new_event )
self.data_buffer = '' # all used-up


### MAIN

# Start the connection-listener thread
thread1 = ConversationHandlerThread( '127.0.0.1', 5555 )
thread1.start()

一旦线程运行,就会在主循环中接收事件,就像任何其他 PyGame 事件一样:

# Main paint / update / event loop
done = False
while ( not done ):
SPRITES.update()

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_COMMAND ):
print(" CLIENT MESSAGE FROM %s - %s " % ( str(event.address), event.message ) )
if ( event.message == 'red' ):
new_sprite = AlienSprite( RED )
SPRITES.add( new_sprite )
# ... etc.

如果您的套接字 I/O 在线程中处理,并且主事件循环从不休眠,您应该能够使用 PyGame 制作一个流畅的程序。保持您的网络流量小而简洁。

关于python - Pygame:使用 time.sleep 延迟轮询 REST 响应的函数会卡住游戏窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59947751/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com