如何让你的角色在不重复点击按钮的情况下移动?

How to make your character move without tapping repeatedly on buttons?

我正在开发一款赛车游戏。我一直在使用此代码,但我的播放器只移动一次。我该如何解决这个问题?

change = 7
dist = 7
change_r = 0
change_l = 0
dist_u = 0
dist_d = 0
pygame.display.update()  


for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_RIGHT:
           change_r = True

        elif event.key == pygame.K_LEFT:
            change_l = True


        elif event.key == pygame.K_UP:
            dist_u = True     

        elif event.key == pygame.K_DOWN:
            dist_d = True



    if event.type == pygame.KEYUP:
        if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT or event.key == pygame.K_UP or event.key == pygame.K_DOWN:
            change_r = False
            change_l = False
            dist_u = False
            dist_d = False
    clock.tick(60)     

    if change_r == True:
        x += change
    if change_l == True:
        x -= change
    if dist_u == True:
        y -= dist
    if dist_d == True:
        y += dist

无论您的事件处理如何,您都应该有一个全局循环。你应该把你的 clock.tick() 和你的动作放在那里。即:

#some constants here
while True:    
    pygame.display.update()  
    clock.tick(60)
    #update you game state
    if change_r == True:
        x += change
    if change_l == True:
        x -= change
    if dist_u == True:
        y -= dist
    if dist_d == True:
        y += dist

    for event in pygame.event.get():
        # react to player input by changing the game state

使用 Pygame 制作可移动 shapes/sprites 的方法有多种。您在问题中发布的代码似乎过于复杂。我将为您提供两种更简单、更易于使用的不同方法。使用精灵 class,并使用函数。

我似乎不是在回答你的问题,但如果我只是告诉你要在你发布的代码中修复什么,我只是故意引导你走上一条会导致许多问题的道路,以及未来的复杂性。

方法一:使用精灵class

要制作赛车精灵,您可以使用如下精灵 class。

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 50))
        self.image.fill((255, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH / 2
        self.rect.y = HEIGHT / 2
        self.vx = 0
        self.vy = 0

    def update(self):
        self.vx = 0
        self.vy = 0
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT]:
            self.vx = -5
        elif key[pygame.K_RIGHT]:
            self.vx = 5
        if key[pygame.K_UP]:
            self.vy = -5
        elif key[pygame.K_DOWN]:
            self.vy = 5
        self.rect.x += self.vx
        self.rect.y += self.vy

由于您的 class 继承自 Pygame 的精灵 class,您必须为您的图像命名 self.image 并且您必须为图像命名矩形 self.rect。正如您还看到的,class 有两个主要方法。一种用于创建 sprite(__init__) 一种用于更新 sprite(update)

要使用您的 class,制作一个 Pygame 精灵组来容纳您所有的精灵,然后将您的玩家对象添加到组中:

sprites = pygame.sprite.Group()
player = Player()
sprtites.add(player)

并在更新屏幕的游戏循环中实际将精灵渲染到屏幕调用 sprites.update()sprites.draw()

sprites.update()
window_name.fill((200, 200, 200))
sprites.draw(window_name)
pygame.display.flip()

我强烈推荐使用 sprite classes 的原因是,它会使您的代码看起来更简洁,并且更易于维护。您甚至可以将每个精灵 class 移动到它们自己的单独文件中。

然而,在完全研究上述方法之前,您应该阅读 pygame.Rect objects and pygame.sprite 对象,因为您将使用它们。

方法二:使用函数

如果您不想进入 sprite classes,您可以使用类似于下面的函数创建您的游戏实体。

def create_car(surface, x, y, w, h, color):
    rect = pygame.Rect(x, y, w, h)
    pygame.draw.rect(surface, color, rect)
    return rect

如果您仍然想使用精灵,但又不想制作 class 只需稍微修改上面的函数即可:

def create_car(surface, x, y, color, path_to_img):
    img = pygame.image.load(path_to_img)
    rect = img.get_rect()
    surface.blit(img, (x, y))

这是我如何使用上述函数制作可移动的示例rectangle/sprite:

import pygame

WIDTH = 640
HEIGHT = 480
display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Moving Player Test")
clock = pygame.time.Clock()
FPS = 60

def create_car(surface, x, y, w, h, color):
    rect = pygame.Rect(x, y, w, h)
    pygame.draw.rect(surface, color, rect)
    return rect

running = True
vx = 0
vy = 0
player_x = WIDTH / 2 # middle of screen width
player_y = HEIGHT / 2 # middle of screen height
player_speed = 5
while running:
    clock.tick(FPS)
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
            pygame.quit()
            quit()
        if e.type == pygame.KEYDOWN:
            if e.key == pygame.K_LEFT:
                vx = -player_speed
            elif e.key == pygame.K_RIGHT:
                vx = player_speed
            if e.key == pygame.K_UP:
                vy = -player_speed
            elif e.key == pygame.K_DOWN:
                vy = player_speed
        if e.type == pygame.KEYUP:
            if e.key == pygame.K_LEFT or e.key == pygame.K_RIGHT or\
               e.key == pygame.K_UP or e.key == pygame.K_DOWN:
                vx = 0
                vy = 0

    player_x += vx
    player_y += vy
    display.fill((200, 200, 200))
    ####make the player#####
    player = create_car(display, player_x, player_y, 10, 10, (255, 0, 0))
    pygame.display.flip()

正如您在上面看到的,可以简化用于移动赛车的代码。

我应该注意,我对上面列出的每种方法都做了一些假设。

  1. 你要么使用圆形、方形,要么使用某种类型的 pygame 形状对象。

  2. 或者说你使用了精灵。

如果您目前没有使用上述任何方法,我建议您使用。一旦您开始构建更大更复杂的游戏,这样做将使您的代码更易于维护。