Out of memory when using pygame.transform.rotate

匿名 (未验证) 提交于 2019-12-03 02:41:02

问题:

I wrote a script that allows a user to control the sprite of an eagle to fly around to learn pygame. It seemed fine until i implemented a rotation function that makes the sprite rotate according to the direction it is flying along. The sprite becomes really fuzzy after moving a short while and an error soon pops up saying out of memory (at this line: eagle_img = pygame.transform.rotate(eagle_img,new_angle-angle))

My code:

# eagle movement script import pygame, math, sys from pygame.locals import * pygame.init() clock = pygame.time.Clock()  # terminate function def terminate():     pygame.quit()     sys.exit()  # incircle function, check if mouse click is inside controller def incircle(coordinates,cir_center,cir_out_rad):     if math.sqrt((coordinates[0]-cir_center[0])**2+\                  (coordinates[1]-cir_center[1])**2) <= cir_out_rad:         return True     return False  # speed function, translates the controller movement into eagle movement def speed(position,cir_center,eagle_speed):     x_dist = position[0] - cir_center[0]     y_dist = position[1] - cir_center[1]     dist = math.sqrt(x_dist**2+y_dist**2)   # distance from controller knob to center     if dist != 0:         return [(x_dist/dist)*eagle_speed,(y_dist/dist)*eagle_speed]     else:         return [0,0]  # rotation function, rotates the eagle image def rotation(position,cir_center):     x_dist = position[0] - cir_center[0]     y_dist = position[1] - cir_center[1]     new_radian = math.atan2(-y_dist,x_dist)     new_radian %= 2*math.pi     new_angle = math.degrees(new_radian)     return new_angle  # screen screenw = 1000 screenh = 700 screen = pygame.display.set_mode((screenw,screenh),0,32) pygame.display.set_caption('eagle movement')  # variables green = (0,200,0) grey = (100,100,100) red = (255,0,0) fps = 60  # controller cir_out_rad = 150    # circle controller outer radius cir_in_rad = 30     # circle controller inner radius cir_center = [screenw-cir_out_rad,int(screenh/2)] position = cir_center    # mouse position  # eagle eaglew = 100 eagleh = 60 eagle_speed = 3 eagle_pos = [screenw/2-eaglew/2,screenh/2-eagleh/2] eagle = pygame.Rect(eagle_pos[0],eagle_pos[1],eaglew,eagleh) eagle_img = pygame.image.load('eagle1.png').convert() eagle_bg_colour = eagle_img.get_at((0,0)) eagle_img.set_colorkey(eagle_bg_colour) eagle_img = pygame.transform.scale(eagle_img,(eaglew,eagleh))  # eagle controls stop_moving = False # becomes True when player stops clicking rotate = False      # becomes True when there is input angle = 90          # eagle is 90 degrees in the beginning  # game loop while True:     # controls     for event in pygame.event.get():         if event.type == QUIT:             terminate()         if event.type == MOUSEBUTTONUP:             stop_moving = True             rotate = False      mouse_input = pygame.mouse.get_pressed()     if mouse_input[0]:         coordinates = pygame.mouse.get_pos()    # check if coordinates is inside controller         if incircle(coordinates,cir_center,cir_out_rad):             position = pygame.mouse.get_pos()             stop_moving = False             rotate = True         else:             cir_center = pygame.mouse.get_pos()             stop_moving = False             rotate = True     key_input = pygame.key.get_pressed()     if key_input[K_ESCAPE] or key_input[ord('q')]:         terminate()      screen.fill(green)      [dx,dy] = speed(position,cir_center,eagle_speed)     if stop_moving:         [dx,dy] = [0,0]     if eagle.left > 0:         eagle.left += dx     if eagle.right < screenw:         eagle.right += dx     if eagle.top > 0:         eagle.top += dy     if eagle.bottom < screenh:         eagle.bottom += dy      if rotate:         new_angle = rotation(position,cir_center)         if new_angle != angle:             eagle_img = pygame.transform.rotate(eagle_img,new_angle-angle)             eagle = eagle_img.get_rect(center=eagle.center)         rotate = False         angle = new_angle      outer_circle = pygame.draw.circle(screen,grey,(cir_center[0],cir_center[1]),\                                   cir_out_rad,3)     inner_circle = pygame.draw.circle(screen,grey,(position[0],position[1]),\                                   cir_in_rad,1)     screen.blit(eagle_img,eagle)     pygame.display.update()     clock.tick(fps) 

Please tell me what's wrong here and how i can improve it. Feel free to try the code out using a sprite named "eagle1.png". Thanks!

回答1:

the reason your eagle picture is becoming blurred is because your continually rotating the same png and not making a copy and rotating that copy while always keeping a non edited picture. here is a function i have always used when rotating square images

def rot_center(image, angle):     """rotate an image while keeping its center and size"""     orig_rect = image.get_rect()     rot_image = pygame.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 

here is one for any shape of picture

def rot_center(image, rect, angle):         """rotate an image while keeping its center"""         rot_image = pygame.transform.rotate(image, angle)         rot_rect = rot_image.get_rect(center=rect.center)         return rot_image,rot_rect 

source from here

as for the "out of memory" error i don't know for sure but i assume the leak is being caused by the rotation of the same png file over and over again. From some research that seems to occur often with other people.

hope this helps clear some things up:)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!