如何让你的角色在不重复点击按钮的情况下移动?
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()
正如您在上面看到的,可以简化用于移动赛车的代码。
我应该注意,我对上面列出的每种方法都做了一些假设。
你要么使用圆形、方形,要么使用某种类型的 pygame 形状对象。
或者说你使用了精灵。
如果您目前没有使用上述任何方法,我建议您使用。一旦您开始构建更大更复杂的游戏,这样做将使您的代码更易于维护。
我正在开发一款赛车游戏。我一直在使用此代码,但我的播放器只移动一次。我该如何解决这个问题?
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()
正如您在上面看到的,可以简化用于移动赛车的代码。
我应该注意,我对上面列出的每种方法都做了一些假设。
你要么使用圆形、方形,要么使用某种类型的 pygame 形状对象。
或者说你使用了精灵。
如果您目前没有使用上述任何方法,我建议您使用。一旦您开始构建更大更复杂的游戏,这样做将使您的代码更易于维护。