Home > Software design >  subsurface ValueError: 'subsurface rectangle outside surface area'
subsurface ValueError: 'subsurface rectangle outside surface area'

Time:08-18

i am trying to get the images of a spritesheet and adding those to an animation dictionary.

It seems that i am stupid or don't understand how subsurfaces work because i really don't get why there is this error:

ValueError: subsurface rectangle outside surface area

Here is my simplyfied code:

import pygame as pg
pg.init()

animations = {"animation": []}
sprite_frame_number = 18

img = pg.Surface((1440, 80))  # that would be the sprite sheet
size = [int(img.get_width() / sprite_frame_number), img.get_height()]  # so in this case size = [80,80]

for x in range(sprite_frame_number):
    frame_location = [size[0] * x, 0]  # so starting with 0, x moves with each iteration 80 pxl to the right
    img_rect = pg.Rect(frame_location, size)
    
    try:  # i used this to see when it starts to crash
        img = img.subsurface(img_rect)
    except ValueError:
        print(x)        
    
    animations["animation"].append(img)
print(animations)

The ValueError prints for x '1' to '17'. So it crashes after creating one subsurface right?

The print(animations) shows {'idle': [<Surface(80x80x32 SW)>,...] that there are 18 surfaces in my dictionary.

First how is it possible that there is a created rect that is outside the surface area and second why are there 18 surfaces in the dict when it says it is not possible? I am confused.

CodePudding user response:

The problem is that you use the same variable, img, for both the original image and the subsurface. The first time, everything is still working, because the surface stored in the imgvariable is still the original surface. The second however, this surface is replaced by the first subsurface. This surface is not as big as the original surface, causing the rectangle to be outside of the surface area.

The way to fix this is creating a new variable to store the subsurface instead of img. This can be any other name you want, but I would go for new_img:

import pygame as pg
pg.init()

animations = {"animation": []}
sprite_frame_number = 18

img = pg.Surface((1440, 80))  # that would be the sprite sheet
size = [int(img.get_width() / sprite_frame_number), img.get_height()]  # so in this case size = [80,80]

for x in range(sprite_frame_number):
    frame_location = [size[0] * x, 0]  # so starting with 0, x moves with each iteration 80 pxl to the right
    img_rect = pg.Rect(frame_location, size)
    
    new_img = img.subsurface(img_rect)  # not the same variable as img
    animations["animation"].append(new_img)
    
print(animations)
  • Related