Python 滚动对象是不稳定的,有时会向右跳几个像素[pygame]

Python 滚动对象是不稳定的,有时会向右跳几个像素[pygame],python,pygame,Python,Pygame,为了为原型创建一个抽象的、滚动的城市天际线,我创建了一个生成随机矩形的类。这些矩形被添加到一个列表中,并从该列表中提取要在屏幕上绘制的项目。矩形从屏幕右侧开始,然后向左滚动,直到它们离开视图平面并被丢弃。建筑物的运动异常剧烈,它们在屏幕上的某个特定点向右移动了几个像素 原型的这段视频相当准确,几乎没有视频捕获延迟。请注意建筑物之间的间隙,当它们位于显示区域最右侧的三分之一范围内时,间隙将突然缩小,就像间隙左侧的建筑物突然向右移动了几个像素一样。间隙越小,越明显。视频中的其他异常来自录像机,应用程

为了为原型创建一个抽象的、滚动的城市天际线,我创建了一个生成随机矩形的类。这些矩形被添加到一个列表中,并从该列表中提取要在屏幕上绘制的项目。矩形从屏幕右侧开始,然后向左滚动,直到它们离开视图平面并被丢弃。建筑物的运动异常剧烈,它们在屏幕上的某个特定点向右移动了几个像素

原型的这段视频相当准确,几乎没有视频捕获延迟。请注意建筑物之间的间隙,当它们位于显示区域最右侧的三分之一范围内时,间隙将突然缩小,就像间隙左侧的建筑物突然向右移动了几个像素一样。间隙越小,越明显。视频中的其他异常来自录像机,应用程序中不存在。下面是一段非常简短的视频,清楚地显示了这种现象:

在大约1秒的时间里,你会注意到后面一层的建筑之间有一个非常窄的间隙。在:04秒时,间隙与蓝色玩家对象相等,左侧矩形移动,间隙消失。在右边有第二个更大的间隙,它做同样的事情,但由于间隙更大,它并没有完全消失。我已经查看了代码很多次,但看不出是什么导致了这种异常。我希望有人能告诉我这是我做的事还是我遇到的限制

我最初是线性编写这个程序的,没有类或函数。我使用一个类重写了它,该类生成图层对象并处理所有的生成和滚动。在这两种情况下,问题都存在。想弄明白为什么这些建筑不能平稳移动,我简直快疯了。我甚至使用png图像而不是随机生成的矩形编写了一个版本。在该版本中,PNG平滑无缝地滚动:(视频有点抖动,但实际程序播放平稳),因此问题仅限于这些随机矩形

以下是该程序的代码:

下面是类代码本身:

class Scroller():
    def __init__(self, speed, color, heightMax):
        # Speed of the layer scroll, the color of the layer and the maximum height for buildings
        # set up the building parameters
        self.buildingHeightMax = heightMax
        self.buildingHeightMin = 100
        self.buildingWidthMax = 125
        self.buildingWidthMin = 75
        self.buildings = []
        self.layerspeed = speed
        self.buildTime = True
        self.buildCountdown = 10
        self.color = color

    def update(self):
        # Check if it's time to build. If not, decrement counter
        if self.buildTime == False:
            self.buildCountdown -= 1
            # If time is 0, time to build, reset counter to a new random time
            if self.buildCountdown <= 0:
                self.buildTime = True
                self.buildCountdown = random.randint(3, self.layerspeed)

        # create building if it's time
        if self.buildTime:
            # generate random width and height of building
            buildingHeight = random.randint(self.buildingHeightMin, self.buildingHeightMax)
            buildingWidth = random.randint(self.buildingWidthMin, self.buildingWidthMax)
            buildingTop = WINDOWHEIGHT - buildingHeight
            # This generates the building object from the above parameters
            building = pygame.Rect(WINDOWWIDTH, buildingTop, buildingWidth, WINDOWHEIGHT)
            self.buildTime = False
            self.buildCountdown = random.randint(3, self.layerspeed * 5)
            # add building to buildings list
            self.buildings.append(building)

        # move all buildings on layer at set speed
        for building in self.buildings:
            # if the building is off the screen, trash it. If not, move it to the
            # right at the objects speed.
            if building.right < 0:
                self.buildings.remove(building)
            else:
                building.left -= self.layerspeed

        # draw the Front buildings
        for i in range(len(self.buildings)):
            pygame.draw.rect(windowSurface, self.color, self.buildings[i])
class Scroller():
定义初始值(自身、速度、颜色、最大高度):
#图层滚动速度、图层颜色和建筑物的最大高度
#设置建筑参数
self.buildingHeightMax=heightMax
自构建权重分钟=100
self.buildingWidthMax=125
自构建宽度最小值=75
self.buildings=[]
self.layer速度=速度
self.buildTime=True
self.buildCountdown=10
self.color=颜色
def更新(自我):
#检查是否是构建的时候了。如果不是,减量计数器
如果self.buildTime==False:
self.buildCountdown-=1
#如果时间为0,则为构建时间,将计数器重置为新的随机时间

如果self.buildCountdown您的问题很可能在于:

    # move all buildings on layer at set speed
    for building in self.buildings:
        # if the building is off the screen, trash it. If not, move it to the
        # right at the objects speed.
        if building.right < 0:
            self.buildings.remove(building)
        else:
            building.left -= self.layerspeed
试试看,你会发现不仅
4
不会被打印,而且
1.5
也会被跳过

可能一个很好的方法是首先遍历所有的建筑,看看哪些需要移除,然后移除所有,最后移除所有剩余的建筑。
你可能想要一些好的建议


您还将更新两次倒计时,第一次在第47行,然后在第58行。有什么原因吗?

太棒了!我不知道这个列表操作。你是对的,我将
building.left-=self.layerspeed
移出了移除死掉建筑的循环,并将其放入一个连续的单独循环中,现在一切都顺利运行。谢谢你的教育。你问我为什么要设置两次计数器,那是个错误。谢谢除了生成一个新的随机数之外,它实际上不会影响任何东西,但它肯定不是必需的。
a = [2, 3, 4, 1.5, 6, 8, 3.2]

for element in a:
    if element == 4:
        a.remove(element)
    else:
        print element