2

我正在尝试使用适用于 Python 2.7 的新 Minecraft Pi Edition API 编写游戏。当我意识到两段代码相互阻塞时,我几乎完成了游戏。如果我将 A 部分放在首位,它将阻止 B 部分运行,直到 A 部分完成。如果我把 B 部分放在首位,它会运行得很慢。我决定需要将这两个部分分成两个单独的线程。'

这是仍然存在问题的代码的缩减版本。我注意到,如果我注释掉ClassName.start()两个类之一的行,另一个类将运行而不会出错。

import mcpi.minecraft as minecraft
import threading

mc = minecraft.Minecraft.create()

class BlockCheckThread(threading.Thread):
    def run(self):
        while True:
            event = mc.events.pollBlockHits()

class WinningCheckThread(threading.Thread):
    def run(self):
        while True:
            blockTest = mc.getBlock(1, 1, 1,) == 50

def main():
    WinningCheckThread().start() # If I comment out either of these .start() lines
    BlockCheckThread().start()   # the other class executes perfectly.

运行它的错误如下:

Exception in thread Thread-2:
...
TypeError: Hit() takes exactly 5 arguments (1 given)

Exception in thread Thread-1:
...
ValueError: invalid literal for int() with base 10: '

要运行代码,您需要一个 Raspberry Pi,并且需要从此处api/python/下载 Minecraft,然后您必须从目录中运行它。(即它必须与mcpi它正在导入的模块位于同一文件夹中。)

这是我第一次尝试线程,所以不要对我的代码笑得太厉害。我很想知道为什么这段代码不起作用,以及我应该做些什么来修复它。

4

2 回答 2

4

您正在共享该Minecraft对象,它不是线程安全的。该Minecraft对象只是一个客户端库,用于连接以命令启动的 Minecraft 服务器minecraft-pi。您需要Minecraft为每个线程创建一个对象,它应该没问题:

import mcpi.minecraft as minecraft
import threading

class BlockCheckThread(threading.Thread):
    def run(self):
        mc = minecraft.Minecraft.create()
        while True:
            event = mc.events.pollBlockHits()

class WinningCheckThread(threading.Thread):
    def run(self):
        mc = minecraft.Minecraft.create()
        while True:
            blockTest = mc.getBlock(1, 1, 1,) == 50

def main():
    WinningCheckThread().start() 
    BlockCheckThread().start()   
于 2013-02-12T15:23:04.860 回答
3

Pi 版的 Python Minecraft 客户端不是线程安全的。发生的情况是两个线程同时发送和接收数据。当响应混淆时(即BlockCheckThread获取对请求的响应,WinningCheckThread反之亦然),消息格式与线程期望得到的不匹配。

您可以简单地锁定每次调用 Minecraft 客户端,以确保您一次只发送和接收一个项目。

我不知道 Minecraft 服务器是否支持它,但你也可以发送多个请求。为此,您需要一个管理器类来跟踪未完成请求的顺序。

于 2013-02-12T15:11:57.420 回答