如何解决使用时钟的Pygame延迟问题
我用pygame制作了一个蛇游戏,并且效果很好。但是,有时它对用户输入的响应不是很好。我正在使用时钟和延迟来设置蛇应该移动多快。
移动代码:
pygame.time.delay(1)
clock.tick(7)
player.move()
render_screen()
渲染屏幕:
screen.fill((0,0))
draw_grid()
player.draw()
food.draw()
screen.fill((0,0),(0,513,512,50))
start.draw()
screen.blit(comic_font.render('Score: ' + str(score),False,(255,100,0)),(10,size + 5))
pygame.display.update()
完整代码:
import pygame
import random
pygame.init()
class Snake:
def __init__(self,x,y):
self.x = x
self.y = y
self.speed_x = 1
self.speed_y = 0
segments = []
for a in range(1,4):
segments.append(Segment(self.x - a,self.y))
self.segments = segments
def move(self):
global score,game_mode
# handle key inputs
keys = pygame.key.get_pressed()
for key in keys:
if self.speed_x == 0:
if keys[pygame.K_a]:
self.speed_x = -1
self.speed_y = 0
if keys[pygame.K_d]:
self.speed_x = 1
self.speed_y = 0
elif self.speed_y == 0:
if keys[pygame.K_w]:
self.speed_x = 0
self.speed_y = -1
if keys[pygame.K_s]:
self.speed_x = 0
self.speed_y = 1
# check for wall collisions
if self.x + self.speed_x < 0 or self.x + self.speed_x > rows - 1 or self.y + self.speed_y > rows - 1 or \
self.y + self.speed_y < 0:
game_mode = "end"
start.text = "RETRY"
return None
# moves snake
self.segments.insert(0,Segment(self.x,self.y))
self.x += self.speed_x
self.y += self.speed_y
# checks for self collisions
for segment in self.segments:
if self.x == segment.x and self.y == segment.y and self.segments.index(segment)!=len(self.segments)-1:
game_mode = "end"
start.text = "RETRY"
break
# checks for eating food
if self.x == food.x and self.y == food.y:
food.x = random.randrange(0,16)
food.y = random.randrange(0,16)
score += 1
else:
self.segments.pop()
def draw(self):
for segment in self.segments:
segment.draw()
pygame.draw.rect(screen,(self.x * size / rows,self.y * size / rows,size / rows,size / rows))
class Segment:
def __init__(self,y):
self.x = x
self.y = y
def draw(self):
pygame.draw.rect(screen,255 - player.segments.index(self),size / rows))
class Food:
def __init__(self,255,size / rows))
class button:
def __init__(self,y,r,g,b,text,font,width,height):
self.x = x
self.y = y
self.r = r
self.b = b
self.g = g
self.text = text
self.font = font
self.width = width
self.height = height
def draw(self):
pygame.draw.rect(screen,(self.r,self.g,self.b),(self.x,self.y,self.width,self.height))
screen.blit(self.font.render(self.text,(self.x + 10,self.y))
def mouse_over(self,pos):
if self.x < pos[0] < self.x + self.width and self.y < pos[1] < self.y + self.height:
return True
def draw_grid():
margin = size / rows
x = 0
y = 0
for line in range(rows):
x = x + margin
y = y + margin
pygame.draw.line(screen,255),(x,size))
pygame.draw.line(screen,y),(size,y))
def render_screen():
screen.fill((0,0))
draw_grid()
player.draw()
food.draw()
screen.fill((0,50))
start.draw()
screen.blit(comic_font.render('Score: ' + str(score),size + 5))
pygame.display.update()
size = 512
rows = 16
screen = pygame.display.set_mode((size,size + 50))
pygame.display.set_caption("Snake")
comic_font = pygame.font.SysFont("Comic Sans MS",30)
clock = pygame.time.Clock()
running = True
game_mode = "wait"
player = Snake(8,8)
food = Food(random.randrange(0,16),random.randrange(0,16))
start = button(size - 155,size + 5,"PLAY",comic_font,150,40)
score = 0
render_screen()
while running:
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if start.mouse_over(pos):
if game_mode == "wait":
game_mode = "play"
start.text = "PAUSE"
elif game_mode == "play":
game_mode = "wait"
start.text = "RESUME"
elif game_mode == "end":
game_mode = "play"
start.text = "PAUSE"
score = 0
running = True
game_mode = "wait"
player = Snake(8,8)
food = Food(random.randrange(0,16))
render_screen()
if game_mode == "play":
pygame.time.delay(1)
clock.tick(7)
player.move()
render_screen()
上面的完整代码可以重现该问题。
经过一些实验,似乎pygame.time.delay(1)较小时,延迟会更少。
我认为用户只能在tic之间读取输入,因此他们必须在现场准确输入。
我认为这可能就是为什么延迟较小时输入会落后的原因,因为延迟会影响每个输入之间的间隔。
有人知道为什么游戏有时不能很好地接收输入吗?
解决方法
pygame.key.get_pressed()
返回带有所有键盘按钮状态的列表。遍历此列表没有任何意义,因为您只想评估键 w a s d的当前状态。
根据按下的键设置速度:
class Snake:
# [...]
def move(self):
# [...]
# handle key inputs
keys = pygame.key.get_pressed()
if self.speed_x == 0:
if keys[pygame.K_a]:
self.speed_x,self.speed_y = -1,0
elif keys[pygame.K_d]:
self.speed_x,self.speed_y = 1,0
elif self.speed_y == 0:
if keys[pygame.K_w]:
self.speed_x,self.speed_y = 0,-1
elif keys[pygame.K_s]:
self.speed_x,1
# [...]
pygame.time.Clock.tick
延迟使游戏的运行速度低于给定的每秒滴答声。处理事件(pygame.key.get_pressed()
)时,将评估pygame.event.get()
返回的状态。
延迟游戏,在处理完事件之后,蛇已经被移动并且显示已更新:
while running:
for event in pygame.event.get():
# [...]
if game_mode == "play":
player.move()
render_screen()
clock.tick(7) # <---
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。