pygame左右移动问题

时间:2017-01-28 13:04:10

标签: python python-2.7 pygame 2d

我已经开始在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,对模块很新。如果这看起来像是一个愚蠢的问题,我很抱歉,但我找不到任何答案。

4 个答案:

答案 0 :(得分:0)

一种方法是创建一个队列来跟踪最后按下的按钮。如果我们按右箭头键,我们将把速度放在列表中的第一位,如果我们按下左箭头键,我们将新的速度放在列表中。因此,最后按下的按钮将始终位于列表中的第一位。然后我们在发布时从列表中删除该按钮。

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类。

答案 1 :(得分:0)

当您使用

测试KEYDOWN事件时,您的问题是
if event.key==K_LEFT and not event.key==K_RIGHT:

你永远是真的,因为当event.key==K_LEFT为真时, 它也始终是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 :(得分:0)

问题是你有重叠的关键功能;如果您先按住右键然后左侧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 :(得分:0)

我知道我的答案很晚了,但是对于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循环中,而没有任何其他循环。