pygame 左右移动问题

pygame moving left and right issue

我已经开始在 pygame 上制作一些东西,但是我在向左或向右移动时遇到了问题。如果我快速从按右箭头键更改为按左箭头键,然后放开右箭头键,方块就会停止移动。这是我的代码

bg = "sky.jpg"
ms = "ms.png"
import pygame, sys
from pygame.locals import *
x,y = 0,0
movex,movey=0,0
pygame.init()
screen=pygame.display.set_mode((664,385),0,32)
background=pygame.image.load(bg).convert()
mouse_c=pygame.image.load(ms).convert_alpha()
m = 0
pygame.event.pump() 
while 1:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type==KEYDOWN:
            if event.key==K_LEFT:
                movex =-0.5
                m = m + 1
            if event.key==K_RIGHT:
                movex=+0.5
                m = m + 1
        elif event.type == KEYUP:
            if event.key==K_LEFT and not event.key==K_RIGHT:
                    movex = 0
            if event.key==K_RIGHT and not event.key==K_LEFT:
                    movex =0

    x+=movex
    y=200
    screen.blit(background, (0,0))
    screen.blit(mouse_c,(x,y))
    pygame.display.update()

有什么方法可以更改此设置,以便在按下右箭头键并松开左箭头键时它会向右移动而不是停止? P.S 我仍在学习 pygame 并且对这个模块还很陌生。如果这看起来像一个愚蠢的问题,但我找不到任何答案,我很抱歉。

一种方法是创建一个队列来跟踪最后按下的按钮。如果我们按下右箭头键,我们会将速度放在列表的第一位,如果我们然后按下左箭头键,我们会将新的速度放在列表的第一位。所以最后按下的按钮将始终在列表中排在第一位。然后我们只需在释放按钮时将其从列表中删除即可。

import pygame
pygame.init()

screen = pygame.display.set_mode((720, 480))
clock = pygame.time.Clock()
FPS = 30

rect = pygame.Rect((350, 220), (32, 32))  # Often used to track the position of an object in pygame.
image = pygame.Surface((32, 32))  # Images are Surfaces, so here I create an 'image' from scratch since I don't have your image.
image.fill(pygame.Color('white'))  # I fill the image with a white color.
velocity = [0, 0]  # This is the current velocity.
speed = 200  # This is the speed the player will move in (pixels per second).
dx = []  # This will be our queue. It'll keep track of the horizontal movement.

while True:
    dt = clock.tick(FPS) / 1000.0  # This will give me the time in seconds between each loop.

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            raise SystemExit
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                dx.insert(0, -speed)
            elif event.key == pygame.K_RIGHT:
                dx.insert(0, speed)
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                dx.remove(-speed)
            elif event.key == pygame.K_RIGHT:
                dx.remove(speed)

    if dx:  # If there are elements in the list.
        rect.x += dx[0] * dt

    screen.fill((0, 0, 0))
    screen.blit(image, rect)
    pygame.display.update()

    # print dx  # Uncomment to see what's happening.

你当然应该把所有东西都放在整洁的函数中,也许还可以创建一个播放器 class。

你的问题是,当你使用

测试 KEYDOWN 事件时
if event.key==K_LEFT and not event.key==K_RIGHT:

你总是得到 True,因为当 event.key==K_LEFT 为 True 时, 它也总是 not event.key==K_RIGHT(因为事件的关键毕竟是 K_LEFT)。

我对这种问题的处理方法是分开 行动的意图。所以,对于关键 事件,我会简单地跟踪什么动作 应该发生,像这样:

moveLeft = False
moveRight = False

while True:
  for event in pygame.event.get():
    if event.type == QUIT:
      pygame.quit()
      sys.exit()
    if event.type == KEYDOWN:
      if event.key == K_LEFT:  moveLeft  = True
      if event.key == K_RIGHT: moveRight = True
    elif event.type == KEYUP:
      if event.key == K_LEFT:  moveLeft  = False
      if event.key == K_RIGHT: moveRight = False

然后,在循环的[​​=24=]部分,你可以 根据输入采取行动,例如:

while True:
  for event in pygame.event.get():
    ...
  if moveLeft  : x -= 0.5
  if moveRight : x += 0.5

问题是你有重叠的关键特征;如果先向右再向左按住,xmove 首先设置为 1,然后变为 -1。但是随后您释放其中一个键,即使您仍然按住另一个键,它也会将 xmove 重置为 0。您要做的是为每个键创建布尔值。这是一个例子:

demo.py:

import pygame

window = pygame.display.set_mode((800, 600))

rightPressed = False
leftPressed = False

white = 255, 255, 255
black = 0, 0, 0

x = 250
xmove = 0

while True:
    window.fill(white)
    pygame.draw.rect(window, black, (x, 300, 100, 100))
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                rightPressed = True
            if event.key == pygame.K_LEFT:
                leftPressed = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                rightPressed = False
            if event.key == pygame.K_LEFT:
                leftPressed = False
    xmove = 0
    if rightPressed:
        xmove = 1
    if leftPressed:
        xmove = -1
    x += xmove
    pygame.display.flip()

我知道我的回答已经很晚了,但我是 Pygame 的新手,对于像我这样的初学者来说,像以前的答案一样编写代码很容易理解,但我有一个解决方案 to.I 没有使用keydown行代码,而不是我只是将移动事件代码嵌套在主游戏的while循环中,我的英语不好所以我给你一个示例代码。

enter code here

while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT or event.type == pygame.K_ESCAPE:
        run = False
    win.blit(bg, (0, 0))
    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_LEFT]:
        x -= 5
    if pressed[pygame.K_RIGHT]:
        x += 5
    if pressed[pygame.K_UP]:
        y -= 5
    if pressed[pygame.K_DOWN]:
        y += 5
    win.blit(image,(x,y))
    pygame.display.update()
pygame.quit()

这将使图像快速移动而无需重复按键,很长一段时间代码只在主 while 循环中而不会在任何其他循环中。