使用Python Turtle开发Breakout游戏时图像无法居中及右侧竖线不显示问题
Breakout游戏砖块居中与边界线显示问题修复
问题描述
使用Python turtle模块开发Breakout游戏时遇到两个问题:
- 砖块布局无法正确居中
- 窗口右侧边界竖线初始不显示,仅拖动窗口侧边后才会出现
原始代码
from turtle import Turtle class Game(): def __init__(self): self.t = Turtle() self.t.screen.title('Object-oriented turtle demo') self.t.screen.bgcolor("black") self.t.screen.setup(width=1000, height=900, startx=None, starty=None) self.t.hideturtle() self.t.penup() self.t.goto(0, 0) self.t.dot(10, "white") # white dot in the center self.blocks = [] self.t.screen.tracer(0) print(self.t.screen.window_width()) def draw_block(self, x, y, width, height, colour): self.t.penup() self.t.goto(x, y) self.t.setheading(0) self.t.pendown() self.t.fillcolor(colour) self.t.begin_fill() for _ in range(2): self.t.forward(width) self.t.right(90) self.t.forward(height) self.t.right(90) self.t.end_fill() def draw_board(self): colours = ["red", "orangered", "dark orange", "orange", "yellow", "yellow green", "green", "turquoise", "blue", "dark blue"] block_width = 80 block_height = 30 block_spacing_x = 10 # Space between blocks block_spacing_y = 40 num_columns = 11 num_rows = 10 window_width = self.t.screen.window_width() total_width_blocks = num_columns * block_width total_spacing = (num_columns - 1) * block_spacing_x total_grid_width = total_width_blocks + total_spacing # Calculate the starting point start_x = -total_grid_width / 2 window_height = self.t.screen.window_height() start_y = (window_height / 2) - block_height - 20 # small margin on top for row in range(num_rows): for column in range(num_columns): x = start_x + column * (block_width + block_spacing_x) y = start_y - row * block_spacing_y self.draw_block(x, y, width=block_width, height=block_height, colour=colours[row]) self.blocks.append({ "x": x, "y": y, "width": block_width, "height": block_height, "color": colours[row], "active": True }) print("Hello") self.draw_vertical_line() self.draw_horizontal_line()# self.t.screen.update() #self.t.screen.mainloop() def draw_vertical_line(self): self.t.pencolor("white") self.t.penup() altura_janela = self.t.screen.window_height() self.t.goto(self.t.screen.window_width() / 2, window_height / 2) self.t.setheading(270) self.t.pendown() self.t.forward(altura_janela) self.t.penup() self.t.goto(-self.t.screen.window_width() / 2, window_height/ 2) self.t.setheading(270) self.t.pendown() self.t.forward(window_height) def draw_horizontal_line(self): self.t.pencolor("white") self.t.penup() window_width = self.t.screen.window_width() margin= 20 line_length= largura_janela - 2 * margin line_center = 0 start_x = line_center - line_length/ 2 self.t.goto(start_x, 0) self.t.setheading(0) self.t.pendown() self.t.forward(line_length) # Execute turtle = Game() turtle.draw_board() #turtle.draw_vertical_line() print(turtle.blocks[-1]) print(turtle.blocks[-1]["x"] + turtle.blocks[-1]["width"]) print(turtle.t.screen.window_width() / 2) last_block = turtle.blocks[-1] right_edge = last_block["x"] + last_block["width"] half_screen = turtle.t.screen.window_width() / 2 turtle.t.screen.mainloop()
问题分析
- 窗口尺寸获取时机错误:
__init__中调用window_width()时窗口未完全初始化,得到的不是设置的1000px,导致砖块居中计算偏差。 - 变量名拼写错误:
draw_vertical_line混用葡萄牙语变量altura_janela和未定义的window_height;draw_horizontal_line使用未定义的largura_janela,导致线条绘制失败。 - 边界线坐标被遮挡:竖线坐标刚好在窗口边缘,被窗口边框遮挡,无法显示。
修复方案与代码
修复后的完整代码
from turtle import Turtle class Game(): def __init__(self): self.t = Turtle() self.t.screen.title('Breakout游戏') self.t.screen.bgcolor("black") self.t.screen.setup(width=1000, height=900, startx=None, starty=None) self.t.screen.update() # 确保窗口尺寸完全初始化 self.t.hideturtle() self.t.penup() self.t.goto(0, 0) self.t.dot(10, "white") # 中心标记点 self.blocks = [] self.t.screen.tracer(0) print("窗口宽度:", self.t.screen.window_width()) def draw_block(self, x, y, width, height, colour): self.t.penup() self.t.goto(x, y) self.t.setheading(0) self.t.pendown() self.t.fillcolor(colour) self.t.begin_fill() for _ in range(2): self.t.forward(width) self.t.right(90) self.t.forward(height) self.t.right(90) self.t.end_fill() def draw_board(self): colours = ["red", "orangered", "dark orange", "orange", "yellow", "yellow green", "green", "turquoise", "blue", "dark blue"] block_width = 80 block_height = 30 block_spacing_x = 10 # 砖块横向间距 block_spacing_y = 40 # 砖块纵向间距 num_columns = 11 num_rows = 10 window_width = self.t.screen.window_width() total_width_blocks = num_columns * block_width total_spacing = (num_columns - 1) * block_spacing_x total_grid_width = total_width_blocks + total_spacing # 修正砖块起始X坐标,确保整体居中 start_x = (window_width - total_grid_width) / 2 - window_width / 2 window_height = self.t.screen.window_height() start_y = (window_height / 2) - block_height - 20 # 顶部留边距 for row in range(num_rows): for column in range(num_columns): x = start_x + column * (block_width + block_spacing_x) y = start_y - row * block_spacing_y self.draw_block(x, y, width=block_width, height=block_height, colour=colours[row]) self.blocks.append({ "x": x, "y": y, "width": block_width, "height": block_height, "color": colours[row], "active": True }) self.draw_vertical_line() self.draw_horizontal_line() self.t.screen.update() def draw_vertical_line(self): self.t.pencolor("white") self.t.penup() window_height = self.t.screen.window_height() window_width = self.t.screen.window_width() offset = 2 # 向内偏移避免被边框遮挡 # 右侧竖线 self.t.goto(window_width / 2 - offset, window_height / 2) self.t.setheading(270) self.t.pendown() self.t.forward(window_height) # 左侧竖线 self.t.penup() self.t.goto(-window_width / 2 + offset, window_height / 2) self.t.setheading(270) self.t.pendown() self.t.forward(window_height) def draw_horizontal_line(self): self.t.pencolor("white") self.t.penup() window_width = self.t.screen.window_width() margin = 20 line_length = window_width - 2 * margin # 修正变量名错误 line_center = 0 start_x = line_center - line_length / 2 self.t.goto(start_x, 0) self.t.setheading(0) self.t.pendown() self.t.forward(line_length) # 运行游戏 game = Game() game.draw_board() # 调试输出 last_block = game.blocks[-1] right_edge = last_block["x"] + last_block["width"] half_screen = game.t.screen.window_width() / 2 print("最后一块砖块信息:", last_block) print("最后一块砖块右边缘坐标:", right_edge) print("屏幕半宽:", half_screen) game.t.screen.mainloop()
核心修改说明
- 窗口尺寸初始化:在
__init__中添加screen.update(),确保窗口完全加载后获取正确尺寸。 - 砖块居中计算:调整
start_x的计算逻辑,让砖块整体在窗口内水平居中。 - 变量名统一:替换葡萄牙语变量名为英文,避免未定义错误。
- 边界线偏移:给竖线坐标增加小偏移量,避免被窗口边框遮挡。
内容的提问来源于stack exchange,提问作者João Pedro F
相关产品推荐
相关产品推荐

