Search code examples
pythonpygamecrash

Pygame crashes after only a few seconds of rendering my code


For some reason, this program crashes after only a second or so of running this. Funnily enough, changing the turnAngle or fps affects how long it lasts before crashing. The error it throws is a ValueError: subsurface rectangle outside of surface area on line 29 / line 9. Any ideas?

import pygame as pg


def rot_center(image, angle):
    orig_rect = image.get_rect()
    rot_image = pg.transform.rotate(image, angle)
    rot_rect = orig_rect.copy()
    rot_rect.center = rot_image.get_rect().center
    rot_image = rot_image.subsurface(rot_rect).copy()
    return rot_image


pg.init()

mainDisplay = pg.display.set_mode([600, 376])

imgSplashBG = pg.image.load('guiAssets/splash/BG.png')
imgSplashFG = pg.image.load('guiAssets/splash/FG.png')
imgSplashRedCircle = pg.image.load('guiAssets/splash/redCircle.png')
imgSplashGreenCircle = pg.image.load('guiAssets/splash/greenCircle.png')

turnAngle = 10

frame = 0
clock = pg.time.Clock()
crashed = False
while not crashed:
    frame += 1
    mainDisplay.blit(imgSplashBG, (0, 0))
    mainDisplay.blit(rot_center(imgSplashGreenCircle, ((frame % 360) * 10)), (-189, -189))
    mainDisplay.blit(rot_center(imgSplashRedCircle, ((frame % 360) * 10)), (453, 230))
    mainDisplay.blit(imgSplashFG, (0, 0))
    pg.display.flip()
    clock.tick(30)

Solution

  • See How do I rotate an image around its center using PyGame?

    Furthermore you have to handle the events in the application loop. See pygame.event.get() respectively pygame.event.pump():

    For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.

    For instance:

    import pygame as pg
    
    def rot_center(image, angle, center):
        rotated_image = pg.transform.rotate(image, angle)
        new_rect = rotated_image.get_rect(center = center)
        return rotated_image, new_rect
    
    pg.init()
    mainDisplay = pg.display.set_mode([600, 376])
    
    imgSplashBG = pg.image.load('guiAssets/splash/BG.png')
    imgSplashFG = pg.image.load('guiAssets/splash/FG.png')
    imgSplashRedCircle = pg.image.load('guiAssets/splash/redCircle.png')
    imgSplashGreenCircle = pg.image.load('guiAssets/splash/greenCircle.png')
    
    turnAngle = 10
    frame = 0
    
    clock = pg.time.Clock()
    run = True
    crashed = False
    while not crashed and run:
    
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False
    
        frame += 1
        angle = (frame*turnAngle) % 360
        centerGreen = (189, 189)
        centerRed = (453, 230)
    
        mainDisplay.blit(imgSplashBG, (0, 0))
        mainDisplay.blit( *rot_center(imgSplashGreenCircle, angle, centerGreen) )
        mainDisplay.blit( *rot_center(imgSplashRedCircle, angle,centerRed) )
        mainDisplay.blit(imgSplashFG, (0, 0))
        pg.display.flip()
        clock.tick(30)
    
    pygame.quit()