【问题标题】:pygame moving left and right issuepygame左右移动问题
【发布时间】:2017-01-28 13:04:09
【问题描述】:

我已经开始在 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()

有没有办法可以改变这一点,如果按下右箭头键并释放左箭头键,它会向右而不是停止? 附言 我仍在学习 pygame 并且对该模块非常陌生。很抱歉,这似乎是一个愚蠢的问题,但我找不到任何答案。

【问题讨论】:

  • ms.png 是块
  • event.key 只能保留一个值,因此当not event.key==K_RIGHT: 已经是event.key==K_LEFT 时,检查它是没有意义的

标签: python python-2.7 pygame 2d


【解决方案1】:

您的问题是,当您使用

测试 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

然后,在循环的“主要”部分,您可以 根据输入采取行动,例如:

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

【讨论】:

    【解决方案2】:

    问题是你有重叠的关键特征;如果先按住右再左,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()
    

    【讨论】:

    • 这几乎是我答案的精确副本。
    • 嘿迈耶,我没有看到你的回答。我可以保证我没有窃取你的任何代码或试图复制你。
    • 不用担心,毕竟这是一种相当明显的方法。请确保在两次发布相同的答案之前阅读其他答案。
    【解决方案3】:

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

    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.
    

    你当然应该把所有东西都放在简洁的函数中,也许还应该创建一个 Player 类。

    【讨论】:

      【解决方案4】:

      我知道我的答案已经很晚了,但我是 Pygame 的新手,对于像我这样的初学者来说,像以前的答案一样编写代码很容易理解,但我有一个解决方案。我没有使用 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循环中,而在任何其他循环中都没有。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-09
        • 2017-09-27
        • 1970-01-01
        • 2020-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多