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

Python超人-宇宙模拟器

上级 b23b32c9
# -*- 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, camera_move_control, \
get_run_speed_factor
from ursina import camera, application, lerp
from bodies import Body
from simulators.ursina.ursina_event import UrsinaEvent
class WormholeSim:
SIZE_SCALE = 1
D = AU / 10 * SIZE_SCALE
def __init__(self):
D = self.D
self.camera_target = CoreValagaClas(name="摄像机目标", mass=1e30, color=(111, 140, 255),
# init_position=[0, 0, 0],
init_position=[D, 0, -D],
init_velocity=[0, 0, 0],
size_scale=self.SIZE_SCALE * 1e2).set_ignore_gravity(True)
self.universes = []
# self.textures = ["cosmic_pan_1.jpg", "cosmic_pan_4.jpg", "cosmic_pan_2.jpg", "cosmic_pan_3.jpg"]
self.create_universes()
self.bodies = [self.camera_target] + self.universes
# self.bodies = self.universes
def create_universe(self, idx, position):
universe_body = create_universe_body(f"宇宙{idx}", texture=f'cosmic_pan_{idx + 1}.jpg', # self.textures[idx],
size_scale=self.SIZE_SCALE,
init_position=position,
init_velocity=[0, 0, 0],
)
return universe_body
def create_universes(self):
D = self.D
positions = [[D, 0, -D], [D, 0, D], [- D, 0, -D], [- D, 0, D],
[D, D, -D], [D, D, D], [- D, D, -D], [- D, D, D],
[D, -D, -D], [D, -D, D], [- D, -D, -D], [- D, -D, D]
]
for idx, pos in enumerate(positions):
self.universes.append(self.create_universe(idx, pos))
def init_setting(self):
camera.clip_plane_near = 0.00005
# camera.clip_plane_near = 0.01
camera.clip_plane_far = 100000000
# 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
for universe in self.universes:
universe.planet.collider = "sphere"
universe.planet.enabled = False
def universe_reset(self):
self.camera_target.speed = 1
self.current_idx += 1
self.target_idx += 1
if self.current_idx > len(self.universes) - 1:
self.current_idx = 0
if self.target_idx > len(self.universes) - 1:
self.target_idx = 0
for u in self.universes:
self.scale_down(u)
u.planet.enabled = False
self.current_universe = self.universes[self.current_idx]
self.target_universe = self.universes[self.target_idx]
self.scale_up(self.current_universe)
# self.scale_down(self.target_universe)
self.current_universe.planet.enabled = True
self.target_universe.planet.enabled = True
def body_update_reset(self):
# for b in self.bodies:
# b.planet.update = lambda: None
self.camera_target.planet.update = lambda: None
def on_ready(self):
"""
事件绑定后,模拟器运行前会触发
@return:
"""
self.init_setting()
self.current_idx = -1
self.target_idx = 0
self.current_universe = None
self.body_update_reset()
self.universe_reset()
# self.target_universe.planet.rotation_y = 100
# self.current_universe.planet.rotation_y = 200
# self.current_universe.planet.rotation_x = 30
# camera_look_at(self.camera_target)
self.camera_target.planet.collider = "sphere"
self.camera_target.planet.enabled = False
camera.collider = "sphere"
camera.current_universe = self.current_universe
camera_look_at(self.camera_target, rotation_z=0)
def scale_up(self, obj):
if obj is None:
return
obj.planet.init_scale = self.SIZE_SCALE * 1000
def scale_down(self, obj):
if obj is None:
return
obj.planet.init_scale = self.SIZE_SCALE
# def camera_move(self, time_data):
# """
# 摄像机移动控制
# @param dt:
# @return:
# """
#
# def camera_rotation():
# # camera.rotation_y += 1
# # self.scale_up(self.target_universe)
# # self.scale_down(self.current_universe)
# if camera.intersects(self.target_universe.planet).hit:
# self.universe_reset()
# return False
# return True
#
# # 摄像机移动控制数据
# camera_move_infos = [
# # 条件:年份
# # 移动的信息:
# # 按坐标系方向移动 x:右+左-, y:升+降-, z:前+(接近太阳)后-(远离太阳)
# # 以摄像机视角移动 f:前 b:后 l:左 r:右 u:上 d:下
# (0, {"z": 1}),
# # (1983, {"to": {"ct_id": 1, "t": 10}}),
# (2, {"begin_execution": lambda p: camera_rotation()}),
# (1987, {"y": -6, "z": -12}),
# (1988, {"y": -3, "z": -12}),
# (1989, {"z": -8, "f": -5}),
# (1993, {"z": -8, "f": -3}),
# (1995, {"z": -8}),
# (2000, {"z": -8, "y": -0.2}),
# (2013, {}),
# (2048, {"f": 3}),
# (2062, {"y": -3}),
# (2063, {"y": -10, "z": 2}),
# (2181, {}),
# # (2082, {"exit": True})
# ]
#
# camera_move_control(camera_move_infos,
# cond_cb=lambda ps: ps["next_cond"] > time_data.total_hours >= ps["cond"],
# value_conv=self.s_f, smooth=10)
# print(time_data.total_hours)
#
# def s_f(self, value=1):
# if value == 0:
# return 0
# return get_run_speed_factor() * value
def on_timer_changed(self, time_data):
# return
# pass
self.target_universe.planet.rotation_y -= 0.5
camera_look_at(self.camera_target, rotation_z=0)
# camera.rotation_x -= 2
self.camera_target.planet.look_at(self.target_universe.planet)
# self.camera_move(time_data)
from ursina import time, distance
self.camera_target.speed *= 1.02
if self.camera_target.speed > 1000:
self.camera_target.speed = 1000
self.camera_target.planet.position = \
lerp(self.camera_target.planet.position, self.target_universe.planet.position,
self.camera_target.speed * time.dt)
# self.camera_target.planet.position += self.camera_target.planet.forward*100
# print(self.camera_target.planet.position)
dd = distance(camera.position, self.target_universe.planet.position)
camera.position = lerp(camera.position, self.target_universe.planet.position, 1500 * time.dt / dd)
# camera.position += camera.forward * 2
# if self.camera_target.planet.intersects(self.target_universe.planet).hit:
if camera.intersects(self.target_universe.planet).hit:
self.universe_reset()
return
if camera.intersects(self.target_universe.planet).hit:
# worm_hole.planet.init_scale = SIZE_SCALE * 1000
self.current_universe.planet.init_scale = self.SIZE_SCALE
if self.target_universe.planet.init_scale < self.SIZE_SCALE * 1000:
self.target_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.2
elif abs(camera.init_rotation_y - camera.rotation_y) < 90:
camera.rotation_y_v += 0.15
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]) #
from ursina import application, time
camera.position = lerp(camera.position, self.target_universe.planet.position, 0.2e-2 * time.dt)
# 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],
# position=[0, 0, ],
position=[0, self.D, -self.D * 2],
cosmic_bg='',
gravity_works=False,
timer_enabled=True,
show_grid=False,
show_trail=False)
if __name__ == '__main__':
"""
"""
wormhole_sim = WormholeSim()
wormhole_sim.run()
......@@ -867,10 +867,18 @@ def camera_move_control(camera_move_infos, cond_cb, value_conv=None, smooth=None
cond_cb_params = {"cond": cond, "next_cond": next_cond, "idx": idx, "info": info, "next_info": next_info}
if cond_cb(cond_cb_params):
begin_execution = info.get("begin_execution", None)
if callable(begin_execution):
if not begin_execution(cond_cb_params):
break
end_execution = info.get("end_execution", None)
t = info.get("to", None)
if t is not None:
camera_to_target(info)
continue
if callable(end_execution):
end_execution(cond_cb_params)
break
p = camera.position
x, y, z = [info.get("x", 0), info.get("y", 0), info.get("z", 0)]
......@@ -918,10 +926,14 @@ def camera_move_control(camera_move_infos, cond_cb, value_conv=None, smooth=None
camera.position = p
if callable(end_execution):
end_execution(cond_cb_params)
e = next_info.get("exit", None)
if e:
print("自动退出...")
exit(0)
break
if __name__ == '__main__':
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册