I have been struggling lately to add a simple PNG to a circle in Pygame. For some reason all I get is a big black square instead of a circle with a picture inside:
import pygame
from pygame.locals import *
import math
planet_texture = pygame.image.load("earth.png")
""" Initialize pygame """
pygame.init()
""" Define colors """
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (135, 206, 235) # sky blue
YELLOW = (255, 255, 224) # light yellow
RED = (255, 69, 0) # red-orange
""" Define constants """
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
PLANET_RADIUS = 100
ATMOSPHERE_THICKNESS = 70
LIGHT_SOURCE_RADIUS = 15
LIGHT_SOURCE_COLOR = WHITE
LIGHT_SOURCE_POS = (SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2)
""" Create the screen """
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Rayleigh Scattering Simulation")
planet_texture.convert()
""" Main loop """
is_light_source_clicked = False
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
# Check if the mouse is over the light source
x, y = event.pos
if math.sqrt((x - LIGHT_SOURCE_POS[0]) ** 2 + (y - LIGHT_SOURCE_POS[1]) ** 2) <= LIGHT_SOURCE_RADIUS:
is_light_source_clicked = True
elif event.type == MOUSEBUTTONUP and event.button == 1:
is_light_source_clicked = False
# Get the position of the mouse
mouse_pos = pygame.mouse.get_pos()
# Move the light source if it is clicked
if is_light_source_clicked:
LIGHT_SOURCE_POS = mouse_pos
# clear the disaply
screen.fill(0)
# Create a new surface with the same size as the circle
image_surface = pygame.Surface((PLANET_RADIUS * 2, PLANET_RADIUS * 2))
# Get the rect of the image surface
image_rect = planet_texture.get_rect()
# Set the center of the image rect to the center of the circle
image_rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
# Blit the planet texture onto the new surface
image_surface.blit(planet_texture, (0, 0))
# Scale the image to fit inside the circle
scaled_image = pygame.transform.scale(image_surface, (PLANET_RADIUS * 2, PLANET_RADIUS * 2))
# Create a rect for the scaled image and set its center to the center of the circle
scaled_image_rect = scaled_image.get_rect()
scaled_image_rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
# Draw the planet
pygame.draw.circle(screen, BLACK, (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), PLANET_RADIUS)
# Draw the atmosphere
for i in range(1, ATMOSPHERE_THICKNESS + 1):
alpha = int((math.sin(math.pi * i / (2 * ATMOSPHERE_THICKNESS))) * 255)
color = (BLUE[0], BLUE[1], BLUE[2], alpha)
pygame.draw.circle(screen, color, (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), PLANET_RADIUS + i, i)
# Draw the light source
pygame.draw.circle(screen, LIGHT_SOURCE_COLOR, LIGHT_SOURCE_POS, LIGHT_SOURCE_RADIUS)
# Blit the scaled image onto the screen
screen.blit(scaled_image, scaled_image_rect)
# Update the screen
pygame.display.update()
""" Quit pygame """
pygame.quit()
I don't know if it's the order of operation, or if I'm missing a step. I'm not totally familiar with the pygame library yet.
EDIT: I have found my own way of solving this problem:
# Create a new surface with the same size as the image
image_surface = pygame.Surface((image.get_width(), image.get_height()))
image_surface.fill(WHITE) # replace this with your desired color
image_surface.set_colorkey(WHITE)
# Draw the planet on the new surface
pygame.draw.circle(image_surface, BLACK, (image.get_width() // 2, image.get_height() // 2), PLANET_RADIUS)
# Blit the planet texture onto the new surface
image_surface.blit(image, (0,0))
# Center the new surface on the screen
image_rect = image_surface.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
# Blit the new surface onto the screen
screen.blit(image_surface, image_rect)
# Draw the atmosphere
for i in range(1, ATMOSPHERE_THICKNESS + 1):
alpha = int((math.sin(math.pi * i / (2 * ATMOSPHERE_THICKNESS))) * 255)
color = (BLUE[0], BLUE[1], BLUE[2], alpha)
pygame.draw.circle(screen, color, (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2), PLANET_RADIUS + i, i)
# Draw the light source
pygame.draw.circle(screen, LIGHT_SOURCE_COLOR, LIGHT_SOURCE_POS, LIGHT_SOURCE_RADIUS)
# Update the screen
pygame.display.update()```