使用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
相关产品推荐
相关产品推荐

