pygame moving left and right issue

别说谁变了你拦得住时间么 提交于 2019-12-08 04:42:59

问题


I have started making something on pygame but I have encountered an issue when moving left or right. if I quickly change from pressing the right arrow key to pressing the left one and also let go of the right one the block just stops moving. this is my code

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()

is there a way I can change this so if the right arrow key is pressed and the left arrow key is released that it will go right instead of stopping? P.S I am still learning pygame and am very new to the module. I'm sorry if this seems like a stupid question but i couldn't find any answers to it.


回答1:


Your problem is that when you test the KEYDOWN events with

if event.key==K_LEFT and not event.key==K_RIGHT:

you always get True, because when event.key==K_LEFT is True, it also always is not event.key==K_RIGHT (because the key of the event is K_LEFT after all).

My approach to this kind of problem is to separate the intent from the action. So, for the key events, I would simply keep track of what action is supposed to happen, like this:

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

Then, in the "main" part of the loop, you can take action based on the input, such as:

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



回答2:


the problem is that you have overlapping key features; If you hold down first right and then left xmove is first set to 1 and then changes to -1. But then you release one of the keys and it resets xmove to 0 even though you are still holding the other key. What you want to do is create booleans for each key. Here is an example:

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:


One way could be to create a queue that keeps track of the button that was pressed last. If we press the right arrow key we'll put the velocity first in the list, and if we then press the left arrow key we put the new velocity first in the list. So the button that was pressed last will always be first in the list. Then we just remove the button from the list when we release it.

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.

You should of course put everything in neat functions and maybe create a Player class.




回答4:


I know my answer is pretty late but im new to Pygame to and for beginner like me doing code like some previous answer is easy to understand but i have a solution to.I didn`t use the keydown line code, instead i just put the moving event code nested in the main game while loop, im bad at english so i give you guy an example code.

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()

This will make the image move rapidly without repeating pushing the key, at long the code just in the main while loop with out inside any other loop.



来源:https://stackoverflow.com/questions/41910100/pygame-moving-left-and-right-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!