Final exam version
This commit is contained in:
144
solar_model.py
Normal file
144
solar_model.py
Normal file
@@ -0,0 +1,144 @@
|
||||
import math
|
||||
import random
|
||||
from solar_objects import Star, Planet
|
||||
|
||||
|
||||
TICKET_CONFIG = {
|
||||
"window": {"width": 1200, "height": 720, "min_width": 850, "min_height": 560},
|
||||
"stars": [
|
||||
{
|
||||
"name": "Star 1",
|
||||
"planet_count": 11,
|
||||
"planets_per_orbit": 1,
|
||||
"orbit_radii": [70, 85, 100, 115, 130, 145, 160, 175, 190, 205, 220],
|
||||
"color": (255, 190, 40),
|
||||
"mass": 1.989e30,
|
||||
},
|
||||
{
|
||||
"name": "Star 2",
|
||||
"planet_count": 12,
|
||||
"planets_per_orbit": 2,
|
||||
"orbit_radii": [80, 110, 140, 170, 200, 230],
|
||||
"color": (255, 150, 55),
|
||||
"mass": 1.650e30,
|
||||
},
|
||||
],
|
||||
"rules": {"even_orbit_direction": -1, "odd_orbit_direction": 1, "orbits_must_intersect": True},
|
||||
}
|
||||
|
||||
|
||||
SAFE_START_ANGLES = [
|
||||
3.009640, 2.737011, 5.484431, 2.979849, 1.049068, 1.478066,
|
||||
1.191136, 1.579170, 4.454420, 4.226254, 2.025695,
|
||||
0.705927, 3.488630, 2.293706, 6.173658, 0.440441, 5.055767,
|
||||
]
|
||||
|
||||
class SolarSystem:
|
||||
def __init__(self, width=1200, height=720):
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.stars = []
|
||||
self.show_orbits = True
|
||||
self.paused = False
|
||||
self.create_system()
|
||||
self.resize(width, height)
|
||||
|
||||
def create_system(self):
|
||||
self.stars = []
|
||||
|
||||
for star_index, star_data in enumerate(TICKET_CONFIG["stars"]):
|
||||
star = Star(
|
||||
0,
|
||||
0,
|
||||
radius=34,
|
||||
color=star_data["color"],
|
||||
name=star_data["name"],
|
||||
mass=star_data["mass"],
|
||||
)
|
||||
|
||||
planet_count = star_data["planet_count"]
|
||||
planets_per_orbit = star_data["planets_per_orbit"]
|
||||
created = 0
|
||||
|
||||
for orbit_number, orbit_radius in enumerate(star_data["orbit_radii"], start=1):
|
||||
direction = self.get_direction(orbit_number)
|
||||
|
||||
# Ближние к звезде планеты двигаются быстрее, дальние — медленнее.
|
||||
# Скорости и начальные углы подобраны так, чтобы планеты не пересекались.
|
||||
angular_speed = (0.055 / (orbit_number ** 0.45)) * (1.0 if star_index == 0 else 0.945)
|
||||
|
||||
# Начальные углы подобраны заранее: планеты не стартуют кучей и не встречаются на пересечениях орбит.
|
||||
angle_index = created if star_index == 0 else 11 + (orbit_number - 1)
|
||||
base_angle = SAFE_START_ANGLES[angle_index]
|
||||
|
||||
for place in range(planets_per_orbit):
|
||||
if created >= planet_count:
|
||||
break
|
||||
|
||||
# Если на одной орбите две планеты, они стоят напротив друг друга.
|
||||
angle = base_angle + place * (2 * math.pi / planets_per_orbit)
|
||||
planet = Planet(
|
||||
star,
|
||||
orbit_number,
|
||||
orbit_radius,
|
||||
angle,
|
||||
angular_speed,
|
||||
direction,
|
||||
random.uniform(3.0e24, 8.0e24),
|
||||
)
|
||||
star.add_planet(planet)
|
||||
created += 1
|
||||
|
||||
self.stars.append(star)
|
||||
|
||||
def get_direction(self, orbit_number):
|
||||
if orbit_number % 2 == 0:
|
||||
return TICKET_CONFIG["rules"]["even_orbit_direction"]
|
||||
return TICKET_CONFIG["rules"]["odd_orbit_direction"]
|
||||
|
||||
def resize(self, width, height):
|
||||
self.width = width
|
||||
self.height = height
|
||||
center_x = width // 2
|
||||
center_y = height // 2
|
||||
distance = 285
|
||||
self.stars[0].set_position(center_x - distance // 2, center_y)
|
||||
self.stars[1].set_position(center_x + distance // 2, center_y)
|
||||
for star in self.stars:
|
||||
for planet in star.planets:
|
||||
planet.x, planet.y = planet.calculate_position()
|
||||
|
||||
def update(self):
|
||||
if self.paused:
|
||||
return
|
||||
for star in self.stars:
|
||||
star.update()
|
||||
|
||||
def draw(self, screen, pygame):
|
||||
for star in self.stars:
|
||||
star.draw(screen, pygame, self.show_orbits)
|
||||
|
||||
def toggle_pause(self):
|
||||
self.paused = not self.paused
|
||||
|
||||
def toggle_orbits(self):
|
||||
self.show_orbits = not self.show_orbits
|
||||
|
||||
def get_all_planets(self):
|
||||
planets = []
|
||||
for star in self.stars:
|
||||
planets.extend(star.planets)
|
||||
return planets
|
||||
|
||||
def get_all_objects(self):
|
||||
objects = []
|
||||
for star in self.stars:
|
||||
objects.append(star)
|
||||
objects.extend(star.planets)
|
||||
return objects
|
||||
|
||||
def get_total_mass(self):
|
||||
return sum(space_object.mass for space_object in self.get_all_objects())
|
||||
|
||||
def get_planet_count(self):
|
||||
return sum(len(star.planets) for star in self.stars)
|
||||
Reference in New Issue
Block a user