pygame doesn't rotate surface
Asked Answered
S

1

2
import pygame

WIDTH, HEIGHT = 1024, 768
pygame.init()
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
skala = pygame.image.load("rock2x3b.jpg")

play = True

if __name__ == "__main__":
    FPS = 60
    clock = pygame.time.Clock()
    square = pygame.Surface((50, 50))
    rotated_square = pygame.transform.rotate(square, 30)
    WIN.blit(skala, (0, 0))
    WIN.blit(rotated_square, (60,60))
    pygame.display.flip()
    while play:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                quit(0)

This code should display rotated square. But see image with the result. Why the rotation doesn't work ?

Sellars answered 24/8, 2023 at 5:37 Comment(0)
T
1

The surface is completely opaque, as it has no alpha channel. You need to create a surface with an alpha channel that allows transparency. If you create a transparent surface, you need to fill it with an opaque color, because initially it is completely transparent:

square = pygame.Surface((50, 50))

square = pygame.Surface((50, 50), pygame.SRCALPHA)
square.fill("black")

Alternatively, you can specify a color key (set_colorkey) that is different from the color of the rectangle to represent the transparent areas:

square = pygame.Surface((50, 50))
square.set_colorkey("black")
square.fill("blue")

A surface usually has 3 color channels (RGB value for each pixel) the alpha channel is an additional channel in which the transparency of a pixel is stored (RGBA).
A surface is always rectangular and axis-aligned. When a surface is rotated, the surface becomes larger (see How do I rotate an image around its center using PyGame?). The new area of the surface must be filled with something. If the surface has no alpha channel and is uniform colored, the new area will always be filled with the color of the surface. The result is a larger solid rectangle. However, if the surface has an alpha channel, the area will be filled with a transparent color.

Compare the results. All rectangles are rotated by 30°, whereas the Surface on which the yellow rectangle was drawn has an alpha canal, the Surface on which the red rectangle was drawn has not. The blue one uses a color key:

import pygame

pygame.init()
window = pygame.display.set_mode((600, 200))
background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *background.get_size(), (128, 128, 128), (64, 64, 64)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
[pygame.draw.rect(background, color, rect) for rect, color in tiles]
clock = pygame.time.Clock()

square = pygame.Surface((100, 100))
square.fill("red")
square_alpha = pygame.Surface((100, 100), pygame.SRCALPHA)
square_alpha.fill("yellow")
square_key = pygame.Surface((100, 100))
square_key.set_colorkey((0, 0, 0))
square_key.fill("blue")
rotated_square = pygame.transform.rotate(square, 30)
rotated_square_alpha = pygame.transform.rotate(square_alpha, 30)
rotated_square_key = pygame.transform.rotate(square_key, 30)

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    window.blit(background, (0, 0))
    window.blit(rotated_square, rotated_square.get_rect(center = (100, 100)))
    window.blit(rotated_square_alpha, rotated_square_alpha.get_rect(center = (300, 100)))
    window.blit(rotated_square_key, rotated_square_key.get_rect(center = (500, 100)))
    pygame.display.flip()
   
pygame.quit()
quit(0)
Thermocline answered 24/8, 2023 at 5:42 Comment(1)
I've spent hours by trying to solve this problem. I tried SRCALPHA or fill the surface. But obviously I didn't try both of them. Thank you for explaining ;-)Sellars

© 2022 - 2024 — McMap. All rights reserved.