Объект заикания Pygame

У меня возникла проблема с программой на Python, использующей pygame. Я хочу заставить солнце в солнечной системе вращаться (вращаться). Частично работает: проблема с каким-то странным "заиканием" солнца при запуске программы. Это заикание повторяется снова и снова, в цикле. Вот код: "

# -*- coding: utf-8 -*-

import pygame as pg
import pygame.locals as local
import sys

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

#deklaration
xres=0
yres=0

#auflösungseinstellungen

try:
    xres=int(sys.argv[1]) #auflösung von der kommandozeile, parameter 1
    yres=int(sys.argv[2]) #auflösung von der kammondozeile, parameter 2

except IndexError:
    xres=800
    yres=600

screen = pg.display.set_mode((xres,yres)) #coords nicht hart coden, variablen nutzen
pg.display.set_caption("future rpg prepreprepalphawhatever")

pg.mouse.set_visible(1)
pg.key.set_repeat(1,30)

clock = pg.time.Clock()


running = 1
rotation_stat = 0.0

while running:
    planet01 = pg.image.load("grafik/menu/planet02.png")
    planet01.set_colorkey((251,0,250), local.RLEACCEL) #load planet01
    sun = pg.image.load("grafik/menu/sun.png") #load sun
    bg = pg.image.load("grafik/menu/bg.png") #load background

    #den hintergrund skalieren, falls auflösung zu hoch
    sizedbg = pg.transform.smoothscale(bg, (xres, yres))

    rotation_stat += 1
    clock.tick(30)
    screen.fill((0,0,0))
    screen.blit(sizedbg, (0,0))
    screen.blit(planet01, (xres/5-planet01.get_width()/2,yres/2-planet01.get_height()/2))

    orig_rect = sun.get_rect()
    sun = pg.transform.rotate(sun, rotation_stat)
    screen.blit(sun, (xres/2-sun.get_width()/2,yres/2-sun.get_height()/2))
    rot_rect = orig_rect.copy()
    rot_rect.center = sun.get_rect().center
    sun = sun.subsurface(rot_rect).copy()


    for event in pg.event.get():
        if event.type == local.QUIT:
            running = 0
        if event.type == local.KEYDOWN:
            if event.key == local.K_ESCAPE:
                pg.event.post(pg.event.Event(local.QUIT))

    pg.display.flip()

person ShadowWolf    schedule 24.03.2012    source источник


Ответы (3)


Поместите код для загрузки изображений вне цикла

person Lie Ryan    schedule 24.03.2012

Я не совсем уверен, но кажется, что вы загружаете изображения каждый раз, когда запускается цикл, который сильно загружает ваш процессор.

person Community    schedule 24.03.2012
comment
Спасибо за ответ, но если я выведу код для загрузки изображений из цикла, солнце разделится и будет вращаться очень странно. - person ShadowWolf; 24.03.2012
comment
Я не совсем уверен, решит ли это вашу проблему, но попробуйте передать DOUBLEBUF в set_mode() следующим образом: self.display_surface = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF) - person ; 24.03.2012
comment
ShadowWolf: это потому, что вы вращаете изображение, которое вы вращали ранее. Повернутое изображение будет больше, а затем вы повернете это, что сделает его больше и т. д. Ваше изображение будет казаться разделенным. - person imallett; 25.03.2012

Я переписал свой ответ на основе ваших комментариев и после просмотра документации pygame

Вам действительно нужно загрузить изображения только один раз. Что я здесь делаю, так это всегда поворачиваю первоначально загруженное солнце на новую поверхность, используя увеличивающееся вращение. Вращение всегда возвращается к 0 градусов. Что касается дрожания, я уверен, что это связано с артефактом алиасинга и, возможно, даже с вашей математикой центрирования. Но моя цель состояла в том, чтобы устранить самый большой удар по производительности, который заключался в чтении вашего изображения солнца с диска каждый кадр (30 раз в секунду).

import pygame as pg
import pygame.locals as local
import sys

def main():
    pg.init()

    xres=800
    yres=600

    try:
        xres=int(sys.argv[1]) 
        yres=int(sys.argv[2]) 

    except IndexError:
        pass

    screen = pg.display.set_mode((xres,yres)) 
    pg.display.set_caption("future rpg prepreprepalphawhatever")

    pg.mouse.set_visible(1)
    pg.key.set_repeat(1,30)

    clock = pg.time.Clock()

    rotation_stat = 0.0

    planet01 = pg.image.load("earth.png")
    planet01.set_colorkey((251,0,250), local.RLEACCEL) #load planet01

    sun = pg.image.load("sun.png") #load sun
    bg = pg.image.load("bg.png") #load background

    sizedbg = pg.transform.smoothscale(bg, (xres, yres))

    planet_pos = (xres/5-planet01.get_width()/2,yres/2-planet01.get_height()/2)

    running = 1

    xres_cent, yres_cent = xres/2, yres/2

    while running:

        clock.tick(30)

        for event in pg.event.get():
            if event.type == local.QUIT:
                running = 0
            if event.type == local.KEYDOWN:
                if event.key == local.K_ESCAPE:
                    pg.event.post(pg.event.Event(local.QUIT))

        rotation_stat += 1
        if rotation_stat % 360 == 0:
            rotation_stat = 0.0

        screen.blit(sizedbg, (0,0))
        screen.blit(planet01, planet_pos)

        sun_rect = sun.get_rect()
        sun_rotated = pg.transform.rotate(sun, rotation_stat)

        center = sun_rotated.get_rect().center
        sun_pos = (xres_cent-center[0], yres_cent-center[1])
        screen.blit(sun_rotated, sun_pos)

        pg.display.flip()

    pg.quit()


if __name__ == "__main__":
    main()
person jdi    schedule 24.03.2012
comment
Спасибо за ответ, но мне нужны xres и yres, чтобы поместить солнце в центр экрана. - person ShadowWolf; 24.03.2012
comment
@ShadowWolf: Хорошо, я только что переписал свой ответ, чтобы указать, как вы загружаете солнце. - person jdi; 24.03.2012
comment
@ShadowWolf: Если этот ответ решил вашу проблему, вы должны принять его с зеленой галочкой. Спасибо! - person jdi; 18.05.2012