Kod:
import pygame
import math
import sys
# Initialize Pygame
pygame.init()
# Window setup
WIDTH, HEIGHT = 3000, 1500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Solar System Simulator")
# Colors
YELLOW = (255, 255, 0)
GRAY = (169, 169, 169)
# Clock
clock = pygame.time.Clock()
FONT = pygame.font.SysFont("Arial", 50)
INFOFONT = pygame.font.SysFont("Arial", 20)
# Constants
CENTER_SCREEN = (WIDTH // 2, HEIGHT // 2)
SCALE = 150 # visual distance scaling factor
TIMESTEP = 0.001 # orbit speed factor
# Orbital body data: (name, parent, distance (AU), radius (px), color, orbital period (years))
PLANETS = [
("Mercury", "Sun", 0.39, 3, (200, 200, 200), 0.24),
("Venus", "Sun", 0.72, 6, (255, 165, 0), 0.62),
("Earth", "Sun", 1.00, 6, (100, 149, 237), 1.00),
("Moon", "Earth", 0.00257, 2, GRAY, 0.0748),
("Mars", "Sun", 1.52, 5, (255, 0, 0), 1.88),
("Jupiter", "Sun", 5.20, 10, (255, 215, 0), 11.86),
("Saturn", "Sun", 9.58, 9, (210, 180, 140), 29.46),
("Uranus", "Sun", 19.22, 7, (173, 216, 230), 84.01),
("Neptune", "Sun", 30.05, 7, (0, 0, 255), 164.8),
("Pluto", "Sun", 39.48, 2, (220, 220, 220), 248.0)
]
def draw_body(x, y, radius, color):
pygame.draw.circle(WIN, color, (int(x), int(y)), radius)
def get_orbit_position(center, distance, angle):
x = center[0] + distance * math.cos(angle)
y = center[1] + distance * math.sin(angle)
return x, y
def main():
global SCALE
global TIMESTEP
run = True
current_center = "Earth" # Can toggle between "Sun" and "Earth"
angles = {name: 0 for name, *_ in PLANETS}
positions = {"Sun": CENTER_SCREEN}
while run:
clock.tick(60)
WIN.fill((0, 0, 0))
scale_text = FONT.render(f"Scale: {SCALE}", True, (255, 255, 255))
WIN.blit(scale_text, (10, 10))
time_text = FONT.render(f"Timestep: {TIMESTEP}", True, (255, 255, 255))
WIN.blit(time_text, (10, 100))
centre_text = FONT.render(f"Centre: {current_center}", True, (255, 255, 255))
WIN.blit(centre_text, (10, 160))
info_text = INFOFONT.render("Up/down to change timestep, Scroll up/down to change zoom and space to change center", True, (255, 255, 255))
WIN.blit(info_text, (10, 230))
# Get screen center object position
sim_center_pos = positions.get(current_center, CENTER_SCREEN)
offset = (
CENTER_SCREEN[0] - sim_center_pos[0],
CENTER_SCREEN[1] - sim_center_pos[1]
)
# Compute all positions
positions["Sun"] = (0, 0) # temporarily set, will be updated
for name, parent, distance, radius, color, period in PLANETS:
# Update angle
angles[name] += TIMESTEP * 2 * math.pi / period
# Get parent position
parent_pos = positions[parent] if parent in positions else CENTER_SCREEN
# Compute orbit position
x, y = get_orbit_position(parent_pos, distance * SCALE, angles[name])
positions[name] = (x, y)
# After all relative positions, apply offset and draw
for name, _, _, radius, color, _ in PLANETS:
x, y = positions[name]
sx = x + offset[0]
sy = y + offset[1]
draw_body(sx, sy, radius, color)
# Draw the Sun (at fixed or offset location)
sun_x, sun_y = positions["Sun"]
sun_sx = sun_x + offset[0]
sun_sy = sun_y + offset[1]
draw_body(sun_sx, sun_sy, 12, YELLOW)
pygame.display.update()
# Handle events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.MOUSEWHEEL:
SCALE = SCALE + 0.1*SCALE*event.y
#SCALE = max(0.01, min(SCALE, 1000))
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
current_center = "Earth" if current_center == "Sun" else "Sun"
elif event.key == pygame.K_UP:
TIMESTEP *= 1.1 # Increase by 10%
elif event.key == pygame.K_DOWN:
TIMESTEP /= 1.1 # Decrease by ~9%
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()