# -*- coding:utf-8 -*- # title :虫洞效果模拟 # description :虫洞效果模拟 # author :Python超人 # date :2023-11-03 # link :https://gitcode.net/pythoncr/ # python_version :3.9 # ============================================================================== from bodies import Sun, Earth from bodies.universe_body import create_universe_body from common.consts import SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU from objs import Obj, SpaceShip, StarWarsSpeeder, ScifiGunship, SciFiBomber, CoreValagaClas from sim_scenes.func import mayavi_run, mpl_run, ursina_run, camera_look_at, two_bodies_colliding from ursina import camera, application, lerp from bodies import Body from simulators.ursina.ursina_event import UrsinaEvent ours_cosmic_bg = "cosmic_pan_1.jpg" worms_cosmic_bg = "cosmic_pan_4.jpg" class WormholeSim: SIZE_SCALE = 1 # 生成的太阳放大 50 倍 RUN_DIAMETER = 1.392e6 velocity_rate = 22 def __init__(self): self.camera_target = CoreValagaClas(name="摄像机目标", mass=1e30, color=(111, 140, 255), # init_position=[0, 0, 0], init_position=[0, 0, AU / 10], init_velocity=[0, 0, 0], size_scale=WormholeSim.SIZE_SCALE * 1e1) # .set_ignore_gravity(True) self.universes = [] self.ours_universe = create_universe_body("我们的宇宙", "cosmic_pan_1.jpg", size_scale=WormholeSim.SIZE_SCALE, init_position=[0, 0, -AU / 120], init_velocity=[0, 0, 0], ) self.universes.append(self.ours_universe) self.worm_hole = create_universe_body("虫洞1", "cosmic_pan_4.jpg", init_position=[0, 0, AU / 120], init_velocity=[0, 0, 0], size_scale=WormholeSim.SIZE_SCALE) self.universes.append(self.worm_hole) self.bodies = [self.camera_target] + self.universes def on_ready(self): """ 事件绑定后,模拟器运行前会触发 @return: """ # 创建天空 camera.clip_plane_near = 0.001 camera.clip_plane_far = 10000000000000 # create_sphere_sky(scale=200000) application.time_scale = 0.001 # camera.scale = 1000 # camera.parent = camera_target.planet # camera.rotation_x = 90 camera.fov = 120 self.worm_hole.planet.rotation_y = 30 self.ours_universe.planet.rotation_y = 130 camera_look_at(self.camera_target) camera.collider = "sphere" self.worm_hole.planet.collider = "sphere" self.ours_universe.planet.init_scale = self.SIZE_SCALE * 1000 self.camera_target.current_universe = self.ours_universe self.camera_target.targe_universe = self.worm_hole # camera_position = camera.position def on_timer_changed(self, time_data): # return # pass # camera_look_at(camera_target) # camera.rotation_x -= 2 self.camera_target.planet.look_at(self.camera_target.targe_universe.planet) if camera.intersects(self.camera_target.targe_universe.planet).hit: # worm_hole.planet.init_scale = SIZE_SCALE * 1000 self.camera_target.current_universe.planet.init_scale = self.SIZE_SCALE if self.camera_target.targe_universe.planet.init_scale < self.SIZE_SCALE * 1000: self.camera_target.targe_universe.planet.init_scale *= 1.1 # if ours_universe.planet.init_scale > SIZE_SCALE: # ours_universe.planet.init_scale /= 1.1 if not hasattr(camera, "init_rotation_y"): camera.init_rotation_y = camera.rotation_y camera.rotation_y_v = 0.01 if abs(camera.init_rotation_y - camera.rotation_y) < 10: camera.rotation_y_v += 0.5 elif abs(camera.init_rotation_y - camera.rotation_y) < 90: camera.rotation_y_v += 0.3 elif abs(camera.init_rotation_y - camera.rotation_y) < 120: camera.rotation_y_v -= 0.1 elif abs(camera.init_rotation_y - camera.rotation_y) < 180: camera.rotation_y_v -= 0.01 if camera.rotation_y_v < 0.1: camera.rotation_y_v = 0.1 else: camera.rotation_y_v = 0 camera.rotation_y += camera.rotation_y_v # camera_look_at(ours_universe) # else: # if two_bodies_colliding(camera_target, worm_hole): # camera_target.stop_and_ignore_gravity() # print(1,camera_target.planet.position) # camera_target.planet.position = lerp(camera_target.planet.position, worm_hole.planet.position, 1e-2) # print(2,camera_target.planet.position) # camera.position = (camera.position[0],camera.position[1],camera.position[2]) # camera.position = lerp(camera.position, self.camera_target.planet.position, 0.2e-2) # camera_position = [camera_position[0], camera_position[1], camera_position[2] - 0.01] # camera.position = camera_position def build_events(self): # 订阅事件后,上面2个函数功能才会起作用 # 运行中,每时每刻都会触发 on_timer_changed UrsinaEvent.on_timer_changed_subscription(wormhole_sim.on_timer_changed) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(wormhole_sim.on_ready) def run(self): self.build_events() # 使用 ursina 查看的运行效果 # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 # position = 左-右+、上+下-、前+后- ursina_run(self.bodies, SECONDS_PER_DAY / 24, # position=(0, AU / 1200, -1.003 * AU), # position=[-AU/100, 0, 0], position=[0, 0, -AU / 10], cosmic_bg='', # gravity_works=False, timer_enabled=True, show_grid=False, show_trail=False) if __name__ == '__main__': """ """ wormhole_sim = WormholeSim() wormhole_sim.run()