gpt4 book ai didi

python - 重组程序以使用 asyncio

转载 作者:太空宇宙 更新时间:2023-11-04 01:08:41 26 4
gpt4 key购买 nike

目前我有一个使用 socket 模块同步联网的游戏。

它的结构是这样的:

服务器:

while True:
add_new_clients()
process_game_state()
for client in clients:
send_data(client)
get_data_from(client)

客户:

connect_to_server()
while True:
get_data_from_server()
process_game_state()
draw_to_screen()
send_input_to_server()

我想用一些使用比 socket 更高级的模块来替换网络代码,例如asyncio 或 gevent。但是,我不知道该怎么做。

我见过的所有例子都是这样构造的:

class Server:
def handle_client(self, connection):
while True:
input = get_input(connection)
output = process(input)
send(connection, output)

然后 handle_client 被并行调用,使用线程或其他东西,为每个加入的客户端。

如果可以单独处理客户端,则此方法工作正常。但是,我仍然想保留一个游戏循环类型的结构,其中只在一种情况下进行处理——我不想为每个客户端检查碰撞等。我该怎么做?

最佳答案

我假设您了解如何使用协议(protocol)创建服务器以及异步范例的工作原理。

您只需将您的 while 事件循环分解处理程序

让我们看看服务器案例和客户端案例:

服务器案例

客户端(服务器端)

您需要创建一个我们称之为协议(protocol)的东西,它将用于创建服务器并用作每个实例 = 一个客户端的模式:

class ClientProtocol(asyncio.Protocol):
def connection_made(self, transport):
# Here, we have a new player, the transport represent a socket.
self.transport = transport


def data_received(self, data):
packet = decode_packet(data) # some function for reading packets
if packet.opcode == CMSG_MOVE: # opcode is a operation code.
self.player.move(packet[0]) # packet[0] is the first "real" data.
self.transport.write("OK YOUR MOVE IS ACCEPTED") # Send back confirmation or whatever.

好的,现在您已经了解了如何与客户合作。

游戏状态

之后,您需要每 X 毫秒处理一次游戏状态:

def processGameState():
# some code...
eventLoop.call_later(0.1, processGameState) # every 100 ms, processGameState is called.

在某些时候,您将在初始化中调用 processGameState,它会告诉 eventLoop 在 100 毫秒后调用 processGameState(这可能不是理想的方法,但它是一个类似的想法 )

至于向客户端发送新数据,你只需要存储一个列表 ClientProtocol并为每个人写一个简单的传输。

get_data_from 显然被删除了,因为我们在 data_received 中异步接收所有数据。 ClientProtocol 的方法.

这是关于如何将所有同步代码重构为异步代码的草图。您可能想要添加身份验证和其他一些东西,如果这是您第一次使用异步范例,我建议您尝试使用 Twisted 而不是 asyncio 来完成它:Twisted 可能比 asyncio 在任何地方都有更多的文档和解释(但 asyncio与 Twisted 完全相同,因此您每次都可以切换回来)。

客户案例

这里也差不多。

但是,您可能需要注意您的绘图方式和管理输入的方式。您最终可能需要使用另一个线程来调用输入处理程序,并使用另一个线程以恒定的帧速率绘制到屏幕。

结论

开始时以异步方式思考非常困难。

但这是值得的。

请注意,即使是我的方法也可能不是最好的或不适合游戏。我只是觉得我会那样做,请花点时间测试您的代码并对其进行分析。检查您是否在未使用 deferToThread(或其他助手)进行适当处理的情况下,在同一函数中混契约(Contract)步和异步代码,这会破坏您游戏的性能.

关于python - 重组程序以使用 asyncio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28997833/

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