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

使用pygame surface.blits的area参数时触发SystemError求助

解决pygame Surface.blits()带area参数触发SystemError的问题

嗨,我仔细看了你的代码,问题的根源其实很明确:你生成的area区域超出了tilemap的范围,而且blits()方法对这种越界情况的处理和单个blit()不一样——单个blit()会自动裁剪超出源Surface的区域,但blits()遇到无效的area时会直接抛出错误。

具体原因分析

你用random.randint(0, size)生成xi和yi,这里的size=4,所以取值范围是0到4(包含4)。假设你的tilemap是4×64=256px的正方形(和你的屏幕尺寸对应),当xi=4时,xi*tilesize=256,对应的area区域是(256, yi*64, 64, 64)——这个区域的左边界已经等于tilemap的宽度,整个区域完全超出了tilemap的有效范围,blits()遇到这种无效参数就会触发SystemError。

而单个调用screen.blit(*blit_args)时,pygame会自动忽略超出源Surface的部分,所以不会报错,这就是为什么两种调用方式表现不一致的原因。

修复后的代码

只需要把随机数生成的上限改成size-1,确保生成的area区域始终在tilemap范围内:

import sys
import random
import pygame
pygame.init()
tilemap = pygame.image.load('pattern.jpg')
tilesize = 64
size = 4
w, h = size*64, size*64
screen = pygame.display.set_mode((w, h))
while True:
    screen.fill((0, 0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    blit_list = []
    for i in range(size):
        for j in range(size):
            # 把上限从size改成size-1,避免area越界
            xi, yi = random.randint(0, size-1), random.randint(0, size-1)
            blit_args = (tilemap, (i*tilesize, j*tilesize), (xi*tilesize, yi*tilesize, tilesize, tilesize))
            # 可以注释掉单个blit调用,改用blits优化
            # screen.blit(*blit_args)
            blit_list.append(blit_args)
    # 现在blits可以正常工作了
    screen.blits(blit_list)
    pygame.display.flip()
    pygame.time.wait(1000)

额外建议

为了更稳妥,你可以提前获取tilemap的实际尺寸,动态计算最大允许的偏移量,避免硬编码依赖:

tile_w, tile_h = tilemap.get_size()
max_x = (tile_w // tilesize) - 1
max_y = (tile_h // tilesize) - 1
xi, yi = random.randint(0, max_x), random.randint(0, max_y)

这样无论你的tilemap尺寸是多少,都能保证area区域有效。

内容的提问来源于stack exchange,提问作者BradMcDanel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:10:22