当图像在屏幕顶部重新生成时,无缝滚动有问题

Having trouble with seamless scrolling when images regenerate at top of screen

所以我不明白为什么在显示屏顶部重新生成时我无法让图像保持连接和无缝。一旦 rect.top 到达底部 (600),我让它们都回到顶部 (rect.bottom = 0)。根据我的速度,他们会做一些有趣的事情,比如先分开,然后在屏幕顶部一起滑动,或者最终在它们之间形成一致的 space。

任何帮助将不胜感激,或者我可以将图像放在同一个 class 并让它在屏幕上重复 6 次并移动它们,这样我就不必做 6 条不同的路 class是的。

import pygame
from pygame.locals import *
import sys
import os

W, H = 800, 600
HW, HH = W / 2, H / 2
AREA = W * H
os.environ['SDL_VIDEO_WINDOW_POS'] = "50,50"
FPS = 30
GREEN = (0, 200, 0)

def events():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

class Road1(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        bkgrnd = pygame.image.load("Images/Road.png").convert_alpha()
        self.image = pygame.transform.scale(bkgrnd, (300, 100))
        self.rect = self.image.get_rect()
        self.rect.x = 100
        self.rect.top = 0
        self.speedy = 0

    def update(self):
        self.rect.top += self.speedy
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.speedy += 0.25
        if keys[pygame.K_s]:
            self.speedy -= 0.25
        if self.speedy <= 0:
            self.speedy = 0
        if self.speedy >= 20:
            self.speedy = 20
        if self.rect.top >= 600:
            self.rect.x = 100
            self.rect.bottom = 0

class Road2(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        bkgrnd = pygame.image.load("Images/Road.png").convert_alpha()
        self.image = pygame.transform.scale(bkgrnd, (300, 100))
        self.rect = self.image.get_rect()
        self.rect.x = 100
        self.rect.top = 100
        self.speedy = 0

    def update(self):
        self.rect.top += self.speedy
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.speedy += 0.25
        if keys[pygame.K_s]:
            self.speedy -= 0.25
        if self.speedy <= 0:
            self.speedy = 0
        if self.speedy >= 20:
            self.speedy = 20
        if self.rect.top >= 600:
            self.rect.x = 100
            self.rect.bottom = 0

pygame.init()
CLOCK = pygame.time.Clock()
DS = pygame.display.set_mode((W, H))
pygame.display.set_caption("Scrolling")

all_sprites = pygame.sprite.Group()
road = pygame.sprite.Group()
rd1 = Road1()
all_sprites.add(rd1)
road.add(rd1)
rd2 = Road2()
all_sprites.add(rd2)
road.add(rd2)

while True:
    CLOCK.tick(FPS)
    events()
    all_sprites.update()
    DS.fill(GREEN)
    all_sprites.draw(DS)
    pygame.display.flip()

如果 "street" 在底部的 window 之外,它的顶部位置不正好是 600,它比 600 大一点。要保持街道对齐彼此,您必须将街道的顶部更改为 window:

的高度
class Road1(pygame.sprite.Sprite):
    # [...]

    def update(self):
        #[...]
        if self.rect.top >= 600:
            self.rect.x = 100
            self.rect.top = self.rect.top - 600
class Road2(pygame.sprite.Sprite):
    # [...]

    def update(self):
        #[...]
        if self.rect.top >= 600:
            self.rect.x = 100
            self.rect.top = self.rect.top - 600

此外,为街道的每个部分生成单独的 class 绝对是一个糟糕的设计。 类 具有属性,class 的构造函数具有参数。使用它们!街道的各个部分仅在其初始位置上有所不同。这可以是 class Road:

的构造函数的参数
class Road(pygame.sprite.Sprite):
    def __init__(self, top):
        pygame.sprite.Sprite.__init__(self)
        bkgrnd = pygame.image.load("Images/Road.png").convert_alpha()
        self.image = pygame.transform.scale(bkgrnd, (300, 100))
        self.rect = self.image.get_rect()
        self.rect.x = 100
        self.rect.top = top # parameter top
        self.speedy = 0

    def update(self):
        self.rect.top += self.speedy
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.speedy += 0.25
        if keys[pygame.K_s]:
            self.speedy -= 0.25
        if self.speedy <= 0:
            self.speedy = 0
        if self.speedy >= 20:
            self.speedy = 20
        if self.rect.top >= 600:
            self.rect.x = 100
            self.rect.top = self.rect.top - 600
# [...]
rd1 = Road(0)
# [...]
rd2 = Road(100)
# [...]

对于无尽的道路,您需要 7 个元素,其中第一个元素位于 -100。如果必须将元素翻转到开头,则其新位置为 top = top-700.
由于 self.speedy 是一个浮点数,我建议添加一个属性 self.top,它与整数属性 self.rect.top 同步。例如:

class Road(pygame.sprite.Sprite):
    def __init__(self, top):
        pygame.sprite.Sprite.__init__(self)
        bkgrnd = pygame.image.load("Images/Road.png").convert_alpha()
        self.image = pygame.transform.scale(bkgrnd, (300, 100))
        self.rect = self.image.get_rect(topleft = (100, top))
        self.top = top
        self.speedy = 0

    def update(self):
        self.top += self.speedy
        if self.top > 600:
            self.top = self.top - 700
        self.rect.top = self.top

        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.speedy = min(20, self.speedy + 0.25)
        if keys[pygame.K_s]:
            self.speedy = max(0, self.speedy + 0.25)
all_sprites = pygame.sprite.Group()
road = pygame.sprite.Group()
for i in range(7):
    rd = Road((i-1) * 100)
    all_sprites.add(rd)
    road.add(rd)