Pygame: Как я могу вращать область поверхности, не мелькая изображения дважды?

Я пытаюсь повернуть весь экран и все объекты на поверхности. Но когда я блюю поверхность, она просто создает новую, оставляя меня с четырьмя. Другими словами; У меня есть два изображения, которые не вращаются, и два, которые вращаются. Я хочу удалить те, которые не вращаются. Я искал часы, пытаясь найти ответы. Но ничего. Возможно ли вообще...? (Вращается при движении мыши.)

# import os
import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((500, 500), pygame.RESIZABLE)
pic = pygame.image.load("image.png")
pic2 = pygame.image.load("image.png")

pygame.display.flip()

angle = 1


while True:
    screen.fill((0, 0, 0))
    screen.blit(pic, (30, 20))
    screen.blit(pic2, (22, 40))
    # This creates a copy and blitz it. So there's 4, when there should be 2.
    # The 2 that are not rotating should not be on the screen.
    screen.blit(pygame.transform.rotate(screen, angle), (100, 0))  # x = 100 so you 
can see the other 2 behind it.
    pygame.display.flip()

    angle += 1

    pygame.event.pump()
    event = pygame.event.wait()
    if event.type == QUIT:
        pygame.display.quit()
    elif event.type == VIDEORESIZE:
        screen = pygame.display.set_mode(event.dict['size'], HWSURFACE | DOUBLEBUF 
| RESIZABLE)
        pygame.display.flip()

person Three Point 14    schedule 02.07.2020    source источник
comment
Каков желаемый результат операции вращения? Что весь экран вращается?   -  person Kingsley    schedule 02.07.2020


Ответы (1)


Код неправильно обрабатывает события, поэтому он вращается только во время движения мыши.

Два изображения постоянно появляются, потому что они перерисовываются в основном цикле. Код рисует их в окне, затем копирует окно, поворачивает его и, наконец, перерисовывает его со смещением вправо. Таким образом, он дублирует то, что уже есть на экране, поэтому вы видите объекты в 4 раза больше.

Формулировка вашего вопроса мне не ясна на 100%, но я думаю, вы просто хотите увидеть изображение этих вращающихся объектов. Итак, первое, что нужно сделать, это создать поверхность за пределами экрана, содержащую эти изображения, и использовать ее для поворота и рисования на реальном экране:

screen = pygame.display.set_mode((400, 400), pygame.RESIZABLE)
pic = pygame.image.load("emitter_128.png")
pic2 = pygame.image.load("big_alien.png")

# Make the original surface to rotate
original_surface = pygame.Surface( ( screen.get_rect().width, screen.get_rect().height ) )
original_surface.fill( (0, 0, 0))
original_surface.blit( pic, (30, 20))
original_surface.blit( pic2, (22, 40))

Затем в основной части кода поверните original_surface и нарисуйте его на экране.

# This creates a copy and blitz it. So there's 4, when there should be 2.
# The 2 that are not rotating should not be on the screen.
screen.fill( ( 0, 0, 50 ) )
if ( rotating ):
    angle += 1
    rotated_surface = pygame.transform.rotate( original_surface, angle )
    rotated_surface_rect = rotated_surface.get_rect()
    rotated_surface_rect.center = screen_centre

screen.blit( rotated_surface, rotated_surface_rect )

Когда квадратные растровые изображения поворачиваются, размер изменяется, поскольку результат (скажем, ромбовидная форма с углом вверх) по-прежнему должен помещаться внутри квадратного растрового изображения. Если вы просто продолжаете рисовать с одной и той же координатой, вращение выглядит шатким.

Один из способов исправить это — нарисовать повернутое растровое изображение вокруг его центра, сохраняя эту центральную точку в одном и том же месте на экране. Это приводит к тому, что растровое изображение кажется вращающимся вокруг себя (вокруг его центроида). Для этого нам нужно переместить центр растрового изображения в желаемую координату экрана. Вот почему нам нужно иметь дело с rotated_surface Rect.

ПРИМЕЧАНИЕ. Ужасная комбинация цветов мигающего фона была выбрана, чтобы проиллюстрировать, какая часть является повернутым растровым изображением, а какая — экраном за ним.

Приносим извинения за низкую частоту кадров анимированного .GIF. Это довольно гладко на экране.

вращающаяся вещь

Код ссылки:

import pygame

pygame.init()
SURFACE = pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE
screen  = pygame.display.set_mode((400, 400), SURFACE )
pic1    = pygame.image.load("emitter_128.png")
pic2    = pygame.image.load("big_alien.png")

# Make the original surface to rotate
original_surface = pygame.Surface( ( screen.get_rect().width, screen.get_rect().height ) )
original_surface.fill( (0, 0, 0))
original_surface.blit( pic1, (30, 20))
original_surface.blit( pic2, (22, 40))

# We need to centre the image so the rotation looks smooth
screen_centre = ( screen.get_rect().width//2, screen.get_rect().height//2 )

angle = 1
rotating = True  # used to pause rotation
running  = True  # used to exit
while running:
    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            running = False          # exit
        elif ( event.type == pygame.KEYDOWN ):
            rotating = not rotating  # pause rotation on any key
        elif ( event.type == pygame.VIDEORESIZE ):
            screen = pygame.display.set_mode(event.dict['size'], SURFACE )
            screen_centre = ( screen.get_rect().width//2, screen.get_rect().height//2 )

    # This creates a copy and blitz it. So there's 4, when there should be 2.
    # The 2 that are not rotating should not be on the screen.
    # screen.fill( ( 0, 0, 50 ) ) - use for horrible background
    screen.fill( ( 0, 0, 0 ) )
    if ( rotating ):
        angle += 1
        rotated_surface = pygame.transform.rotate( original_surface, angle )
        rotated_surface_rect = rotated_surface.get_rect()
        rotated_surface_rect.center = screen_centre

    # finally draw the rotated bitmap to the screen
    screen.blit( rotated_surface, rotated_surface_rect )

    # Update the window
    pygame.display.flip()

pygame.display.quit()
person Kingsley    schedule 02.07.2020
comment
Ух ты. Это больше, чем я даже просил. Извините, если я был неясен, кстати. Но да. Я просто хотел повернуть все (два объекта), не удваивая их и получая 4. Но я буду использовать все ваши советы, чтобы улучшить больше. Спасибо за помощь! - person Three Point 14; 02.07.2020