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 循环中而不会在任何其他循环中。
我已经开始在 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 循环中而不会在任何其他循环中。