Pygame绘制矩形异常:指定大尺寸却仅显示1x1像素
Pygame绘制大矩形仅显示1x1像素的问题排查与解决
问题描述
尝试在地图上绘制大绿色矩形标记时,仅能看到1个绿色像素。使用多种pygame.draw.rect写法均得到位置正确但尺寸为1x1的矩形,相关绘制代码如下:
pygame.draw.rect(display, (0, 255, 0), (x, y, 1000, 1000)) # 以下写法也存在同样问题 pygame.draw.rect(display, (0, 255, 0), (x, y, x + 1000, y + 1000)) pygame.draw.rect(display, (0, 255, 0), ((x, y), (x + 1000, y + 1000))) pygame.draw.rect(display, (0, 255, 0), ((x, y), (1000, 1000)))
完整代码:
import pygame, os, sys, ast pygame.init() script_dir = os.path.dirname(os.path.abspath(__file__)) txt_path = os.path.join(script_dir, "map.txt") zoom = 1 with open(txt_path, "r") as file: data = file.read() data = result = ast.literal_eval(data) display = pygame.display.set_mode((len(data), len(data[0]))) x = 0 for line in data: x += 1 y = 0 for pixel in line: y += 1 if pixel == 0: pygame.draw.rect(display, (0, 0, 0), (x* zoom, y * zoom, x* zoom + zoom, y * zoom + zoom)) elif pixel == 2: plus = 200 pygame.draw.rect(display, (0, 255, 0), (x, y, 100, 100)) print(x, y) else: pygame.draw.rect(display, (255, 255, 255), (x* zoom, y * zoom, x* zoom + zoom, y * zoom + zoom)) while True: pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
问题原因
绿色矩形被后续绘制覆盖:在遍历地图像素的循环中,遇到值为2的像素时先绘制大绿色矩形,但后续循环会继续处理其他像素,在绿色矩形的区域上逐个绘制1x1的黑白小矩形,将绿色区域几乎完全覆盖,最终仅留下最初的(x,y)位置的绿色像素未被覆盖,看起来就是1x1的矩形。
pygame.draw.rect参数使用错误:绘制普通像素时,错误地将矩形参数写成(x*zoom, y*zoom, x*zoom + zoom, y*zoom + zoom),第三、四个参数应为宽度和高度,而非右下角坐标。虽然当前zoom=1时结果看似正常,但属于错误写法,zoom>1时会导致矩形尺寸异常。窗口尺寸与坐标逻辑错位:创建窗口时使用
(len(data), len(data[0])),len(data)是地图行数,len(data[0])是列数,而Pygame窗口参数为(width, height),这会导致窗口宽度对应行数、高度对应列数,与常规坐标映射逻辑相反。
解决方法
1. 调整绘制顺序
将大绿色矩形的绘制放在所有普通像素绘制完成之后,避免被后续小矩形覆盖:
import pygame, os, sys, ast pygame.init() script_dir = os.path.dirname(os.path.abspath(__file__)) txt_path = os.path.join(script_dir, "map.txt") zoom = 1 with open(txt_path, "r") as file: data = file.read() data = ast.literal_eval(data) # 修正窗口尺寸:宽度对应列数,高度对应行数 display = pygame.display.set_mode((len(data[0]), len(data))) # 第一步:绘制所有普通像素 for x_idx, line in enumerate(data): for y_idx, pixel in enumerate(line): rect_x = x_idx * zoom rect_y = y_idx * zoom if pixel == 0: pygame.draw.rect(display, (0, 0, 0), (rect_x, rect_y, zoom, zoom)) elif pixel != 2: pygame.draw.rect(display, (255, 255, 255), (rect_x, rect_y, zoom, zoom)) # 第二步:绘制绿色标记矩形 for x_idx, line in enumerate(data): for y_idx, pixel in enumerate(line): if pixel == 2: rect_x = x_idx * zoom rect_y = y_idx * zoom pygame.draw.rect(display, (0, 255, 0), (rect_x, rect_y, 100, 100)) print(rect_x, rect_y) while True: pygame.display.update() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
2. 修正矩形参数写法
将普通像素的绘制参数改为(rect_x, rect_y, zoom, zoom),确保宽度和高度的定义正确。
3. 限制绿色矩形不超出窗口(可选)
如果绿色矩形尺寸过大超出窗口范围,可添加判断裁剪尺寸:
window_width, window_height = display.get_size() rect_width = min(100, window_width - rect_x) rect_height = min(100, window_height - rect_y) pygame.draw.rect(display, (0, 255, 0), (rect_x, rect_y, rect_width, rect_height))
内容的提问来源于stack exchange,提问作者user23558394
相关产品推荐
相关产品推荐

