提交 b35e0d2c 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 a6359a59
...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): ...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase):
window_size = (1920 / 3, 1080 / 3) window_size = (1920 / 3, 1080 / 3)
def __init__(self): def __init__(self):
super(EarthSeasonsSim, self).__init__(sun_transparent=False, show_sphere_sky=False, look_at_earth=False) super(EarthSeasonsSim, self).__init__(sun_transparent=False,
show_sphere_sky=False,
look_at_earth=False,
exit_at_total_days=400,
earth_cn_size_factor=1.01,
show_name=False)
def on_ready(self): def on_ready(self):
super(EarthSeasonsSim, self).on_ready() super(EarthSeasonsSim, self).on_ready()
......
...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): ...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase):
window_size = (1920 / 3, 1080 / 3) window_size = (1920 / 3, 1080 / 3)
def __init__(self): def __init__(self):
super(EarthSeasonsSim, self).__init__(sun_transparent=False, show_sphere_sky=False, look_at_earth=False) super(EarthSeasonsSim, self).__init__(sun_transparent=False,
show_sphere_sky=False,
look_at_earth=False,
exit_at_total_days=400,
earth_cn_size_factor=1.01,
show_name=False)
def on_ready(self): def on_ready(self):
super(EarthSeasonsSim, self).on_ready() super(EarthSeasonsSim, self).on_ready()
......
...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): ...@@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase):
window_size = (1920 / 3, 1080 / 3) window_size = (1920 / 3, 1080 / 3)
def __init__(self): def __init__(self):
super(EarthSeasonsSim, self).__init__(sun_transparent=False, show_sphere_sky=False, look_at_earth=False) super(EarthSeasonsSim, self).__init__(sun_transparent=False,
show_sphere_sky=False,
look_at_earth=False,
exit_at_total_days=400,
earth_cn_size_factor=1.01,
show_name=False)
def on_ready(self): def on_ready(self):
super(EarthSeasonsSim, self).on_ready() super(EarthSeasonsSim, self).on_ready()
......
...@@ -14,23 +14,41 @@ from sim_scenes.func import ursina_run, camera_look_at, create_sphere_sky ...@@ -14,23 +14,41 @@ from sim_scenes.func import ursina_run, camera_look_at, create_sphere_sky
from sim_scenes.science.earth_season_func import create_important_pos_earths, get_solar_terms_angles, create_earth from sim_scenes.science.earth_season_func import create_important_pos_earths, get_solar_terms_angles, create_earth
from sim_scenes.universe_sim_scenes import UniverseSimScenes from sim_scenes.universe_sim_scenes import UniverseSimScenes
from simulators.ursina.entities.body_timer import TimeData, BodyTimer from simulators.ursina.entities.body_timer import TimeData, BodyTimer
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent from simulators.ursina.ursina_event import UrsinaEvent
from common.func import find_file
class EarthSeasonsSimBase(UniverseSimScenes): class EarthSeasonsSimBase(UniverseSimScenes):
def __init__(self, sun_transparent=True, show_sphere_sky=True, look_at_earth=True): def __init__(self,
sun_transparent=True,
show_sphere_sky=True,
look_at_earth=True,
show_china=True,
exit_at_total_days=375,
earth_cn_size_factor=1.001,
earth_clouds_size_factor=1.01,
show_name=True):
if sun_transparent: if sun_transparent:
self.sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机 self.sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机
else: else:
self.sun = Sun(size_scale=5e1) self.sun = Sun(size_scale=5e1)
self.show_sphere_sky = show_sphere_sky self.show_sphere_sky = show_sphere_sky
self.look_at_earth = look_at_earth self.look_at_earth = look_at_earth
self.show_china = show_china
self.show_name = show_name
self.exit_at_total_days = exit_at_total_days
# 在 4 个节气的位置创建固定不动的透明地球 # 在 4 个节气的位置创建固定不动的透明地球
self.earth_1, self.earth_2, self.earth_3, self.earth_4 = create_important_pos_earths(texture="earth-huge.jpg") self.earth_1, self.earth_2, self.earth_3, self.earth_4 = create_important_pos_earths(texture="earth-huge.jpg",
size_scale=4.9e3,
position_offset=1.0)
# 运动的地球 # 运动的地球
self.earth, self.earth_clouds = create_earth(earth_texture="earth-huge.jpg", self.earth, self.earth_clouds, self.earth_cn = create_earth(earth_texture="earth-huge.jpg",
with_clouds=True, earth_rotation_speed=0.5, earth_cn_texture="earth-huge-cn.png",
clouds_rotation_speed=0.6) with_clouds=True, earth_rotation_speed=0.7,
clouds_rotation_speed=0.78,
earth_cn_size_factor=earth_cn_size_factor,
earth_clouds_size_factor=earth_clouds_size_factor)
# 地球立春的位置和速度 # 地球立春的位置和速度
self.earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08] self.earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08]
...@@ -47,6 +65,11 @@ class EarthSeasonsSimBase(UniverseSimScenes): ...@@ -47,6 +65,11 @@ class EarthSeasonsSimBase(UniverseSimScenes):
self.earth_1, self.earth_2, self.earth_3, self.earth_4, self.earth_1, self.earth_2, self.earth_3, self.earth_4,
] ]
if self.show_china:
self.bodies += [self.earth_cn]
self.wait_days = 10
self.wait_days_count = self.wait_days
# 中国农历24节气表,数据为 节气名称 和 camera.rotation_y 的角度范围值 # 中国农历24节气表,数据为 节气名称 和 camera.rotation_y 的角度范围值
self.solar_terms_angles = get_solar_terms_angles() self.solar_terms_angles = get_solar_terms_angles()
...@@ -57,19 +80,87 @@ class EarthSeasonsSimBase(UniverseSimScenes): ...@@ -57,19 +80,87 @@ class EarthSeasonsSimBase(UniverseSimScenes):
self.earth_3.planet.rotation_y -= 80 # 秋分 self.earth_3.planet.rotation_y -= 80 # 秋分
self.earth_4.planet.rotation_y -= 145 # 冬至 self.earth_4.planet.rotation_y -= 145 # 冬至
self.earth_1.planet.alpha = 0.3 self.earth.planet.rotation_y -= 185 # 一开始就正对太阳
self.earth_2.planet.alpha = 0.3 self.earth_cn.planet.rotation_y -= 185 # 一开始就正对太阳
self.earth_3.planet.alpha = 0.3
self.earth_4.planet.alpha = 0.3 self.earth_clouds.planet.rotation_y -= 50 # 一开始就正对太阳
self.earth_1.planet.alpha = 0.2
self.earth_2.planet.alpha = 0.2
self.earth_3.planet.alpha = 0.2
self.earth_4.planet.alpha = 0.2
if self.show_sphere_sky: if self.show_sphere_sky:
self.sky = create_sphere_sky(scale=8000) self.sky = create_sphere_sky(scale=8000)
self.sky.rotation_y = 100 self.sky.rotation_y = 100
self.sky.rotation_x = 20 self.sky.rotation_x = 20
self.sky.rotation_z = -65 self.sky.rotation_z = -65
if self.show_name:
font = find_file("fonts/DroidSansFallback.ttf", UrsinaConfig.CN_FONT)
from ursina import color
text_scale = self.earth.name_text.scale * 2
self.earth.name_text.scale = text_scale
self.earth_1.name_text.scale = text_scale
self.earth_2.name_text.scale = text_scale
self.earth_3.name_text.scale = text_scale
self.earth_4.name_text.scale = text_scale
self.earth.name_text.font = font
self.earth.name_text.color = color.yellow
self.earth_1.name_text.font = font
self.earth_2.name_text.font = font
self.earth_3.name_text.font = font
self.earth_4.name_text.font = font
if hasattr(self.earth_clouds, "name_text"): if hasattr(self.earth_clouds, "name_text"):
self.earth_clouds.name_text.enabled = False self.earth_clouds.name_text.enabled = False
if self.look_at_earth:
# 摄像机始终看向移动的地球
camera_look_at(self.earth, rotation_z=0)
if self.show_china:
if hasattr(self.earth_cn, "name_text"):
self.earth_cn.name_text.enabled = False
cn_planet = self.earth_cn.planet
origin_update = cn_planet.update
cn_planet.alpha_inc = 0.01
cn_planet.alpha_direct = -1
alpha_range = [0.3, 0.7]
cn_planet.alpha = alpha_range[1]
def cn_blink():
origin_update()
alpha = cn_planet.alpha
alpha += cn_planet.alpha_direct * cn_planet.alpha_inc
if cn_planet.alpha_direct < 0 and alpha < alpha_range[0]:
alpha = alpha_range[0]
cn_planet.alpha_direct = 1
elif cn_planet.alpha_direct > 0 and alpha > alpha_range[1]:
alpha = alpha_range[1]
cn_planet.alpha_direct = -1
cn_planet.alpha = alpha
# print(cn_planet.alpha)
if self.wait_days_count <= 0:
self.earth_cn.planet.alpha = alpha_range[1]
cn_planet.update = origin_update
cn_planet.update = cn_blink
from ursina import application, invoke
def delay_app_start():
import time
time.sleep(8.0)
self.wait_days_count = 0
application.paused = False
import threading
application.paused = True
threading.Thread(target=delay_app_start).start()
# invoke(lambda: app_start, delay=3.0)
def earth_text_display(self, term_name): def earth_text_display(self, term_name):
""" """
控制4个透明地球文本是否显示,防止地球文字的叠加 控制4个透明地球文本是否显示,防止地球文字的叠加
...@@ -84,7 +175,11 @@ class EarthSeasonsSimBase(UniverseSimScenes): ...@@ -84,7 +175,11 @@ class EarthSeasonsSimBase(UniverseSimScenes):
e.name_text.enabled = True e.name_text.enabled = True
def on_timer_changed(self, time_data: TimeData): def on_timer_changed(self, time_data: TimeData):
if time_data.total_days > 375:
if self.show_china and self.wait_days_count > 0:
self.wait_days_count = self.wait_days - time_data.total_days
if time_data.total_days > self.exit_at_total_days:
exit(0) exit(0)
if self.look_at_earth: if self.look_at_earth:
# 摄像机始终看向移动的地球 # 摄像机始终看向移动的地球
...@@ -117,9 +212,8 @@ class EarthSeasonsSimBase(UniverseSimScenes): ...@@ -117,9 +212,8 @@ class EarthSeasonsSimBase(UniverseSimScenes):
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(self.bodies, SECONDS_PER_DAY, ursina_run(self.bodies, SECONDS_PER_DAY,
position=init_position, # 摄像机和太阳是相同位置 position=init_position, # 摄像机和太阳是相同位置
show_name=True, show_name=self.show_name,
show_grid=False, show_grid=False,
cosmic_bg='', cosmic_bg='',
# show_timer=True, # show_timer=True,
timer_enabled=True) timer_enabled=True)
...@@ -30,7 +30,7 @@ class JupiterMoonProtectsEarthSim: ...@@ -30,7 +30,7 @@ class JupiterMoonProtectsEarthSim:
# 分别保存太阳碰撞次数、木星碰撞次数、地球碰撞次数、月球碰撞次数、木星保护次数、月球保护次数 # 分别保存太阳碰撞次数、木星碰撞次数、地球碰撞次数、月球碰撞次数、木星保护次数、月球保护次数
self.colliding_count = [0, 0, 0, 0, 0, 0] self.colliding_count = [0, 0, 0, 0, 0, 0]
self.sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变 self.sun = Sun(name="太阳", size_scale=0.8e2) # 太阳放大 80 倍,距离保持不变
self.jupiter = Jupiter(name="木星", size_scale=0.6e3,distance_scale=0.7) # 木星放大 600 倍,距离保持不变 self.jupiter = Jupiter(name="木星", size_scale=0.6e3, distance_scale=0.7) # 木星放大 600 倍,距离保持不变
self.earth = Earth(name="地球", size_scale=2.5e3) # 地球放大 2000 倍,距离保持不变 self.earth = Earth(name="地球", size_scale=2.5e3) # 地球放大 2000 倍,距离保持不变
self.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大 self.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大
init_position=[self.earth_moon_d, 0, AU], init_position=[self.earth_moon_d, 0, AU],
...@@ -47,6 +47,8 @@ class JupiterMoonProtectsEarthSim: ...@@ -47,6 +47,8 @@ class JupiterMoonProtectsEarthSim:
self.comets = [] self.comets = []
self.comet_radius = calculate_distance(self.jupiter.position, self.sun.position) * 1.5
for i in range(comet_num): for i in range(comet_num):
# 随机生成 comet_num 个石头 # 随机生成 comet_num 个石头
comet = self.create_comet(i, gravity_only_for=[self.sun, self.jupiter, self.earth]) comet = self.create_comet(i, gravity_only_for=[self.sun, self.jupiter, self.earth])
...@@ -57,15 +59,22 @@ class JupiterMoonProtectsEarthSim: ...@@ -57,15 +59,22 @@ class JupiterMoonProtectsEarthSim:
self.colliding_info = "太阳碰撞:%s次(%s)\n\n木星碰撞:%s次(%s)\n\n地球碰撞:%s次(%s)\n\n月球碰撞:%s次(%s)\n\n木星保护:%s次\n\n月球保护:%s次\n\n" self.colliding_info = "太阳碰撞:%s次(%s)\n\n木星碰撞:%s次(%s)\n\n地球碰撞:%s次(%s)\n\n月球碰撞:%s次(%s)\n\n木星保护:%s次\n\n月球保护:%s次\n\n"
def random_pos_vel(self): def random_pos_vel(self):
# 随机生成石头的位置和初始速度信息
radius = calculate_distance(self.jupiter.position, self.sun.position) * 1.5
x = radius * math.cos(random.uniform(0, 2 * math.pi)) * (random.randint(100, 150) / 100)
z = radius * math.sin(random.uniform(0, 2 * math.pi)) * (random.randint(100, 150) / 100)
sun_pos = self.sun.position sun_pos = self.sun.position
pos = [x + sun_pos[0], 0 + sun_pos[1], z + sun_pos[2]] # # 随机生成石头的位置和初始速度信息
radius = self.comet_radius * (random.randint(100, 150) / 100)
rnd_angle = random.randint(0, 360)
# x = radius * math.cos(random.uniform(0, 2 * math.pi)) * (random.randint(100, 150) / 100)
# z = radius * math.sin(random.uniform(0, 2 * math.pi)) * (random.randint(100, 150) / 100)
angle = math.pi * rnd_angle / 180
x = sun_pos[0] + radius * math.cos(angle)
z = sun_pos[2] + radius * math.sin(angle)
pos = [x, 0 + sun_pos[1], z]
# 随机速度 # 随机速度
vel = [-random.randint(90, 200) / 300, 0, 0] vel = [-random.randint(90, 200) / 300, 0, 0]
vel = [0, 0, 0]
return pos, vel return pos, vel
def create_comet(self, index, gravity_only_for): def create_comet(self, index, gravity_only_for):
...@@ -81,14 +90,14 @@ class JupiterMoonProtectsEarthSim: ...@@ -81,14 +90,14 @@ class JupiterMoonProtectsEarthSim:
# vel = [0, 0, 0] # vel = [0, 0, 0]
# 石头随机大小 # 石头随机大小
size_scale = random.randint(600, 1200) * 1.5e4 size_scale = random.randint(300, 600) * 1.5e4
# 随机创建石头 # 随机创建石头
rock = create_rock( rock = create_rock(
no=index % 8 + 1, name=f'岩石{index + 1}', mass=size_scale / 1000, no=index % 7 + 1, name=f'岩石{index + 1}', mass=size_scale / 1000,
size_scale=size_scale, color=(255, 200, 0), size_scale=size_scale, color=(255, 200, 0),
init_position=pos, init_velocity=vel, gravity_only_for=gravity_only_for init_position=pos, init_velocity=vel, gravity_only_for=gravity_only_for
) )
rock.set_light_disable(True)
# 给石头一个随机旋转的方向和值 # 给石头一个随机旋转的方向和值
rock.rotation = [0, 0, 0] rock.rotation = [0, 0, 0]
rock.rotation[random.randint(0, 2)] = random.randint(90, 200) / 100 rock.rotation[random.randint(0, 2)] = random.randint(90, 200) / 100
...@@ -193,13 +202,15 @@ class JupiterMoonProtectsEarthSim: ...@@ -193,13 +202,15 @@ class JupiterMoonProtectsEarthSim:
0, "0.0%", 0, "0.0%",
0, "0.0%", 0, "0.0%",
0, 0) 0, 0)
camera_look_at(self.sun)
self.sky = create_sphere_sky(scale=8000) self.sky = create_sphere_sky(scale=8000)
self.sky.rotation_y = 100 # self.sky.rotation_y = 100
self.sky.rotation_x = 20 # self.sky.rotation_x = 20
self.sky.rotation_z = -65 # self.sky.rotation_z = -65
application.time_scale = 3 application.time_scale = 3
if __name__ == '__main__': if __name__ == '__main__':
""" """
木星、月球保护地球模拟 木星、月球保护地球模拟
...@@ -219,7 +230,7 @@ if __name__ == '__main__': ...@@ -219,7 +230,7 @@ if __name__ == '__main__':
# 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹
# position = 左-右+、上+下-、前+后- # position = 左-右+、上+下-、前+后-
ursina_run(sim.bodies, SECONDS_PER_MONTH * 3, ursina_run(sim.bodies, SECONDS_PER_MONTH * 3,
position=(30000000, 0, -3000000000), position=(AU, AU * 5, -AU * 5),
cosmic_bg='', cosmic_bg='',
show_grid=False, show_grid=False,
show_timer=True) show_timer=True)
...@@ -53,8 +53,10 @@ def create_important_pos_earths(texture="earth_transparent.png", size_scale=5e3, ...@@ -53,8 +53,10 @@ def create_important_pos_earths(texture="earth_transparent.png", size_scale=5e3,
def create_earth(earth_texture="earth_hd.jpg", with_clouds=False, def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
earth_cn_texture=None,
clouds_texture="transparent_clouds.png", clouds_texture="transparent_clouds.png",
earth_rotation_speed=0.5, clouds_rotation_speed=0.5): earth_rotation_speed=0.5, clouds_rotation_speed=0.5,
earth_cn_size_factor=1.001, earth_clouds_size_factor=1.01):
""" """
创建运动的地球(和云层) 创建运动的地球(和云层)
@param earth_texture: 地球的纹理图片 @param earth_texture: 地球的纹理图片
...@@ -69,15 +71,22 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False, ...@@ -69,15 +71,22 @@ def create_earth(earth_texture="earth_hd.jpg", with_clouds=False,
text_color=[255, 255, 255], rotation_speed=earth_rotation_speed, text_color=[255, 255, 255], rotation_speed=earth_rotation_speed,
init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79]) init_position=[-1 * AU, 0, 0], init_velocity=[0, 0, -29.79])
if earth_cn_texture is None:
earth_cn = None
else:
earth_cn = Earth(name="", texture=earth_cn_texture,
rotation_speed=earth_rotation_speed, show_name=False,
size_scale=earth_cn_size_factor * 5e3, parent=earth)
if not with_clouds: if not with_clouds:
return earth return earth, None, earth_cn
# 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点) # 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点)
earth_clouds = Earth(name="", texture=clouds_texture, earth_clouds = Earth(name="", texture=clouds_texture,
rotation_speed=clouds_rotation_speed, show_name=False, rotation_speed=clouds_rotation_speed, show_name=False,
size_scale=1.01 * 5e3, parent=earth) size_scale=earth_clouds_size_factor * 5e3, parent=earth)
return earth, earth_clouds return earth, earth_clouds, earth_cn
def get_solar_terms_angles(): def get_solar_terms_angles():
......
...@@ -21,9 +21,9 @@ if __name__ == '__main__': ...@@ -21,9 +21,9 @@ if __name__ == '__main__':
""" """
sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机 sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机
# 在 4 个节气的位置创建固定不动的透明地球 # 在 4 个节气的位置创建固定不动的透明地球
earth_1, earth_2, earth_3, earth_4 = create_important_pos_earths() earth_1, earth_2, earth_3, earth_4 = create_important_pos_earths(position_offset=1.01)
# 运动的地球 # 运动的地球
earth = create_earth() earth, _, _ = create_earth()
# 地球立春的位置和速度 # 地球立春的位置和速度
earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08] earth.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08]
......
...@@ -25,7 +25,7 @@ if __name__ == '__main__': ...@@ -25,7 +25,7 @@ if __name__ == '__main__':
earth_1, earth_2, earth_3, earth_4 = create_important_pos_earths() earth_1, earth_2, earth_3, earth_4 = create_important_pos_earths()
# 创建运动的地球和云层 # 创建运动的地球和云层
earth, earth_clouds = create_earth(with_clouds=True, earth_rotation_speed=0.5, clouds_rotation_speed=0.8) earth, earth_clouds, _ = create_earth(with_clouds=True, earth_rotation_speed=0.5, clouds_rotation_speed=0.8)
pos_vel = get_earth_pos_vel_by_term_name("寒露") pos_vel = get_earth_pos_vel_by_term_name("寒露")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册