我在pygame中创建了迷宫游戏(这是我的第一个)。但是,无论何时我进入然后离开暂停屏幕,时钟都停留在00:00:-15。甚至更奇怪的是,如果我再次进入并离开暂停屏幕,代码将按照我预期的方式工作(继续输入进入暂停视频之前的时钟。
以下是生成时钟的代码:
# creates the string that displays time
def get_time(hours,minutes,seconds):
if len(str(hours)) > 1:
a = str(hours)
else:
a = "0" + str(hours)
if len(str(minutes)) > 1:
b = str(minutes)
else:
b = "0" + str(minutes)
if len(str(seconds)) > 1:
c = str(seconds)
else:
c = "0" + str(seconds)
return a + ":" + b + ":" + c
# creates the time counter
def draw_time(start_time,pause_time):
hours = 0
minutes = 0
seconds = 0
current_time = time.time() - pause_time - start_time
if current_time > 3600:
while True:
if current_time - 3600 > 0:
hours += 1
current_time -= 3600
else:
while True:
if current_time - 60 > 0:
minutes += 1
current_time -= 60
else:
seconds += int(current_time)
break
break
else:
while True:
if current_time - 60 > 0:
minutes += 1
current_time -= 60
else:
seconds += int(current_time)
break
return [font1.render(get_time(hours, minutes, seconds), True, (0, 0, 0), (255, 255, 255)), get_time(hours, minutes, seconds)]
这将显示它:
screen.blit(text[0], (700, 15))
这将激活/禁用暂停屏幕:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or event.key == pygame.K_p:
if pause:
pause = False
pause_time = time.time() - pause_time_start
else:
pause = True
pause_time_start = time.time() - game_time - start
if event.key == pygame.K_RETURN:
done = True
这是整个代码:
import pygame
import random
import time
pygame.init()
# all fonts used
font1 = pygame.font.SysFont("comicsansms", 49, True)
font2 = pygame.font.SysFont("comicsansms", 150, True)
font3 = pygame.font.SysFont("comicsansms", 28, True)
# creates the string that displays time
def get_time(hours,minutes,seconds):
if len(str(hours)) > 1:
a = str(hours)
else:
a = "0" + str(hours)
if len(str(minutes)) > 1:
b = str(minutes)
else:
b = "0" + str(minutes)
if len(str(seconds)) > 1:
c = str(seconds)
else:
c = "0" + str(seconds)
return a + ":" + b + ":" + c
# creates the time counter
def draw_time(start_time,pause_time):
hours = 0
minutes = 0
seconds = 0
current_time = time.time() - pause_time - start_time
if current_time > 3600:
while True:
if current_time - 3600 > 0:
hours += 1
current_time -= 3600
else:
while True:
if current_time - 60 > 0:
minutes += 1
current_time -= 60
else:
seconds += int(current_time)
break
break
else:
while True:
if current_time - 60 > 0:
minutes += 1
current_time -= 60
else:
seconds += int(current_time)
break
return [font1.render(get_time(hours, minutes, seconds), True, (0, 0, 0), (255, 255, 255)), get_time(hours, minutes, seconds)]
class cell:
def __init__(self,up,down,left,right):
self.visited = False
self.walls = [up,down,left,right]
class labyrinth:
# generates the maze
def __init__(self,id):
self.id = id
self.walls = []
self.maze_walls = []
self.cells = []
x = 0
t = 0
# creates all cell within the maze
for f in range(22):
for s in range(28):
# if command makes sure no cellls are created where the clock is supposed to be
if not (f in (0,1,2) and s > 20):
self.cells.append(cell((x + 8, t, 25, 8), (x + 8, t + 33, 25, 8), (x, t + 8, 8, 25), (x + 33, t + 8, 8, 25)))
x += 33
x = 0
t += 33
# generates maze using prim's algorithm
for v in self.cells[0].walls:
self.maze_walls.append(v)
self.walls.append(v)
self.cells[0].visited = True
while len(self.walls) > 0:
wall = random.choice(self.walls)
# checks which cells are divided by the wall
divided_cells = []
for u in self.cells:
if wall in u.walls:
divided_cells.append(u)
if len(divided_cells) > 1 and (not ((divided_cells[0].visited and divided_cells[1].visited) or ((not divided_cells[0].visited) and (not divided_cells[1].visited)))):
# checks which cells have been visited
for k in divided_cells:
k.walls.remove(wall)
if k.visited == False:
k.visited = True
for q in k.walls:
if not q in self.walls:
self.walls.append(q)
if not q in self.maze_walls:
self.maze_walls.append(q)
if wall in self.maze_walls:
self.maze_walls.remove(wall)
self.walls.remove(wall)
for j in range(0,736,33):
for i in range(0,951,33):
self.maze_walls.append((i, j, 8, 8))
# draws the maze
def draw(self, goal):
screen.fill((0, 0, 0))
for k in self.maze_walls:
pygame.draw.rect(screen, color, pygame.Rect(k[0],k[1],k[2],k[3]))
pygame.draw.rect(screen, color, pygame.Rect(695, 0, 300, 105)) # clock background
pygame.draw.rect(screen, (0, 255, 0), goal) # finish
id = 0
running = True
while running:
screen = pygame.display.set_mode((930, 733))
done = False
color = (0, 128, 255) # color of the walls
x = 16
y = 16
clock = pygame.time.Clock()
start = time.time()
id += 1
maze = labyrinth(id)
goal = pygame.Rect(899,701,25,25)
victory = False
speed = 4 # movement speed
pause = False
pause_time = 0 # time spent in pause menue
game_time = 0 # time spent playingg
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or event.key == pygame.K_p:
if pause:
pause = False
pause_time = time.time() - pause_time_start
else:
pause = True
pause_time_start = time.time() - game_time - start
if event.key == pygame.K_RETURN:
done = True
if pause:
screen.fill((0, 0, 0))
pause_text = font2.render("PAUSE",True,(255,255,255))
screen.blit(pause_text, (468 - (pause_text.get_width() // 2), 368 - (pause_text.get_height() // 2)))
# the actual game
if not victory and not pause:
game_time = time.time() - pause_time - start
move_up = True
move_down = True
move_left = True
move_right = True
pressed = pygame.key.get_pressed()
# movment
if pressed[pygame.K_w] or pressed[pygame.K_UP]:
# checks if their is a overlap with the wall
for m in maze.maze_walls:
player = pygame.Rect(x, y - speed, 10, 10)
if player.colliderect(pygame.Rect(m[0],m[1],m[2],m[3])):
move_up = False
break
if move_up:
y -= speed
if pressed[pygame.K_s] or pressed[pygame.K_DOWN]:
player = pygame.Rect(x, y + speed, 10, 10)
for m in maze.maze_walls:
if player.colliderect(pygame.Rect(m[0],m[1],m[2],m[3])):
move_down = False
break
if move_down:
y += speed
if pressed[pygame.K_a] or pressed[pygame.K_LEFT]:
player = pygame.Rect(x - speed, y, 10, 10)
for m in maze.maze_walls:
if player.colliderect(pygame.Rect(m[0],m[1],m[2],m[3])):
move_left = False
break
if move_left:
x -= speed
if pressed[pygame.K_d] or pressed[pygame.K_RIGHT]:
player = pygame.Rect(x + speed, y, 10, 10)
for m in maze.maze_walls:
if player.colliderect(pygame.Rect(m[0],m[1],m[2],m[3])):
move_right = False
break
if move_right:
x += speed
# checks if player has reached the goal
if goal.colliderect((x, y, 10, 10)):
victory = True
# draws the screen
maze.draw(goal)
text = draw_time(start, pause_time)
pygame.draw.rect(screen, (255, 100, 0), pygame.Rect(x,y,10,10))
screen.blit(text[0], (700, 15))
# victory screen
if victory:
screen.fill((0, 0, 0))
time_text = font1.render("Time Taken: " + text[1],True,(255,255,255))
victory_text = font2.render("VICTORY!",True,(255,255,255))
reset = font3.render("(Press Enter to Start New Game)",True,(255,255,255))
screen.blit(victory_text,(468 - (victory_text.get_width() // 2), 328 - (victory_text.get_height() // 2)))
screen.blit(time_text, (468 - (time_text.get_width() // 2), (248 - (time_text.get_height() // 2)) + victory_text.get_height()))
screen.blit(reset, (468 - (reset.get_width() // 2), (248 - (reset.get_height() // 2)) + victory_text.get_height() + time_text.get_height()))
clock.tick(60)
pygame.display.flip()
答案 0 :(得分:0)
我个人会采用略有不同的方法来记录时间。似乎您要跟踪(pause_time
,pause_time_start
,game_time
,current_time
)有很多不同的时钟变量。假设您不想专门跟踪游戏暂停的时间,则可以只使用game_time
变量和一个更新变量,并且仅在玩游戏时更新game_time
游戏。
game_time = 0
last_clock_update = time.time()
while not done:
if not paused:
cur_time = time.time()
clock_update = cur_time - last_clock_update # get time since last clock update
game_time += clock_update
last_clock_update = cur_time
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE or event.key == pygame.K_p:
if pause:
last_clock_update = time.time() # Set this to current time so the next clock update after a pause is accurate
# Rest of game code
我们在这里所做的是通过计算自上次更新以来的时间,在循环的每次迭代中更新game_time
-仅在游戏未暂停的情况下。
此外,如果您想跟踪游戏暂停了多长时间(或其他一些统计信息),则可以制作一个类似于game_time
的新变量,并根据需要以相同的方式添加它处于游戏状态。
答案 1 :(得分:0)
您在这里处理两种不同的时间测量,即瞬时和持续时间。从time.time()
获得的是一个瞬间-它描述了一个特定的时间点。当减去两个瞬间时,您得到一个持续时间-这两个特定点之间经过的时间。通过混淆两者,您会看到令人困惑的结果。
start = time.time()
# ...
pause_time = 0 # time spent in pause menue
game_time = 0 # time spent playingg
在这里,您说的是游戏开始时即是即时。您说的是pause_time和game_time是持续时间。它们是自游戏开始以来在暂停/未暂停模式下花费的时间。
您没有暂停的每一帧都更新game_time:
game_time = time.time() - pause_time - start
这里start
和time.time()
是瞬间,而pause_time
是持续时间。尽管阅读有点尴尬,但这种方法有效。从start
中减去time.time()
可以得出自游戏以暂停或未暂停模式开始以来的总经过时间,而减去pause_time
则可以得出在未暂停模式下花费的时间。很好。
这是您的暂停行为:
pause = True
pause_time_start = time.time() - game_time - start
因此time.time()
和start
再次是即时的。减去它们可以让您在任何游戏中总花费的时间更长。减去game_time
可得出暂停模式下的总经过时间,即持续时间。我不确定这不是您真正想要的,因为下次您使用它时,您的未暂停代码中:
pause = False
pause_time = time.time() - pause_time_start
所以time.time()
是一个瞬间,而pause_time_start
是一个持续时间。这样减去它们会在游戏开始前的某个时刻为您提供另一个瞬间。但是您像持续时间一样使用此瞬间!瞬间是静止一个数字,但是通常它是一个非常大的数字。 (从技术上讲,这是自纪元以来的秒数,在大多数操作系统中,您可能要运行Pygame的时间是1970年1月1日午夜。)
再次更新game_time
时,事情显然出了问题:
game_time = time.time() - pause_time - start
现在pause_time
的值不正确,您正在尝试添加一个瞬间(time.time()
)并减去另外两个瞬间。这给您带来巨大的负面价值。当您尝试渲染时,您的时间渲染代码非常混乱,因为它不期望负数。它不显示“ -15”秒。屏幕上显示的数字不正确,例如“ -1545616400”!
之所以能够在 second 时间周期内工作,是因为这些错误会被抵消。这种计算方式使game_time
的负数极大,从而影响了pause_start_time
的下一次计算,使其极大地正数,并最终使pause_time
的下一次计算恢复为较小的持续时间。>
您可以通过确定pause_time_start
应该是什么并修复相应的计算来最小化此问题。我想您可能是因为这是游戏暂停的即时。如果是这样,您可以更新您的取消暂停/暂停代码:
if pause:
pause = False
pause_time += time.time() - pause_time_start
else:
pause = True
pause_time_start = time.time()
在我们暂停的那一刻,我们要做的只是记住那一瞬间,以备后用。在我们取消暂停的那一刻,我们将暂停所花费的时间添加到累计暂停时间中。我们的瞬间保持瞬间,我们的持续时间保持持续时间。