Pygame如何记录玩游戏时的键盘动作
Pygame how to record keyboard movement while playing the game
所以我正在尝试制作也能记录玩家移动然后回放的俄罗斯方块,将其视为回放功能。
我尝试过实现键盘库,但问题是当我尝试 record(recorded_events = keyboard.record("esc"))
时,整个游戏冻结,直到我按下“esc”,当我尝试播放它时,它冻结并且什么都不做。
我注意到的是,如果我将打印语句放在播放旁边,它会在游戏冻结时打印整个键盘输入,但无论如何都无法播放。
IDK 做什么
我的代码片段接受输入并打勾并将它们放入文本文件中。
if event.key == pygame.K_DOWN:
increaseGravity = True
u = " s\n"
time = str(pygame.time.get_ticks())
e = time + "," + u
f.writelines(str(e))
以及负责播放的代码部分!
if event.key == pygame.K_h:
f = open("m.txt", "r")
currtick = pygame.time.get_ticks()
for x in f:
b = x.split(',')
cc = int(b[0])
if cc == currtick:
print(" works")
keyboard.press_and_release(b[1].strip)
这就是文本文件的样子,第一个是报价,第二个是移动
1453, d
1763, d
2752, a
以下建议:
if event.key == pygame.K_h:
currtick = pygame.time.get_ticks()
for x in keyList:
# Variable that counts
cx = 0
# current tick time combined with the movment tick
cc = (int(keyList[cx][0])) + currtick
# puts key id into xx variable
xx= int(keyList[cx][1])
#prints both
print(keyList[cx][0],keyList[cx][1])
#adds +1 to cx
cx =+ 1
# if current tick + time when pressed is equal to current game tick it executes print and presses the key
if cc == currtick:
print(" works")
if(xx == 1073741904):
keyboard.press_release('a')
我创建了一个示例,可以记录事件,然后在事件之间大致相同的时间重播事件。
当按下鼠标左键时,记录被启用并且 KEYDOWN
事件连同它们发生的时间附加到列表中。 Left-clicking 再次禁用录音。 Right-clicking 将开始播放 scheduling a custom event to occur. When that event occurs, the recorded event is inserted into the event queue 录制的事件。然后使用刚刚发布的事件和下一个事件之间的时间差设置计时器。
import time
import random
import pygame
CUSTOM_PLAYBACK_EVENT = pygame.USEREVENT + 1
def queue_next_event(event_list, event_index):
"""Set a timer for the next playback event"""
if event_index == 0:
timer_duration = 100 # effectively immediate
else:
elapsed_time = event_list[event_index][1] - event_list[event_index - 1][1]
timer_duration = round(elapsed_time * 1000) # convert to milliseconds
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, timer_duration)
print(f"{time.time()} Set timer for {timer_duration} ms")
class Block(pygame.sprite.Sprite):
def __init__(self, size, pos):
pygame.sprite.Sprite.__init__(self)
self.size = size
self.image = pygame.Surface([size[0], size[1]])
self.image.fill(pygame.color.Color("blueviolet"))
self.rect = self.image.get_rect()
self.rect[0] = pos[0]
self.rect[1] = pos[1]
# initially stationary
self.speedx = 0
self.speedy = 0
def update(self):
"""Move, but stay within window bounds"""
width, height = screen.get_size()
if not (self.size[0] // 2) < self.rect.center[0] < (width - self.size[0] // 2):
self.speedx *= -1 # reverse direction
self.rect.x += self.speedx
if not (self.size[1] // 2) < self.rect.center[1] < (height - self.size[1] // 2):
self.speedy *= -1 # reverse direction
self.rect.y += self.speedy
def draw(self, screen):
# Add this draw function so we can draw individual sprites
screen.blit(self.image, self.rect)
def handle_event(self, event):
# update speeds based one keypress
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.speedx -= 1
elif event.key == pygame.K_RIGHT:
self.speedx += 1
elif event.key == pygame.K_UP:
self.speedy -= 1
elif event.key == pygame.K_DOWN:
self.speedy += 1
elif event.key == pygame.K_SPACE:
self.speedx = 0
self.speedy = 0
else:
pass
# initialise screen
screen = pygame.display.set_mode((800, 800), pygame.RESIZABLE | pygame.NOFRAME)
pygame.init()
sprite_list = pygame.sprite.Group()
# create a cube at a random position
cube = Block((80, 80), (random.randint(100, 700), random.randint(100, 700)))
clock = pygame.time.Clock()
# variables for recording
recording = False
playback = False
playback_index = 0
recorded_events = []
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
else:
# handle the event
cube.handle_event(event)
if recording:
# save the event and the time
recorded_events.append((event, time.time())) # event
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left click
recording = not recording # toggle recording
elif event.button == 3: # Right click toggles playback
playback = not playback
if playback:
if recorded_events:
playback_index = 0 # always start playback at zero
queue_next_event(recorded_events, playback_index)
else:
playback = False # can't playback no events
else: # disable playback timer
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, 0)
elif event.type == CUSTOM_PLAYBACK_EVENT:
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, 0) # disable playback timer
# post the next event
pygame.event.post(recorded_events[playback_index][0])
playback_index += 1
if playback_index < len(recorded_events):
queue_next_event(recorded_events, playback_index)
else:
playback = False
# clear the screen
screen.fill(pygame.Color("white"))
# update sprites
cube.update()
# draw sprites
cube.draw(screen)
# refresh display
pygame.display.update()
clock.tick(60) # limit to 60 FPS
pygame.quit()
记录的事件不会被清除,所以如果您停止和开始记录会有更大的差距,有一个调试 print
语句可以帮助跟踪事情。理想情况下会有一些记录和回放的视觉指示。
所以我正在尝试制作也能记录玩家移动然后回放的俄罗斯方块,将其视为回放功能。
我尝试过实现键盘库,但问题是当我尝试 record(recorded_events = keyboard.record("esc"))
时,整个游戏冻结,直到我按下“esc”,当我尝试播放它时,它冻结并且什么都不做。
我注意到的是,如果我将打印语句放在播放旁边,它会在游戏冻结时打印整个键盘输入,但无论如何都无法播放。
IDK 做什么
我的代码片段接受输入并打勾并将它们放入文本文件中。
if event.key == pygame.K_DOWN:
increaseGravity = True
u = " s\n"
time = str(pygame.time.get_ticks())
e = time + "," + u
f.writelines(str(e))
以及负责播放的代码部分!
if event.key == pygame.K_h:
f = open("m.txt", "r")
currtick = pygame.time.get_ticks()
for x in f:
b = x.split(',')
cc = int(b[0])
if cc == currtick:
print(" works")
keyboard.press_and_release(b[1].strip)
这就是文本文件的样子,第一个是报价,第二个是移动
1453, d
1763, d
2752, a
以下建议:
if event.key == pygame.K_h:
currtick = pygame.time.get_ticks()
for x in keyList:
# Variable that counts
cx = 0
# current tick time combined with the movment tick
cc = (int(keyList[cx][0])) + currtick
# puts key id into xx variable
xx= int(keyList[cx][1])
#prints both
print(keyList[cx][0],keyList[cx][1])
#adds +1 to cx
cx =+ 1
# if current tick + time when pressed is equal to current game tick it executes print and presses the key
if cc == currtick:
print(" works")
if(xx == 1073741904):
keyboard.press_release('a')
我创建了一个示例,可以记录事件,然后在事件之间大致相同的时间重播事件。
当按下鼠标左键时,记录被启用并且 KEYDOWN
事件连同它们发生的时间附加到列表中。 Left-clicking 再次禁用录音。 Right-clicking 将开始播放 scheduling a custom event to occur. When that event occurs, the recorded event is inserted into the event queue 录制的事件。然后使用刚刚发布的事件和下一个事件之间的时间差设置计时器。
import time
import random
import pygame
CUSTOM_PLAYBACK_EVENT = pygame.USEREVENT + 1
def queue_next_event(event_list, event_index):
"""Set a timer for the next playback event"""
if event_index == 0:
timer_duration = 100 # effectively immediate
else:
elapsed_time = event_list[event_index][1] - event_list[event_index - 1][1]
timer_duration = round(elapsed_time * 1000) # convert to milliseconds
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, timer_duration)
print(f"{time.time()} Set timer for {timer_duration} ms")
class Block(pygame.sprite.Sprite):
def __init__(self, size, pos):
pygame.sprite.Sprite.__init__(self)
self.size = size
self.image = pygame.Surface([size[0], size[1]])
self.image.fill(pygame.color.Color("blueviolet"))
self.rect = self.image.get_rect()
self.rect[0] = pos[0]
self.rect[1] = pos[1]
# initially stationary
self.speedx = 0
self.speedy = 0
def update(self):
"""Move, but stay within window bounds"""
width, height = screen.get_size()
if not (self.size[0] // 2) < self.rect.center[0] < (width - self.size[0] // 2):
self.speedx *= -1 # reverse direction
self.rect.x += self.speedx
if not (self.size[1] // 2) < self.rect.center[1] < (height - self.size[1] // 2):
self.speedy *= -1 # reverse direction
self.rect.y += self.speedy
def draw(self, screen):
# Add this draw function so we can draw individual sprites
screen.blit(self.image, self.rect)
def handle_event(self, event):
# update speeds based one keypress
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.speedx -= 1
elif event.key == pygame.K_RIGHT:
self.speedx += 1
elif event.key == pygame.K_UP:
self.speedy -= 1
elif event.key == pygame.K_DOWN:
self.speedy += 1
elif event.key == pygame.K_SPACE:
self.speedx = 0
self.speedy = 0
else:
pass
# initialise screen
screen = pygame.display.set_mode((800, 800), pygame.RESIZABLE | pygame.NOFRAME)
pygame.init()
sprite_list = pygame.sprite.Group()
# create a cube at a random position
cube = Block((80, 80), (random.randint(100, 700), random.randint(100, 700)))
clock = pygame.time.Clock()
# variables for recording
recording = False
playback = False
playback_index = 0
recorded_events = []
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
else:
# handle the event
cube.handle_event(event)
if recording:
# save the event and the time
recorded_events.append((event, time.time())) # event
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left click
recording = not recording # toggle recording
elif event.button == 3: # Right click toggles playback
playback = not playback
if playback:
if recorded_events:
playback_index = 0 # always start playback at zero
queue_next_event(recorded_events, playback_index)
else:
playback = False # can't playback no events
else: # disable playback timer
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, 0)
elif event.type == CUSTOM_PLAYBACK_EVENT:
pygame.time.set_timer(CUSTOM_PLAYBACK_EVENT, 0) # disable playback timer
# post the next event
pygame.event.post(recorded_events[playback_index][0])
playback_index += 1
if playback_index < len(recorded_events):
queue_next_event(recorded_events, playback_index)
else:
playback = False
# clear the screen
screen.fill(pygame.Color("white"))
# update sprites
cube.update()
# draw sprites
cube.draw(screen)
# refresh display
pygame.display.update()
clock.tick(60) # limit to 60 FPS
pygame.quit()
记录的事件不会被清除,所以如果您停止和开始记录会有更大的差距,有一个调试 print
语句可以帮助跟踪事情。理想情况下会有一些记录和回放的视觉指示。