diff --git a/sim_scenes/featured/earth_seasons_1.py b/sim_scenes/featured/earth_seasons_1.py index dd92a8523ab0b5dd591f421bcbeb70edd7949af7..0d8c5a0ca1025bc61480b48163c73a1585c5f49d 100644 --- a/sim_scenes/featured/earth_seasons_1.py +++ b/sim_scenes/featured/earth_seasons_1.py @@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): window_size = (1920 / 3, 1080 / 3) 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): super(EarthSeasonsSim, self).on_ready() diff --git a/sim_scenes/featured/earth_seasons_2.py b/sim_scenes/featured/earth_seasons_2.py index e867914bcb4f531eee3ccf483249122593f2e636..c9d7aa6c35c6807a662cee92a3445821e945092a 100644 --- a/sim_scenes/featured/earth_seasons_2.py +++ b/sim_scenes/featured/earth_seasons_2.py @@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): window_size = (1920 / 3, 1080 / 3) 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): super(EarthSeasonsSim, self).on_ready() diff --git a/sim_scenes/featured/earth_seasons_3.py b/sim_scenes/featured/earth_seasons_3.py index acb35574780c8082ba03f27fe3dd13d59a98b3cd..3b6aaeb709c95f646606e2f21a1197351e9717bd 100644 --- a/sim_scenes/featured/earth_seasons_3.py +++ b/sim_scenes/featured/earth_seasons_3.py @@ -16,7 +16,12 @@ class EarthSeasonsSim(EarthSeasonsSimBase): window_size = (1920 / 3, 1080 / 3) 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): super(EarthSeasonsSim, self).on_ready() diff --git a/sim_scenes/featured/earth_seasons_base.py b/sim_scenes/featured/earth_seasons_base.py index bff49be87daae563f4e2fbd07f436320f334d78b..29ad0a45ce3995b60116f091b4961117bd302ebd 100644 --- a/sim_scenes/featured/earth_seasons_base.py +++ b/sim_scenes/featured/earth_seasons_base.py @@ -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.universe_sim_scenes import UniverseSimScenes from simulators.ursina.entities.body_timer import TimeData, BodyTimer +from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_event import UrsinaEvent +from common.func import find_file 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: self.sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机 else: self.sun = Sun(size_scale=5e1) self.show_sphere_sky = show_sphere_sky 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 个节气的位置创建固定不动的透明地球 - 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", - with_clouds=True, earth_rotation_speed=0.5, - clouds_rotation_speed=0.6) + self.earth, self.earth_clouds, self.earth_cn = create_earth(earth_texture="earth-huge.jpg", + earth_cn_texture="earth-huge-cn.png", + 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] @@ -47,6 +65,11 @@ class EarthSeasonsSimBase(UniverseSimScenes): 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 的角度范围值 self.solar_terms_angles = get_solar_terms_angles() @@ -57,19 +80,87 @@ class EarthSeasonsSimBase(UniverseSimScenes): self.earth_3.planet.rotation_y -= 80 # 秋分 self.earth_4.planet.rotation_y -= 145 # 冬至 - self.earth_1.planet.alpha = 0.3 - self.earth_2.planet.alpha = 0.3 - self.earth_3.planet.alpha = 0.3 - self.earth_4.planet.alpha = 0.3 + self.earth.planet.rotation_y -= 185 # 一开始就正对太阳 + self.earth_cn.planet.rotation_y -= 185 # 一开始就正对太阳 + + 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: self.sky = create_sphere_sky(scale=8000) self.sky.rotation_y = 100 self.sky.rotation_x = 20 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"): 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): """ 控制4个透明地球文本是否显示,防止地球文字的叠加 @@ -84,7 +175,11 @@ class EarthSeasonsSimBase(UniverseSimScenes): e.name_text.enabled = True 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) if self.look_at_earth: # 摄像机始终看向移动的地球 @@ -117,9 +212,8 @@ class EarthSeasonsSimBase(UniverseSimScenes): # position = 左-右+、上+下-、前+后- ursina_run(self.bodies, SECONDS_PER_DAY, position=init_position, # 摄像机和太阳是相同位置 - show_name=True, + show_name=self.show_name, show_grid=False, cosmic_bg='', # show_timer=True, timer_enabled=True) - diff --git a/sim_scenes/featured/jupiter_moon_protects_earth.py b/sim_scenes/featured/jupiter_moon_protects_earth.py index 0183c54d7a36ed8b2dbe8e9ecd17f42c8e8f9833..c42a2270bc4f3150c84d4b59dfab35edb493c549 100644 --- a/sim_scenes/featured/jupiter_moon_protects_earth.py +++ b/sim_scenes/featured/jupiter_moon_protects_earth.py @@ -30,7 +30,7 @@ class JupiterMoonProtectsEarthSim: # 分别保存太阳碰撞次数、木星碰撞次数、地球碰撞次数、月球碰撞次数、木星保护次数、月球保护次数 self.colliding_count = [0, 0, 0, 0, 0, 0] 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.moon = Moon(name="月球", size_scale=3.5e3, # 月球球放大 3000 倍,为了较好的效果,地月距离要比实际大 init_position=[self.earth_moon_d, 0, AU], @@ -47,6 +47,8 @@ class JupiterMoonProtectsEarthSim: self.comets = [] + self.comet_radius = calculate_distance(self.jupiter.position, self.sun.position) * 1.5 + for i in range(comet_num): # 随机生成 comet_num 个石头 comet = self.create_comet(i, gravity_only_for=[self.sun, self.jupiter, self.earth]) @@ -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" 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 - 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 = [0, 0, 0] return pos, vel def create_comet(self, index, gravity_only_for): @@ -81,14 +90,14 @@ class JupiterMoonProtectsEarthSim: # vel = [0, 0, 0] # 石头随机大小 - size_scale = random.randint(600, 1200) * 1.5e4 + size_scale = random.randint(300, 600) * 1.5e4 # 随机创建石头 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), init_position=pos, init_velocity=vel, gravity_only_for=gravity_only_for ) - + rock.set_light_disable(True) # 给石头一个随机旋转的方向和值 rock.rotation = [0, 0, 0] rock.rotation[random.randint(0, 2)] = random.randint(90, 200) / 100 @@ -193,13 +202,15 @@ class JupiterMoonProtectsEarthSim: 0, "0.0%", 0, "0.0%", 0, 0) + camera_look_at(self.sun) self.sky = create_sphere_sky(scale=8000) - self.sky.rotation_y = 100 - self.sky.rotation_x = 20 - self.sky.rotation_z = -65 + # self.sky.rotation_y = 100 + # self.sky.rotation_x = 20 + # self.sky.rotation_z = -65 application.time_scale = 3 + if __name__ == '__main__': """ 木星、月球保护地球模拟 @@ -219,7 +230,7 @@ if __name__ == '__main__': # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(sim.bodies, SECONDS_PER_MONTH * 3, - position=(30000000, 0, -3000000000), + position=(AU, AU * 5, -AU * 5), cosmic_bg='', show_grid=False, show_timer=True) diff --git a/sim_scenes/science/earth_season_func.py b/sim_scenes/science/earth_season_func.py index babe16ec46276d4b0f956e8bb360489c86ad5662..a510e00a0f77fe6cd529d12d4515ca28fcccfd43 100644 --- a/sim_scenes/science/earth_season_func.py +++ b/sim_scenes/science/earth_season_func.py @@ -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, + earth_cn_texture=None, 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: 地球的纹理图片 @@ -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, 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: - return earth + return earth, None, earth_cn # 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点) earth_clouds = Earth(name="", texture=clouds_texture, 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(): diff --git a/sim_scenes/science/earth_seasons.py b/sim_scenes/science/earth_seasons.py index 5ba44d9431dac8e360d15e45c58ed8b5761f398e..e7388796b72e06e23c9e494b7420ff944df67633 100644 --- a/sim_scenes/science/earth_seasons.py +++ b/sim_scenes/science/earth_seasons.py @@ -21,9 +21,9 @@ if __name__ == '__main__': """ sun = Sun(size_scale=5e1, texture="transparent.png") # 太阳使用透明纹理,不会遮挡摄像机 # 在 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] diff --git a/sim_scenes/science/earth_seasons_2.py b/sim_scenes/science/earth_seasons_2.py index b9282fa73b1efd11f005d65c59a2783d4ba00e4b..44d015e50b70bf372f1198b3cd07645424057278 100644 --- a/sim_scenes/science/earth_seasons_2.py +++ b/sim_scenes/science/earth_seasons_2.py @@ -25,7 +25,7 @@ if __name__ == '__main__': 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("寒露") diff --git a/textures/earth-huge-cn.png b/textures/earth-huge-cn.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a2b051e37c74e2e07572a262dddbc6b175da0a Binary files /dev/null and b/textures/earth-huge-cn.png differ