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

Python超人-宇宙模拟器

上级 13e0fe0d
# -*- coding:utf-8 -*-
# title :虫洞效果模拟
# description :虫洞效果模拟
# author :Python超人
# date :2023-11-19
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# ==============================================================================
from bodies import Sun, Earth
from simulators.ursina.entities.entity_utils import create_ambient_light
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.camera_target.go_target = None
self.camera_target.go_target_stage = None
self.last_universe = None
self.current_universe = None
self.target_universe = None
self.universes = []
self.create_universes()
self.bodies = [self.camera_target] + 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 = 100
for universe in self.universes:
universe.planet.collider = "sphere"
universe.planet.enabled = False
def universe_reset(self):
self.camera_target.speed = 100
camera.speed = 100
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.last_universe = self.current_universe
self.current_universe = self.universes[self.current_idx]
self.target_universe = self.universes[self.target_idx]
if self.last_universe is None:
self.camera_target.go_target = self.target_universe
self.camera_target.go_target_stage = "target_universe"
self.camera_target.go_target_hit = False
else:
self.camera_target.go_target = self.last_universe
self.camera_target.go_target_stage = "last_universe"
self.camera_target.go_target_hit = False
self.scale_up(self.current_universe)
# self.scale_down(self.target_universe)
self.current_universe.planet.enabled = True
# self.current_universe.planet.set_light_off()
self.target_universe.planet.enabled = True
# self.target_universe.planet.set_light_off()
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()
# create_ambient_light(parent=camera)
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 * 100
def scale_down(self, obj):
if obj is None:
return
obj.planet.init_scale = self.SIZE_SCALE
def on_timer_changed(self, time_data):
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
if self.camera_target.go_target is not None:
go_target = self.camera_target.go_target.planet
self.camera_target.planet.look_at(go_target)
self.camera_target.speed *= 1.02
if self.camera_target.speed > 2000:
self.camera_target.speed = 2000
self.camera_target.planet.position = \
lerp(self.camera_target.planet.position, go_target.position,
self.camera_target.speed * time.dt)
if self.camera_target.go_target_stage == "last_universe":
if self.camera_target.planet.intersects(go_target).hit and not self.camera_target.go_target_hit:
self.camera_target.go_target_hit = True
self.camera_target.go_target_stage == "target_universe"
self.camera_target.go_target = self.target_universe
self.camera_target.speed = 100
camera.speed = 100 # TODO:这个不能反复执行
elif self.camera_target.go_target_stage == "target_universe":
if self.camera_target.planet.intersects(go_target).hit and not self.camera_target.go_target_hit:
self.camera_target.go_target_hit = True
camera.speed = 1000 # TODO:这个不能反复执行
# self.camera_target.planet.position += self.camera_target.planet.forward*100
# print(self.camera_target.planet.position)
camera.speed *= 1.02
if camera.speed > 5000:
camera.speed = 5000
dd = distance(camera.position, self.target_universe.planet.position)
camera.position = lerp(camera.position, self.target_universe.planet.position, camera.speed * 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()
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()
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
# pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina # pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina
from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, \ from ursina import Ursina, window, Entity, Mesh, SmoothFollow, Texture, clamp, time, \
camera, color, mouse, Vec2, Vec3, Vec4, Text, \ camera, color, mouse, Vec2, Vec3, Vec4, Text, \
load_texture, held_keys, destroy, PointLight, DirectionalLight, distance load_texture, held_keys, destroy, distance, \
PointLight, DirectionalLight, AmbientLight
from common import color_utils from common import color_utils
from common.image_utils import find_texture from common.image_utils import find_texture
...@@ -385,6 +386,27 @@ def create_fixed_star_lights(fixed_star): ...@@ -385,6 +386,27 @@ def create_fixed_star_lights(fixed_star):
intensity=10, range=10, color=color.white) intensity=10, range=10, color=color.white)
def create_point_light(parent, light_color=None, position=(0, 0, 0)):
if light_color is None:
light_color = color.white
light = PointLight(parent=parent,
position=position,
scale=1000000,
intensity=100000, color=light_color)
return light
def create_ambient_light(parent, light_color=None, position=(0, 0, 0)):
if light_color is None:
light_color = color.white
light = AmbientLight(parent=parent,
position=position,
intensity=1000, color=light_color)
return light
def get_value_direction_vectors(vectors): def get_value_direction_vectors(vectors):
# 计算速度的大小 # 计算速度的大小
x, y, z = vectors[0], vectors[1], vectors[2] x, y, z = vectors[0], vectors[1], vectors[2]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册