You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

问题原因

  1. 绿色矩形被后续绘制覆盖:在遍历地图像素的循环中,遇到值为2的像素时先绘制大绿色矩形,但后续循环会继续处理其他像素,在绿色矩形的区域上逐个绘制1x1的黑白小矩形,将绿色区域几乎完全覆盖,最终仅留下最初的(x,y)位置的绿色像素未被覆盖,看起来就是1x1的矩形。

  2. pygame.draw.rect参数使用错误:绘制普通像素时,错误地将矩形参数写成(x*zoom, y*zoom, x*zoom + zoom, y*zoom + zoom),第三、四个参数应为宽度和高度,而非右下角坐标。虽然当前zoom=1时结果看似正常,但属于错误写法,zoom>1时会导致矩形尺寸异常。

  3. 窗口尺寸与坐标逻辑错位:创建窗口时使用(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:14:51