1

我正在使用 pygame 开发一个火车模拟器(仅使用一个矩形来表示一列火车)我有一个类火车,这个类有一个停止功能来停止每个车站的火车(由 x 坐标定义):

def stop(self):

    current_time = pg.time.get_ticks()

    while pg.time.get_ticks() - current_time < self.stopping_Time:
        continue
    pass

此实现适用于一个火车实例,但我的问题是,当添加更多火车时,如果一个实例停在其车站,所有其他火车实例即使不在车站也停止!

我也尝试过这个实现,但它没有用:

def stop(self):
    while self.stopping_Time> 0:
        self.stopping_Time -= 1
    pass

这个答案对我也不起作用:https ://stackoverflow.com/a/46801334/11334093

是多线程问题吗?我是否需要为每个火车实例创建一个线程,以便它们可以独立执行停止功能?或者我如何为这个功能使用多处理技巧?

这是我的整个火车课:

class train(object):
    """docstring for train"""
    def __init__(self, x, y, width, height, vel):

        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.vel = vel
        self.right = True
        self.left = False
        self.headway = 20
        self.stopping_Time = 2500
        self.capacity = 200
        self.start_time = pg.time.get_ticks()

    def draw(self, win):
        #trains
        pg.draw.rect(win, (255,0,0), (self.x, self.y, self.width, self.height))


    def stop(self):

        self.current_time = pg.time.get_ticks()

        while pg.time.get_ticks() - self.current_time < self.stopping_Time:
            continue
        pass

    def move(self):

        if self.right:

            if self.x == 235 or self.x == 510 or self.x == 1295:

                self.stop()

                if self.x == 1295:
                    self.right = False
                    self.left = True
                    self.x -= self.vel

                else:
                    self.x += self.vel

            else:
                self.x += self.vel 

        else:

            if self.x == 235 or self.x == 510:
                #train.stop = 3 * 100
                self.stop()

                if self.x == 235:
                    self.right = True
                    self.left = False
                    self.x += self.vel

                else:
                    self.x -= self.vel
            else:
                self.x -= self.vel

我还有另一个函数,我在其中调用:

for train in op_trains:
    train.move()

op_train 是一个包含所有列车实例的列表,一次由一列列车填充。

4

1 回答 1

2

我强烈建议不要对您的这个问题使用多线程/处理。虽然多线程/处理可能能够解决您的问题,但引入它可能会使将来难以添加或改进代码,并且很可能会导致更多错误。这个问题可以通过调整代码的设计来解决。

之所以所有列车同时停止,是由于 stop 函数中的 while 循环。

def stop(self):

    current_time = pg.time.get_ticks()

    while pg.time.get_ticks() - current_time < self.stopping_Time:
        continue
    pass

这个 while 循环阻塞了主线程,阻止了 pygame 处理其他火车。stop 函数是从 train 类中的 move 函数调用的。现在的目标是用一种方法来替换这个 while 循环,以跟踪不阻塞主线程的火车停止多长时间。

您需要做的是在您的火车类中有一个状态来表示火车是否停止。

    def __init__(self, x, y, width, height, vel):

        self.x = x
        self.y = y
        self.width = width
        self.height = height

        self.vel = vel
        self.right = True
        self.left = False
        self.headway = 20
        self.stopping_Time = 2500
        self.capacity = 200
        self.start_time = pg.time.get_ticks()
        # new attributes
        self.stopped = False
        self.stopped_time = None

要停止火车,请切换状态并记录停止开始的时间。

    def stop(self):
        self.stopped_time = pg.time.get_ticks()
        self.stopped = True

在你的移动函数中,有一个 if 条件来检查这个标志是否为真,如果是,它停止了多长时间。如果它停止的时间足够长,请将标志设置为 False 并继续前进。我已经继续并重新排序了函数并清理了条件。

    def move(self):
        if self.stopped and pg.time.get_ticks() - self.stopped_time < self.stopping_Time:
                return
        self.stopped = False
        if self.right:
            self.x += self.vel 
        else:
            self.x -= self.vel

        if self.x == 235 or self.x == 510 or self.x == 1295:
            self.stop()

        if self.x == 235:
            self.right = True
            self.left = False
        elif self.x == 1295:
            self.right = False
            self.left = True

请注意,没有循环。

此代码假定您的调用train.move()位于某种主事件循环中,并在该循环中不断被调用。

于 2020-05-11T15:40:54.623 回答