Pygame Tetris在主游戏屏幕上赢得了正确的关闭
我最近遵循了YouTube的俄罗斯俄罗斯俄罗斯俄罗斯游戏教程,如果您在开始屏幕上退出,当您尝试完全退出程序时,此错误似乎仅在主游戏屏幕上发生。如果我在主游戏屏幕上关闭,则以下错误填充:
File "C:\Users\OneDrive\import pygame", line 400, in <module>
main_menu(win)
File "C:\Users\OneDrive\import pygame", line 393, in main_menu
main(win)
File "C:\Users\OneDrive\import pygame", line 371, in main
draw_window(win, grid, score, last_score)
File "C:\Users\OneDrive\import pygame", line 265, in draw_window
surface.fill((0, 0, 0))
pygame.error: display Surface quit
这是每个代码块的崩溃:
行265:
def draw_window(surface, grid, score=0, last_score = 0):
surface.fill((0, 0, 0))
pygame.font.init()
font = pygame.font.SysFont('comicsans', 60)
label = font.render('Tetris', 1, (255, 255, 255))
行371
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
行383-395
def main_menu(win):
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
main(win)
pygame.display.quit()
行398-400
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
i比较了word for word for source代码,并且源代码似乎也可以从我看到的问题上遇到这个问题。我是编码的全新,并感谢您提供的任何帮助!我下面有完整的东西。我只希望它在用户选择时能够完美地关闭。这是我关注的源代码的链接( https://www.techwithtim.net/tutorials/game-development-with-python/tetris-pygame/tutorial-4/ )
import pygame
import random
pygame.font.init()
s_width = 800
s_height = 700
play_width = 300 # meaning 300 // 10 = 30 width per block
play_height = 600 # meaning 600 // 20 = 30 height per block
block_size = 30
top_left_x = (s_width - play_width) // 2
top_left_y = s_height - play_height
# SHAPE FORMATS
S = [['.....',
'.....',
'..00.',
'.00..',
'.....'],
['.....',
'..0..',
'..00.',
'...0.',
'.....']]
Z = [['.....',
'.....',
'.00..',
'..00.',
'.....'],
['.....',
'..0..',
'.00..',
'.0...',
'.....']]
I = [['..0..',
'..0..',
'..0..',
'..0..',
'.....'],
['.....',
'0000.',
'.....',
'.....',
'.....']]
O = [['.....',
'.....',
'.00..',
'.00..',
'.....']]
J = [['.....',
'.0...',
'.000.',
'.....',
'.....'],
['.....',
'..00.',
'..0..',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'...0.',
'.....'],
['.....',
'..0..',
'..0..',
'.00..',
'.....']]
L = [['.....',
'...0.',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..0..',
'..00.',
'.....'],
['.....',
'.....',
'.000.',
'.0...',
'.....'],
['.....',
'.00..',
'..0..',
'..0..',
'.....']]
T = [['.....',
'..0..',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..00.',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'..0..',
'.....'],
['.....',
'..0..',
'.00..',
'..0..',
'.....']]
shapes = [S, Z, I, O, J, L, T]
shape_colors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)]
# index 0 - 6 represent shape
class Piece(object): # *
def __init__(self, x, y, shape):
self.x = x
self.y = y
self.shape = shape
self.color = shape_colors[shapes.index(shape)]
self.rotation = 0
def create_grid(locked_pos={}): # *
grid = [[(0,0,0) for _ in range(10)] for _ in range(20)]
for i in range(len(grid)):
for j in range(len(grid[i])):
if (j, i) in locked_pos:
c = locked_pos[(j,i)]
grid[i][j] = c
return grid
def convert_shape_format(shape):
positions = []
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
positions.append((shape.x + j, shape.y + i))
for i, pos in enumerate(positions):
positions[i] = (pos[0] - 2, pos[1] - 4)
return positions
def valid_space(shape, grid):
accepted_pos = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)]
accepted_pos = [j for sub in accepted_pos for j in sub]
formatted = convert_shape_format(shape)
for pos in formatted:
if pos not in accepted_pos:
if pos[1] > -1:
return False
return True
def check_lost(positions):
for pos in positions:
x, y = pos
if y < 1:
return True
return False
def get_shape():
return Piece(5, 0, random.choice(shapes))
def draw_text_middle(surface, text, size, color):
font = pygame.font.SysFont("comicsans", size, bold=True)
label = font.render(text, 1, color)
surface.blit(label, (top_left_x + play_width /2 - (label.get_width()/2), top_left_y + play_height/2 - label.get_height()/2))
def draw_grid(surface, grid):
sx = top_left_x
sy = top_left_y
for i in range(len(grid)):
pygame.draw.line(surface, (128,128,128), (sx, sy + i*block_size), (sx+play_width, sy+ i*block_size))
for j in range(len(grid[i])):
pygame.draw.line(surface, (128, 128, 128), (sx + j*block_size, sy),(sx + j*block_size, sy + play_height))
def clear_rows(grid, locked):
inc = 0
for i in range(len(grid)-1, -1, -1):
row = grid[i]
if (0,0,0) not in row:
inc += 1
ind = i
for j in range(len(row)):
try:
del locked[(j,i)]
except:
continue
if inc > 0:
for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
x, y = key
if y < ind:
newKey = (x, y + inc)
locked[newKey] = locked.pop(key)
return inc
def draw_next_shape(shape, surface):
font = pygame.font.SysFont('comicsans', 30)
label = font.render('Next Shape', 1, (255,255,255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height/2 - 100
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
pygame.draw.rect(surface, shape.color, (sx + j*block_size, sy + i*block_size, block_size, block_size), 0)
surface.blit(label, (sx + 10, sy - 30))
def update_score(nscore):
score = max_score()
with open('scores.txt', 'w') as f:
if int(score) > nscore:
f.write(str(score))
else:
f.write(str(nscore))
def max_score():
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
return score
def draw_window(surface, grid, score=0, last_score = 0):
surface.fill((0, 0, 0))
pygame.font.init()
font = pygame.font.SysFont('comicsans', 60)
label = font.render('Tetris', 1, (255, 255, 255))
surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), 30))
# current score
font = pygame.font.SysFont('comicsans', 30)
label = font.render('Score: ' + str(score), 1, (255,255,255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height/2 - 100
surface.blit(label, (sx + 20, sy + 160))
# last score
label = font.render('High Score: ' + last_score, 1, (255,255,255))
sx = top_left_x - 200
sy = top_left_y + 200
surface.blit(label, (sx + 20, sy + 160))
for i in range(len(grid)):
for j in range(len(grid[i])):
pygame.draw.rect(surface, grid[i][j], (top_left_x + j*block_size, top_left_y + i*block_size, block_size, block_size), 0)
pygame.draw.rect(surface, (255, 0, 0), (top_left_x, top_left_y, play_width, play_height), 5)
draw_grid(surface, grid)
#pygame.display.update()
def main(win): # *
last_score = max_score()
locked_positions = {}
grid = create_grid(locked_positions)
change_piece = False
run = True
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.27
level_time = 0
score = 0
while run:
grid = create_grid(locked_positions)
fall_time += clock.get_rawtime()
level_time += clock.get_rawtime()
clock.tick()
if level_time/1000 > 5:
level_time = 0
if level_time > 0.12:
level_time -= 0.005
if fall_time/1000 > fall_speed:
fall_time = 0
current_piece.y += 1
if not(valid_space(current_piece, grid)) and current_piece.y > 0:
current_piece.y -= 1
change_piece = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_piece.x -= 1
if not(valid_space(current_piece, grid)):
current_piece.x += 1
if event.key == pygame.K_RIGHT:
current_piece.x += 1
if not(valid_space(current_piece, grid)):
current_piece.x -= 1
if event.key == pygame.K_DOWN:
current_piece.y += 1
if not(valid_space(current_piece, grid)):
current_piece.y -= 1
if event.key == pygame.K_UP:
current_piece.rotation += 1
if not(valid_space(current_piece, grid)):
current_piece.rotation -= 1
shape_pos = convert_shape_format(current_piece)
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
score += clear_rows(grid, locked_positions) * 10
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
draw_text_middle(win, "YOU LOST!", 80, (255,255,255))
pygame.display.update()
pygame.time.delay(1500)
run = False
update_score(score)
def main_menu(win): # *
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
main(win)
pygame.display.quit()
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
还有另一个更新高分的文件:
def update_score(nscore):
score = max_score()
with open('scores.txt', 'w') as f:
if int(score) > nscore:
f.write(str(score))
else:
f.write(str(nscore))
def max_score():
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
return score
I recently followed a Youtube tutorial for a Tetris game, The error only seems to happen on the main game screen when you try to exit the program entirely, if you exit on the start screen it closes perfectly fine. If I close out on the main game screen, the following errors populate:
File "C:\Users\OneDrive\import pygame", line 400, in <module>
main_menu(win)
File "C:\Users\OneDrive\import pygame", line 393, in main_menu
main(win)
File "C:\Users\OneDrive\import pygame", line 371, in main
draw_window(win, grid, score, last_score)
File "C:\Users\OneDrive\import pygame", line 265, in draw_window
surface.fill((0, 0, 0))
pygame.error: display Surface quit
Here is a breakdown of each block of code:
Line 265:
def draw_window(surface, grid, score=0, last_score = 0):
surface.fill((0, 0, 0))
pygame.font.init()
font = pygame.font.SysFont('comicsans', 60)
label = font.render('Tetris', 1, (255, 255, 255))
Line 371
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
Line 383-395
def main_menu(win):
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
main(win)
pygame.display.quit()
Line 398 - 400
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
I compared mine word for word against the source code, and it seems the source code also has this issue from what I can see. I am brand new to coding and would appreciate any help given! I have the full thing pasted below. I just want it to be able to close out perfectly whenever the user chooses to do so. Here is the link to the Source code I followed (https://www.techwithtim.net/tutorials/game-development-with-python/tetris-pygame/tutorial-4/)
import pygame
import random
pygame.font.init()
s_width = 800
s_height = 700
play_width = 300 # meaning 300 // 10 = 30 width per block
play_height = 600 # meaning 600 // 20 = 30 height per block
block_size = 30
top_left_x = (s_width - play_width) // 2
top_left_y = s_height - play_height
# SHAPE FORMATS
S = [['.....',
'.....',
'..00.',
'.00..',
'.....'],
['.....',
'..0..',
'..00.',
'...0.',
'.....']]
Z = [['.....',
'.....',
'.00..',
'..00.',
'.....'],
['.....',
'..0..',
'.00..',
'.0...',
'.....']]
I = [['..0..',
'..0..',
'..0..',
'..0..',
'.....'],
['.....',
'0000.',
'.....',
'.....',
'.....']]
O = [['.....',
'.....',
'.00..',
'.00..',
'.....']]
J = [['.....',
'.0...',
'.000.',
'.....',
'.....'],
['.....',
'..00.',
'..0..',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'...0.',
'.....'],
['.....',
'..0..',
'..0..',
'.00..',
'.....']]
L = [['.....',
'...0.',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..0..',
'..00.',
'.....'],
['.....',
'.....',
'.000.',
'.0...',
'.....'],
['.....',
'.00..',
'..0..',
'..0..',
'.....']]
T = [['.....',
'..0..',
'.000.',
'.....',
'.....'],
['.....',
'..0..',
'..00.',
'..0..',
'.....'],
['.....',
'.....',
'.000.',
'..0..',
'.....'],
['.....',
'..0..',
'.00..',
'..0..',
'.....']]
shapes = [S, Z, I, O, J, L, T]
shape_colors = [(0, 255, 0), (255, 0, 0), (0, 255, 255), (255, 255, 0), (255, 165, 0), (0, 0, 255), (128, 0, 128)]
# index 0 - 6 represent shape
class Piece(object): # *
def __init__(self, x, y, shape):
self.x = x
self.y = y
self.shape = shape
self.color = shape_colors[shapes.index(shape)]
self.rotation = 0
def create_grid(locked_pos={}): # *
grid = [[(0,0,0) for _ in range(10)] for _ in range(20)]
for i in range(len(grid)):
for j in range(len(grid[i])):
if (j, i) in locked_pos:
c = locked_pos[(j,i)]
grid[i][j] = c
return grid
def convert_shape_format(shape):
positions = []
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
positions.append((shape.x + j, shape.y + i))
for i, pos in enumerate(positions):
positions[i] = (pos[0] - 2, pos[1] - 4)
return positions
def valid_space(shape, grid):
accepted_pos = [[(j, i) for j in range(10) if grid[i][j] == (0,0,0)] for i in range(20)]
accepted_pos = [j for sub in accepted_pos for j in sub]
formatted = convert_shape_format(shape)
for pos in formatted:
if pos not in accepted_pos:
if pos[1] > -1:
return False
return True
def check_lost(positions):
for pos in positions:
x, y = pos
if y < 1:
return True
return False
def get_shape():
return Piece(5, 0, random.choice(shapes))
def draw_text_middle(surface, text, size, color):
font = pygame.font.SysFont("comicsans", size, bold=True)
label = font.render(text, 1, color)
surface.blit(label, (top_left_x + play_width /2 - (label.get_width()/2), top_left_y + play_height/2 - label.get_height()/2))
def draw_grid(surface, grid):
sx = top_left_x
sy = top_left_y
for i in range(len(grid)):
pygame.draw.line(surface, (128,128,128), (sx, sy + i*block_size), (sx+play_width, sy+ i*block_size))
for j in range(len(grid[i])):
pygame.draw.line(surface, (128, 128, 128), (sx + j*block_size, sy),(sx + j*block_size, sy + play_height))
def clear_rows(grid, locked):
inc = 0
for i in range(len(grid)-1, -1, -1):
row = grid[i]
if (0,0,0) not in row:
inc += 1
ind = i
for j in range(len(row)):
try:
del locked[(j,i)]
except:
continue
if inc > 0:
for key in sorted(list(locked), key=lambda x: x[1])[::-1]:
x, y = key
if y < ind:
newKey = (x, y + inc)
locked[newKey] = locked.pop(key)
return inc
def draw_next_shape(shape, surface):
font = pygame.font.SysFont('comicsans', 30)
label = font.render('Next Shape', 1, (255,255,255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height/2 - 100
format = shape.shape[shape.rotation % len(shape.shape)]
for i, line in enumerate(format):
row = list(line)
for j, column in enumerate(row):
if column == '0':
pygame.draw.rect(surface, shape.color, (sx + j*block_size, sy + i*block_size, block_size, block_size), 0)
surface.blit(label, (sx + 10, sy - 30))
def update_score(nscore):
score = max_score()
with open('scores.txt', 'w') as f:
if int(score) > nscore:
f.write(str(score))
else:
f.write(str(nscore))
def max_score():
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
return score
def draw_window(surface, grid, score=0, last_score = 0):
surface.fill((0, 0, 0))
pygame.font.init()
font = pygame.font.SysFont('comicsans', 60)
label = font.render('Tetris', 1, (255, 255, 255))
surface.blit(label, (top_left_x + play_width / 2 - (label.get_width() / 2), 30))
# current score
font = pygame.font.SysFont('comicsans', 30)
label = font.render('Score: ' + str(score), 1, (255,255,255))
sx = top_left_x + play_width + 50
sy = top_left_y + play_height/2 - 100
surface.blit(label, (sx + 20, sy + 160))
# last score
label = font.render('High Score: ' + last_score, 1, (255,255,255))
sx = top_left_x - 200
sy = top_left_y + 200
surface.blit(label, (sx + 20, sy + 160))
for i in range(len(grid)):
for j in range(len(grid[i])):
pygame.draw.rect(surface, grid[i][j], (top_left_x + j*block_size, top_left_y + i*block_size, block_size, block_size), 0)
pygame.draw.rect(surface, (255, 0, 0), (top_left_x, top_left_y, play_width, play_height), 5)
draw_grid(surface, grid)
#pygame.display.update()
def main(win): # *
last_score = max_score()
locked_positions = {}
grid = create_grid(locked_positions)
change_piece = False
run = True
current_piece = get_shape()
next_piece = get_shape()
clock = pygame.time.Clock()
fall_time = 0
fall_speed = 0.27
level_time = 0
score = 0
while run:
grid = create_grid(locked_positions)
fall_time += clock.get_rawtime()
level_time += clock.get_rawtime()
clock.tick()
if level_time/1000 > 5:
level_time = 0
if level_time > 0.12:
level_time -= 0.005
if fall_time/1000 > fall_speed:
fall_time = 0
current_piece.y += 1
if not(valid_space(current_piece, grid)) and current_piece.y > 0:
current_piece.y -= 1
change_piece = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_piece.x -= 1
if not(valid_space(current_piece, grid)):
current_piece.x += 1
if event.key == pygame.K_RIGHT:
current_piece.x += 1
if not(valid_space(current_piece, grid)):
current_piece.x -= 1
if event.key == pygame.K_DOWN:
current_piece.y += 1
if not(valid_space(current_piece, grid)):
current_piece.y -= 1
if event.key == pygame.K_UP:
current_piece.rotation += 1
if not(valid_space(current_piece, grid)):
current_piece.rotation -= 1
shape_pos = convert_shape_format(current_piece)
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
score += clear_rows(grid, locked_positions) * 10
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
draw_text_middle(win, "YOU LOST!", 80, (255,255,255))
pygame.display.update()
pygame.time.delay(1500)
run = False
update_score(score)
def main_menu(win): # *
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
main(win)
pygame.display.quit()
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
There is also another file which updates the High score:
def update_score(nscore):
score = max_score()
with open('scores.txt', 'w') as f:
if int(score) > nscore:
f.write(str(score))
else:
f.write(str(nscore))
def max_score():
with open('scores.txt', 'r') as f:
lines = f.readlines()
score = lines[0].strip()
return score
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
main_menu()
运行main(Main()
,当您关闭窗口时,它不会停止程序,但仅关闭窗口,然后返回到main_menu()< /code>运行自己的循环,并且它试图访问窗口(显示菜单)
一个解决方案是在<<<
sys.exit()
(或exit()exit()
)中使用代码> main()一次停止程序。其他解决方案是在
main_menu()
main(Main()之后,使用run = false
也停止了此循环。但是,当您在游戏中
松散
时,此方法需要修改才能继续运行。它可能需要使用
返回true
,返回false
inmain()
,并且它
main_menu()
使用此<代码>是/false 关闭循环main_menu()
runsmain()
and when you close window then it doesn't stop program but it only close window and it goes back tomain_menu()
which runs own loop and it tries to access window (to display menu)One solution is to use
sys.exit()
(orexit()
) inmain()
to stop program at once.Other solution is to use
run = False
inmain_menu()
aftermain()
to stop this loop too.but this method needs modification to keep running when you
loose
in game.It may need to use
return True
,return False
inmain()
and it
main_menu()
use thisTrue/False
to close loop