# -*- coding:utf-8 -*- # title :地球季节模拟(四季和24节气) # description :地球季节模拟(四季和24节气) # author :Python超人 # date :2023-02-11 # link :https://gitcode.net/pythoncr/ # python_version :3.8 # ============================================================================== from ursina import camera from bodies import Sun, Earth from common.consts import SECONDS_PER_DAY, AU 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_event import UrsinaEvent class EarthSeasonsSim(UniverseSimScenes): window_size = (1920 / 3, 1080 / 3) def __init__(self): self.sun = Sun(size_scale=5e1) # 太阳使用透明纹理,不会遮挡摄像机 # 在 4 个节气的位置创建固定不动的透明地球 self.earth_1, self.earth_2, self.earth_3, self.earth_4 = \ create_important_pos_earths(texture="earth-huge.jpg", size_scale=4.5e3, 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.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08] self.earth.init_velocity = [-23.550875, 0., -18.05398] self.earth_clouds.init_position = [-9.1507536e+07, 0.0000000e+00, 1.1907757e+08] self.earth_clouds.init_velocity = [-23.550875, 0., -18.05398] self.earth.rotate_axis_color = (255, 255, 50) self.earth.rotate_axis_scale = 0.65 self.bodies = [ self.sun, self.earth, self.earth_clouds, self.earth_1, self.earth_2, self.earth_3, self.earth_4, ] # 中国农历24节气表,数据为 节气名称 和 camera.rotation_y 的角度范围值 self.solar_terms_angles = get_solar_terms_angles() def on_ready(self): # 将 4 个节气位置的地球进行旋转,让中国面对太阳 self.earth_1.planet.rotation_y += 115 # 春分 self.earth_2.planet.rotation_y += 15 # 夏至 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.sky = create_sphere_sky(scale=8000) # self.sky.rotation_y = 100 # self.sky.rotation_x = 20 # self.sky.rotation_z = -65 if hasattr(self.earth_clouds, "name_text"): self.earth_clouds.name_text.enabled = False # 摄像机始终看向移动的地球 camera_look_at(self.sun, rotation_z=0) def earth_text_display(self, term_name): """ 控制4个透明地球文本是否显示,防止地球文字的叠加 @param term_name: @return: """ for e in [self.earth_1, self.earth_2, self.earth_3, self.earth_4]: if hasattr(e, "name_text"): if term_name == e.name: e.name_text.enabled = False else: e.name_text.enabled = True def on_timer_changed(self, time_data: TimeData): if time_data.total_days > 400: exit(0) # 根据角度范围判断,显示中国农历24节气 for info in self.solar_terms_angles: if info[1] <= camera.rotation_y < info[2]: term_name = info[0] # 控制4个透明地球文本是否显示,防止地球文字的叠加 self.earth_text_display(term_name) # 地球名称文字显示为相应的节气 if hasattr(self.earth, "name_text"): self.earth.name_text.text = term_name # if term_name == "立春": # 找到立春的位置和速度 # print("position", earth.position) # print("velocity", earth.velocity) # print(camera.rotation_y) def run(self): # 订阅事件后,上面2个函数功能才会起作用 # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(self.on_ready) # 运行中,每时每刻都会触发 on_timer_changed UrsinaEvent.on_timer_changed_subscription(self.on_timer_changed) # 设置计时器的最小时间单位为天 BodyTimer().min_unit = BodyTimer.MIN_UNIT_DAYS # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(self.bodies, SECONDS_PER_DAY * 10, # position=(0, 0, 0), # 摄像机和太阳是相同位置 position=(0, 4 * AU, 0), # 摄像机和太阳是相同位置 # show_name=True, show_grid=False, cosmic_bg='', # show_timer=True, timer_enabled=True) if __name__ == '__main__': """ 摄像机以太阳的视角看地球(四季和24节气) """ sim = EarthSeasonsSim() sim.run()