游戏中none是哪个键(跟着一起写一个多人在线游戏(二))

编程派微信号:这篇文章来自Kyrylo Subbotin,他是IT咨询公司的Python工程师。我们的译者sleepyjoker目前是东南大学电子科学与工程专业大二的学生,虽然他对Python还处于学习阶段,但他喜欢通过代码完成各种有趣的任务。这篇文章经过编程派作者EarlGrey的校对。
接下来,我们将探讨如何编写游戏中的循环。
游戏循环是任何游戏的核心组成部分。它不断地接收玩家的输入,更新游戏状态,并将结果渲染到屏幕上。对于在线游戏来说,这个循环被划分为服务端和客户端两部分,它们通过网络进行通信。通常,客户端负责获取玩家的输入,例如按键或鼠标移动,然后将这些数据传递给服务器,并将从服务器返回的数据展示给玩家。服务器则处理所有玩家的数据,更新每个玩家的状态,进行必要的计算以渲染下一帧画面,然后将结果(例如游戏对象的新位置)返回给客户端。必须明确区分服务器和客户端的功能,避免混淆。如果游戏的逻辑计算被置于客户端,那么将无法与其他客户端同步,而且游戏将容易受到数据篡改的影响。
游戏中的循环迭代通常被称为“tick”。每次“tick”表示当前循环迭代已经完成,下一帧的数据已经准备好。
下面是一个使用WebSocket连接服务器的客户端示例。客户端运行一个简单的循环,将按键信息传递给服务器,并展示从服务器接收的所有数据。点击查看客户端源代码。
例3.1:基本游戏循环
以下是服务器的运行方式:
web.run_app是一个方便的快捷方式,可以快速创建服务器的务,并使用其run_forever()方法运行asyncio事件循环。建议你查看这个方法的源代码,了解服务器是如何建立和终止的。
app是一个类似字典的对象,用于在连接的客户端之间共享数据。我们将用它来存储套接字列表,这个列表将用于向所有已连接的客户端发送消息。通过调用函数asyncio.ensure_future(),我们可以安排每两秒向客户端发送一次“tick”信号的主循环game_loop任务。这个任务将在与网络服务器相同的asyncio事件循环中并发执行。
在启动的任务中,我们在asyncio的主事件循环中运行工作者线程。当一个工作者使用await语句等待协程完成时,就会切换到另一个工作者任务。例如,经过一段时间后,asyncio.sleep会将执行权交还给调度器,而ws.receive()则会等待来自套接字的信息。在此期间,调度器会切换到其他任务。当你在浏览器中打开主页并连接到服务器后,可以尝试按键。你按下的键对应的字符编码将由服务器输出并返回给客户端的消息每两秒由游戏循环中的“tick”触发。
