为什么我的角色在我添加背景时忽略了时钟滴答声?

Why is my character ignoring the clock tick when i add the background?

这就是我没有背景时会发生的事情: https://www.youtube.com/watch?v=S-bv-j8le24

这是代码:

import pygame

pygame.init()

#####Variables#####

white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
gameWindowWidth = 1280
gameWindowHeight = 720
gameRunning = True
clock = pygame.time.Clock()

###################

#####Loading#####

ninja01 = pygame.image.load("C:\Users\Tom\Desktop\gameImages\charSprite\s_Idle__000.png")
background = pygame.image.load("C:\Users\Tom\Desktop\gameImages\Background\DistantCity\PNG\m_image.png")

#################

#####Classes#####

class player():
    def __init__(self):
        self.playerX = gameWindowWidth * 0.2
        self.playerY = gameWindowHeight * 0.8
        self.changeOnX = 0

    def changingX(self):
        if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            self.changeOnX = 5
        if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            self.changeOnX = -5
        if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
            self.changeOnX = 0
        if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
            self.changeOnX = 0

    def move(self):
        self.playerX = self.playerX + self.changeOnX

        gameWindow.blit(ninja01, (self.playerX, self.playerY))


################

ninja = player()
gameWindow = pygame.display.set_mode((gameWindowWidth, gameWindowHeight))
pygame.display.set_caption("Platformer Game")

while gameRunning == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False


    #gameWindow.blit(background, (0, 0))
    ninja.changingX()
    ninja.move()
    pygame.display.update()
    clock.tick(144)

这就是当我有背景时会发生的事情: https://www.youtube.com/watch?v=l89zZQ_8kzg

这是代码:

import pygame

pygame.init()

#####Variables#####

white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
gameWindowWidth = 1280
gameWindowHeight = 720
gameRunning = True
clock = pygame.time.Clock()

###################

#####Loading#####

ninja01 = pygame.image.load("C:\Users\Tom\Desktop\gameImages\charSprite\s_Idle__000.png")
background = pygame.image.load("C:\Users\Tom\Desktop\gameImages\Background\DistantCity\PNG\m_image.png")

#################

#####Classes#####

class player():
    def __init__(self):
        self.playerX = gameWindowWidth * 0.2
        self.playerY = gameWindowHeight * 0.8
        self.changeOnX = 0

    def changingX(self):
        if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            self.changeOnX = 5
        if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            self.changeOnX = -5
        if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
            self.changeOnX = 0
        if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
            self.changeOnX = 0

    def move(self):
        self.playerX = self.playerX + self.changeOnX

        gameWindow.blit(ninja01, (self.playerX, self.playerY))


################

ninja = player()
gameWindow = pygame.display.set_mode((gameWindowWidth, gameWindowHeight))
pygame.display.set_caption("Platformer Game")

while gameRunning == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False


    gameWindow.blit(background, (0, 0))
    ninja.changingX()
    ninja.move()
    pygame.display.update()
    clock.tick(144)

除了第一个注释掉 "gameWindow.blit(background, (0, 0))" 之外,代码完全相同。

我的问题是为什么添加背景后我的角色运行速度变慢了?

同样在第二个中,他的移动速度不会改变,直到我将 clock.tick 降低到 30 左右及以下。

clock.tick(144) 表示如果渲染速度快于 144 fps 可能会暂停。由于帧率足够高,而且渲染仍然需要足够长的时间,也许 clock.tick 会立即返回,不需要延迟。

所以当你在背景中绘制时,渲染肯定不会更快,所以它仍然足够慢 clock.tick returns 立即。除了现在渲染有点慢,所以你注意到渲染的延迟。

你所有整个游戏循环的时间都是由Clock.tick方法控制的。因此,您每帧只需 运行 一次输入和位置更新代码。你拥有的精灵越多,它就越能减慢这个循环,这就是你在包含背景时所观察到的。您可以将输入和更新逻辑的时间与渲染周期分开,这将解决您的问题。考虑我在下面执行的重构:

import pygame

pygame.init()

#####Variables#####

white = (255,255,255)
black = (0,0,0)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
gameWindowWidth = 1280
gameWindowHeight = 720
gameRunning = True
clock = pygame.time.Clock()

###################

#####Loading#####

ninja01 = pygame.image.load("/path/to/your/ninja/sprite")
background = pygame.image.load("/path/to/your/background/sprite")

#################

#####Classes#####

class player():
    def __init__(self):
        self.playerX = gameWindowWidth * 0.2
        self.playerY = gameWindowHeight * 0.8
        self.velocity = 0.0

    def setVelocity(self, velocity):
        self.velocity = velocity

    def update(self, dt):
        self.playerX += self.velocity * dt

    def draw(self):
        gameWindow.blit(ninja01, (self.playerX, self.playerY))


################

ninja = player()
gameWindow = pygame.display.set_mode((gameWindowWidth, gameWindowHeight))
pygame.display.set_caption("Platformer Game")

fps = 60
target_frame_time = 1.0 / fps
current_frame_time = 0.0

while gameRunning == True:
    dt = clock.tick()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameRunning = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            ninja.setVelocity(1)
        if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            ninja.setVelocity(-1)
        if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
            ninja.setVelocity(0)
        if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
            ninja.setVelocity(0)

    ninja.update(dt)

    current_frame_time += dt

    if current_frame_time >= target_frame_time:
        gameWindow.blit(background, (0, 0))
        ninja.draw()

        pygame.display.flip()

        current_frame_time -= target_frame_time

在忍者上调用更新时,使用以下公式计算位置:

distance = velocity * time

通过这些代码更改,您现在可以在输入和游戏更新逻辑持续 运行 的同时实现一致的帧速率。