用Pygame进行基本网络编程

22

我需要为Pygame项目做一些基本的网络编程。

基本上,这是一个2D单人或合作游戏。网络编程只需要支持两个玩家,其中一个是主机。

唯一需要发送的信息是玩家、小兵和子弹的位置。

我查阅了一些资料,Twisted 似乎是一个不错的选择,但我从未做过网络编程,也不确定是否太复杂。

因此,相对新手能否在 Pygame 中实现网络编程?

5个回答

16

这个问题最近在 Reddit 上被问到了,所以我更多地是从那里复制我的答案。很抱歉我不能提供更多的链接,因为我只有不到10的声望,所以一次只能发布两个链接。

Twisted 可能可行,但我没有太多的经验。我建议使用 sockets,因为这就是 Twisted 在后台使用的。Beej 的指南(谷歌一下)几乎是 sockets 的圣经,如果你想学习它们的工作原理(用 C++ 编写,但概念适用于任何语言)。Python 确实抽象了一些复杂性,但了解后台发生的事情仍然是一个好主意。

对于 Python 特定的 sockets,你可以直接使用 howto(user745294 上面发布了一个链接)。这里有一篇标题为“每个程序员需要了解的游戏网络”的好文章。它讨论了不同类型的主要网络风格(客户端-服务器、点对点、UDP v. TCP 等)以及一些主要游戏在其网络方面使用的历史背景。

下面是我在Python 2.6/Pygame中制作网络“游戏”时做的演示链接。它实际上不是一款游戏,但你创建的每个客户端都连接到服务器并控制一个角色。你可以使用箭头键移动你的角色,角色将在所有连接的客户端上移动。我试图用一些注释来说明我正在发送和接收的内容,但你可能需要一些关于套接字的知识才能理解它。
源代码在此帖子下方的codepad链接中提供。你需要在与脚本相同的目录中提供两个图像:
1. bg.png是背景精灵。它应该是400像素宽、300像素高的图像(如果需要,可以在GameClient类中更改)。 2. sprite.png是玩家角色。它应该比背景小,这样你就可以看到它在移动了。

以下是一些 Codepad 链接,如果您不想访问 Mediafire 的话可以使用(您需要提供自己的 bg.png 和 sprite.png)。 服务器:http://codepad.org/p9lVrmqn 客户端:http://codepad.org/e6pwGj24 - nemec
1
无论如何,mediafire链接已经失效了。不过codepad的链接很好,谢谢! - John T
嗨,我知道这已经过时了,但mediafire链接已经失效了。如果你仍然有源代码,我非常感兴趣! - Jackpy
源代码已在上方评论的Codepad链接中提供。只在Mediafire中增加了两个图像:bg.png(背景)和sprite.png(玩家角色)。请提供自己的两个图像(我已经没有它们了),代码将正常工作。 - nemec
@nemec 当我尝试从codepad链接复制代码并创建一些图像时,我收到了几个python1/3冲突错误。当我修复这些错误后,又收到了另一个错误:ConnectionResetError: [WinError 10054] 远程主机强制关闭了一个现有的连接。我在这里做错了什么吗? - Patlatus
显示剩余2条评论

7

您可以使用Twisted来进行Pygame的网络编程。在Launchpad上的“game”项目中,有一些示例可以展示如何将主循环集成起来;基本上,您可以使用twisted.internet.task.LoopingCall来绘制Pygame帧并处理输入,同时让您选择的Twisted反应器正常运行。


2

1
Mastermind使用pickle是不安全的。警告:pickle模块不安全,容易受到错误或恶意构造的数据攻击。永远不要从不受信任或未经身份验证的来源反序列化数据。 - skrx
作者已更改库,现在默认使用 JSON,这是安全的。 - skrx

0

1
请勿在任何不受信任的通信中使用Pyro。它绝对不适用于通过互联网进行的游戏。http://packages.python.org/Pyro4/security.html#pickle-as-serialization-format - Glyph
我承认这不是最好的使用案例,谢谢指出。 - Tshirtman
链接已经失效: "404. 未找到。请求的URL在该服务器上未被找到。" - Peter Mortensen

0

使用原始套接字是低级且充满危险的。如前所述,Twisted 是复杂的,并需要时间来启动和运行。为了避免一些头疼的问题,我建议尝试使用像 zerorpc 这样的东西。

你需要以下解决方案:

  • 发现(本地)网络上的其他玩家,你不想让玩家输入某个 IP 地址
  • 处理网络错误
  • 序列化包含数据(位置、玩家名称等)的消息
  • 处理线程,因为网络是异步 I/O

以上应该仍然被称为“基础”,你应该真正使用一些带有惯用 API 的花哨的网络库。

实质上,你需要公开网络服务(在其自己的线程中),该服务将推送消息到 Python 的 Queue,然后从你的 Pygame 代码访问此相同的队列,如果有消息,则更新你用于存储玩家位置并在屏幕上绘制它的任何结构。

你不应该像发送子弹位置这样的东西通过网络发送,因为它们可以在本地轻松(且更快地)计算。你只需通过网络发送一个事件,例如 bullet_shot,带有源位置和速度向量。


2
Twisted并不是非常复杂的。一个回声服务器只需要3行代码。一个双向RPC服务器也不比它多。虽然Twisted是一个通用的网络解决方案,适用于游戏客户端,但zerorpc依赖于zeromq,因此不适合不可信的客户端通信;它更多地用于协调后端服务之间的通信。 - Glyph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接