Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Python_超人
宇宙模拟器
提交
0f55a42a
宇宙模拟器
项目概览
Python_超人
/
宇宙模拟器
通知
19
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
宇宙模拟器
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
0f55a42a
编写于
11月 20, 2023
作者:
三月三net
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Python超人-宇宙模拟器
上级
ba31cad0
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
549 addition
and
537 deletion
+549
-537
sim_lab/wormhole_sim.py
sim_lab/wormhole_sim.py
+402
-79
sim_lab/wormhole_sim_01.py
sim_lab/wormhole_sim_01.py
+147
-0
sim_lab/wormhole_sim_03.py
sim_lab/wormhole_sim_03.py
+0
-0
sim_scenes/wormhole_sim.py
sim_scenes/wormhole_sim.py
+0
-458
未找到文件。
sim_lab/wormhole_sim.py
浏览文件 @
0f55a42a
...
@@ -2,58 +2,161 @@
...
@@ -2,58 +2,161 @@
# title :虫洞效果模拟
# title :虫洞效果模拟
# description :虫洞效果模拟
# description :虫洞效果模拟
# author :Python超人
# author :Python超人
# date :2023-11-
03
# date :2023-11-
19
# link :https://gitcode.net/pythoncr/
# link :https://gitcode.net/pythoncr/
# python_version :3.9
# python_version :3.9
# ==============================================================================
# ==============================================================================
from
bodies
import
Sun
,
Earth
from
bodies
import
Sun
,
Earth
from
simulators.ursina.entities.entity_utils
import
create_ambient_light
from
bodies.universe_body
import
create_universe_body
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
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
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
sim_scenes.func
import
mayavi_run
,
mpl_run
,
ursina_run
,
camera_look_at
,
two_bodies_colliding
,
camera_move_control
,
\
from
ursina
import
camera
,
application
,
lerp
get_run_speed_factor
,
create_text_panel
from
ursina
import
camera
,
application
,
lerp
,
Vec3
from
bodies
import
Body
from
bodies
import
Body
from
simulators.ursina.ursina_event
import
UrsinaEvent
from
simulators.ursina.ursina_event
import
UrsinaEvent
from
dataclasses
import
dataclass
,
field
import
inspect
ours_cosmic_bg
=
"cosmic_pan_1.jpg"
worms_cosmic_bg
=
"cosmic_pan_4.jpg"
@
dataclass
(
order
=
True
)
class
WormholeInfo
:
# entity: object
name
:
str
=
field
(
default
=
''
)
position
:
list
[
float
]
=
field
(
default_factory
=
[
0
,
0
,
0
])
camera_target_init_speed
:
int
=
100
camera_init_speed
:
int
=
100
camera_target_speed
:
int
=
2000
camera_target_max_speed
:
int
=
2000
camera_forward_speed
:
int
=
-
0.1
camera_max_speed
:
int
=
5000
camera_acc_speed
:
int
=
1.02
camera_forward_acc_speed
:
int
=
0.01
size_factor
:
float
=
10
rotation_x
:
float
=
None
rotation_y
:
float
=
None
rotation_z
:
float
=
None
around_max_count
:
int
=
300
around_max_speed
:
int
=
-
200
around_min_speed
:
int
=
100
around_direction
:
str
=
"right"
around_acc_speed
:
int
=
-
2
# class WormholeInfoParams:
# def __init__(self):
# self.params = []
#
# def add(self, param_name):
#
# return self
class
WormholeSim
:
class
WormholeSim
:
SIZE_SCALE
=
1
# 生成的太阳放大 50 倍
SIZE_SCALE
=
1
RUN_DIAMETER
=
1.392e6
D
=
AU
/
10
*
SIZE_SCALE
velocity_rate
=
22
def
__init__
(
self
):
def
__init__
(
self
):
self
.
camera_target
=
CoreValagaClas
(
name
=
"摄像机目标"
,
mass
=
1e30
,
color
=
(
111
,
140
,
255
),
D
=
self
.
D
self
.
camera_target
=
CoreValagaClas
(
name
=
"摄像机镜头"
,
mass
=
1e30
,
color
=
(
111
,
140
,
255
),
# init_position=[0, 0, 0],
# init_position=[0, 0, 0],
init_position
=
[
0
,
0
,
AU
/
10
],
init_position
=
[
D
,
0
,
-
D
],
init_velocity
=
[
0
,
0
,
0
],
init_velocity
=
[
0
,
0
,
0
],
size_scale
=
WormholeSim
.
SIZE_SCALE
*
1e1
)
# .set_ignore_gravity(True)
size_scale
=
self
.
SIZE_SCALE
*
1e3
).
set_ignore_gravity
(
True
)
self
.
wormholeinfo_default_vals
=
None
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
.
universes
=
[]
self
.
wormhole_infos
=
{}
self
.
ours_universe
=
create_universe_body
(
"我们的宇宙"
,
"cosmic_pan_1.jpg"
,
self
.
create_universes
()
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
self
.
bodies
=
[
self
.
camera_target
]
+
self
.
universes
def
on_ready
(
self
):
def
create_universe
(
self
,
name
,
idx
,
position
):
"""
if
name
is
None
:
事件绑定后,模拟器运行前会触发
name
=
f
"宇宙
{
idx
}
"
@return:
universe_body
=
create_universe_body
(
name
,
texture
=
f
'cosmic_pan_
{
idx
+
1
}
.jpg'
,
# self.textures[idx],
"""
size_scale
=
self
.
SIZE_SCALE
,
# 创建天空
init_position
=
position
,
camera
.
clip_plane_near
=
0.0001
init_velocity
=
[
0
,
0
,
0
],
camera
.
clip_plane_far
=
10000000000
)
return
universe_body
def
create_universes
(
self
):
D
=
self
.
D
# camera_target_init_speed: int = 100
# camera_init_speed: int = 100
# camera_target_speed: int = 2000
# camera_forward_speed: int = - 0.1
# camera_max_speed: int = 2000
# camera_acc_speed: int = 1.02
# camera_forward_acc_speed: int = 0.01
# size_factor: float = 10
# rotation_x: float = None
# rotation_y: float = None
# rotation_z: float = None
# around_max_count: int = 300
# around_max_speed: int = -200
# around_direction: str = "right"
# around_acc_speed: int = -2
wormhole_infos
=
[
{
"position"
:
[
D
,
0
,
-
D
],
"rotation_y"
:
-
150
},
{
"position"
:
[
D
,
0
,
D
],
"rotation_z"
:
30
,
"around_acc_speed"
:
-
20
,
"around_min_speed"
:
150
,
"camera_forward_speed"
:
-
0.3
,
"around_max_count"
:
500
},
{
"position"
:
[
-
D
,
-
D
,
D
]},
{
"position"
:
[
-
D
,
0
,
-
D
]},
{
"position"
:
[
D
,
D
,
D
]},
{
"position"
:
[
D
,
-
D
,
D
]},
{
"position"
:
[
-
D
,
-
D
,
-
D
]},
{
"position"
:
[
-
D
,
0
,
D
]},
{
"position"
:
[
D
,
D
,
-
D
]},
{
"position"
:
[
-
D
,
D
,
-
D
]},
{
"position"
:
[
-
D
,
D
,
D
]},
{
"position"
:
[
D
,
-
D
,
-
D
]}
]
def
build_wormhole_info_param
(
wormhole_info
):
# ps = WormholeInfoParams()
if
self
.
wormholeinfo_default_vals
is
None
:
self
.
wormholeinfo_default_vals
=
{}
init_wormholeinfo_default_vals
=
True
else
:
init_wormholeinfo_default_vals
=
False
ps
=
{}
attributes
=
inspect
.
getmembers
(
WormholeInfo
)
for
attr
in
attributes
:
if
not
attr
[
0
].
startswith
(
'_'
):
pn
=
attr
[
0
]
if
init_wormholeinfo_default_vals
:
self
.
wormholeinfo_default_vals
[
pn
]
=
attr
[
1
]
if
pn
not
in
wormhole_info
.
keys
():
continue
ps
[
pn
]
=
wormhole_info
[
pn
]
# attr[1].default
return
ps
for
idx
,
wormhole_info
in
enumerate
(
wormhole_infos
):
pos
=
wormhole_info
.
get
(
"position"
,
[
0
,
0
,
0
])
name
=
wormhole_info
.
get
(
"name"
,
f
"宇宙
{
idx
}
"
)
ps1
=
build_wormhole_info_param
(
wormhole_info
)
ps1
[
"position"
]
=
pos
ps1
[
"name"
]
=
name
universe
=
self
.
create_universe
(
name
,
idx
,
pos
)
self
.
universes
.
append
(
universe
)
self
.
wormhole_infos
[
universe
]
=
WormholeInfo
(
**
ps1
)
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)
# create_sphere_sky(scale=200000)
application
.
time_scale
=
0.001
application
.
time_scale
=
0.001
# camera.scale = 1000
# camera.scale = 1000
...
@@ -61,60 +164,278 @@ class WormholeSim:
...
@@ -61,60 +164,278 @@ class WormholeSim:
# camera.rotation_x = 90
# camera.rotation_x = 90
camera
.
fov
=
100
camera
.
fov
=
100
self
.
worm_hole
.
planet
.
rotation_y
=
100
for
universe
in
self
.
universes
:
self
.
ours_universe
.
planet
.
rotation_y
=
200
universe
.
planet
.
collider
=
"sphere"
self
.
ours_universe
.
planet
.
rotation_x
=
30
universe
.
planet
.
enabled
=
False
camera
.
forward_speed
=
0
def
get_wormhole_data
(
self
,
data_name
,
default_val
=
None
,
universe
=
None
):
def
ret_value
():
if
default_val
is
None
:
if
data_name
in
self
.
wormholeinfo_default_vals
.
keys
():
return
self
.
wormholeinfo_default_vals
[
data_name
]
return
default_val
if
universe
is
None
:
universe
=
self
.
current_universe
wormhole_info
=
self
.
wormhole_infos
[
universe
]
if
wormhole_info
is
None
:
return
ret_value
()
if
not
hasattr
(
wormhole_info
,
data_name
):
return
ret_value
()
val
=
getattr
(
wormhole_info
,
data_name
)
if
val
is
None
:
return
ret_value
()
return
val
def
universe_reset
(
self
):
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
]
rotation_x
:
float
=
self
.
get_wormhole_data
(
"rotation_x"
)
rotation_y
:
float
=
self
.
get_wormhole_data
(
"rotation_y"
)
rotation_z
:
float
=
self
.
get_wormhole_data
(
"rotation_z"
)
if
rotation_x
is
not
None
:
self
.
current_universe
.
planet
.
rotation_x
=
rotation_x
if
rotation_y
is
not
None
:
self
.
current_universe
.
planet
.
rotation_y
=
rotation_y
if
rotation_z
is
not
None
:
self
.
current_universe
.
planet
.
rotation_z
=
rotation_z
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_target_init_speed"
)
camera
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
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
.
last_universe
.
planet
.
enabled
=
True
size_factor
=
self
.
get_wormhole_data
(
"size_factor"
,
universe
=
self
.
last_universe
)
self
.
scale_down
(
self
.
last_universe
,
scale_size
=
self
.
SIZE_SCALE
*
size_factor
)
self
.
camera_target
.
go_target_stage
=
"last_universe"
self
.
camera_target
.
go_target_hit
=
False
self
.
scale_down
(
u
)
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_target_speed"
)
camera
.
forward_speed
=
self
.
get_wormhole_data
(
"camera_forward_speed"
)
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
()
camera_look_at
(
self
.
camera_target
)
# camera_look_at(self.camera_target)
self
.
camera_target
.
planet
.
collider
=
"sphere"
self
.
camera_target
.
planet
.
enabled
=
False
camera
.
collider
=
"sphere"
camera
.
collider
=
"sphere"
self
.
worm_hole
.
planet
.
collider
=
"sphere"
camera
.
current_universe
=
self
.
current_universe
self
.
ours_universe
.
planet
.
init_scale
=
self
.
SIZE_SCALE
*
1000
camera_look_at
(
self
.
camera_target
,
rotation_z
=
0
)
self
.
camera_target
.
current_universe
=
self
.
ours_universe
self
.
camera_target
.
targe_universe
=
self
.
worm_hole
self
.
text_panel
=
create_text_panel
(
font
=
"fonts/DroidSansFallback.ttf"
,
font_scale
=
1.3
)
# camera_position = camera.position
def
update_text_panel
(
self
):
"""
更新文字信息面板
@param d_sun:
@return:
"""
panel_text
=
"虫洞穿越宇宙:
\n\n
当前宇宙:%s "
%
self
.
current_universe
.
name
panel_text
+=
"
\n\n
下站宇宙:%s"
%
self
.
target_universe
.
name
if
self
.
last_universe
is
not
None
:
panel_text
+=
"
\n\n
上站宇宙:%s "
%
self
.
last_universe
.
name
self
.
text_panel
.
text
=
panel_text
def
scale_up
(
self
,
obj
):
if
obj
is
None
:
return
obj
.
planet
.
init_scale
=
self
.
SIZE_SCALE
*
100
def
scale_down
(
self
,
obj
,
scale_size
=
None
):
if
obj
is
None
:
return
if
scale_size
is
None
:
scale_size
=
self
.
SIZE_SCALE
obj
.
planet
.
init_scale
=
scale_size
def
around_universe
(
self
,
around_target
):
around_max_count
=
self
.
get_wormhole_data
(
"around_max_count"
)
around_max_speed
=
self
.
get_wormhole_data
(
"around_max_speed"
)
around_min_speed
=
self
.
get_wormhole_data
(
"around_min_speed"
)
around_direction
=
self
.
get_wormhole_data
(
"around_direction"
)
around_acc_speed
=
self
.
get_wormhole_data
(
"around_acc_speed"
)
# around_target = camera
self
.
camera_target
.
planet
.
look_at
(
around_target
)
# print(self.camera_target.planet.rotation_x,self.camera_target.planet.rotation_y,self.camera_target.planet.rotation_z)
planet_direction
=
getattr
(
self
.
camera_target
.
planet
,
around_direction
)
if
not
hasattr
(
self
.
camera_target
,
"around_speed"
):
self
.
camera_target
.
around_speed
=
0
if
not
hasattr
(
self
.
camera_target
,
"around_count"
):
self
.
camera_target
.
around_count
=
0
if
self
.
camera_target
.
around_count
>
around_max_count
:
if
hasattr
(
self
.
camera_target
,
"around_speed"
)
and
\
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
around_min_speed
):
self
.
camera_target
.
around_speed
-=
around_acc_speed
else
:
# delattr(self.camera_target, "around_speed")
delattr
(
self
.
camera_target
,
"around_count"
)
self
.
camera_target
.
go_target_stage
=
"last_universe"
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
else
:
self
.
camera_target
.
around_speed
+=
around_acc_speed
if
hasattr
(
self
.
camera_target
,
"around_speed"
):
if
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
around_max_speed
):
self
.
camera_target
.
around_speed
=
around_max_speed
self
.
camera_target
.
planet
.
position
+=
planet_direction
*
self
.
camera_target
.
around_speed
print
(
"around_speed"
,
self
.
camera_target
.
around_speed
)
if
hasattr
(
self
.
camera_target
,
"around_count"
):
self
.
camera_target
.
around_count
+=
1
# camera.forward_speed = -0.05
if
abs
(
camera
.
forward_speed
)
>
0.01
:
camera_forward_acc_speed
=
self
.
get_wormhole_data
(
"camera_forward_acc_speed"
)
camera
.
forward_speed
+=
camera_forward_acc_speed
# else:
# camera.forward_speed = 0
def
go_last_universe
(
self
,
go_target
):
if
self
.
camera_target
.
planet
.
intersects
(
go_target
).
hit
:
if
not
self
.
camera_target
.
go_target_hit
:
self
.
camera_target
.
go_target_hit
=
True
self
.
camera_target
.
go_target_stage
=
"around_universe"
self
.
camera_target
.
go_target
=
self
.
target_universe
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
camera
.
speed
=
1
# 在看上一个宇宙时候,停留一会
# # camera.forward_speed = -0.05
# if camera.forward_speed < 0:
# camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed")
# camera.forward_speed += camera_forward_acc_speed
# else:
# camera.forward_speed = 0
if
hasattr
(
self
.
camera_target
,
"around_speed"
):
if
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
10
):
around_acc_speed
=
self
.
get_wormhole_data
(
"around_acc_speed"
)
around_direction
=
self
.
get_wormhole_data
(
"around_direction"
)
planet_direction
=
getattr
(
self
.
camera_target
.
planet
,
around_direction
)
self
.
camera_target
.
around_speed
-=
around_acc_speed
self
.
camera_target
.
planet
.
position
+=
planet_direction
*
self
.
camera_target
.
around_speed
else
:
delattr
(
self
.
camera_target
,
"around_speed"
)
def
on_timer_changed
(
self
,
time_data
):
def
on_timer_changed
(
self
,
time_data
):
# return
self
.
target_universe
.
planet
.
rotation_y
-=
0.5
# pass
if
self
.
last_universe
is
not
None
:
# camera_look_at(camera_target)
self
.
last_universe
.
planet
.
rotation_y
+=
0.3
camera_look_at
(
self
.
camera_target
,
rotation_z
=
0
)
# camera.rotation_x -= 2
# 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
:
# self.camera_target.planet.look_at(self.target_universe.planet)
# worm_hole.planet.init_scale = SIZE_SCALE * 1000
# self.camera_move(time_data)
self
.
camera_target
.
current_universe
.
planet
.
init_scale
=
self
.
SIZE_SCALE
from
ursina
import
time
,
distance
if
self
.
camera_target
.
targe_universe
.
planet
.
init_scale
<
self
.
SIZE_SCALE
*
1000
:
self
.
camera_target
.
targe_universe
.
planet
.
init_scale
*=
1.1
camera_max_speed
=
self
.
get_wormhole_data
(
"camera_max_speed"
)
# if ours_universe.planet.init_scale > SIZE_SCALE:
camera_acc_speed
=
self
.
get_wormhole_data
(
"camera_acc_speed"
)
# ours_universe.planet.init_scale /= 1.1
camera_target_max_speed
=
self
.
get_wormhole_data
(
"camera_target_max_speed"
,
)
if
not
hasattr
(
camera
,
"init_rotation_y"
):
camera
.
init_rotation_y
=
camera
.
rotation_y
if
self
.
camera_target
.
go_target
is
not
None
:
camera
.
rotation_y_v
=
0.01
go_target
=
self
.
camera_target
.
go_target
.
planet
if
self
.
camera_target
.
go_target_stage
==
"around_universe"
:
if
abs
(
camera
.
init_rotation_y
-
camera
.
rotation_y
)
<
10
:
# 摄像机镜头环绕目标宇运动(摄像机镜头暂时不去目标)
camera
.
rotation_y_v
+=
0.5
self
.
around_universe
(
go_target
)
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
:
else
:
camera
.
rotation_y_v
=
0
# 摄像机镜头看向目标宇宙,并逐渐靠近目标
camera
.
rotation_y
+=
camera
.
rotation_y_v
self
.
camera_target
.
planet
.
look_at
(
go_target
)
# camera_look_at(ours_universe)
self
.
camera_target
.
planet
.
position
=
\
# else:
lerp
(
self
.
camera_target
.
planet
.
position
,
go_target
.
position
,
# if two_bodies_colliding(camera_target, worm_hole):
self
.
camera_target
.
speed
*
time
.
dt
)
# 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)
self
.
camera_target
.
speed
*=
camera_acc_speed
# print(2,camera_target.planet.position)
if
self
.
camera_target
.
speed
>
camera_target_max_speed
:
# camera.position = (camera.position[0],camera.position[1],camera.position[2]) #
self
.
camera_target
.
speed
=
camera_target_max_speed
camera
.
position
=
lerp
(
camera
.
position
,
self
.
camera_target
.
planet
.
position
,
0.1e-2
)
if
self
.
camera_target
.
go_target_stage
==
"last_universe"
:
# 进入新的宇宙后,摄像机回看上一个宇宙的镜头
self
.
go_last_universe
(
go_target
)
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
.
forward_speed
=
0
# camera.speed = 3000 # TODO:这个不能反复执行
# self.camera_target.planet.position += self.camera_target.planet.forward*100
# print(self.camera_target.planet.position)
# 摄像机加速度计算(摄像机圆滑效果)
camera
.
speed
*=
camera_acc_speed
if
camera
.
speed
>
camera_max_speed
:
camera
.
speed
=
camera_max_speed
if
camera
.
speed
!=
0
:
dd
=
distance
(
camera
.
position
,
self
.
target_universe
.
planet
.
position
)
camera
.
position
=
lerp
(
camera
.
position
,
self
.
target_universe
.
planet
.
position
,
camera
.
speed
*
time
.
dt
/
dd
)
if
camera
.
forward_speed
!=
0
:
camera
.
position
+=
camera
.
forward
*
camera
.
forward_speed
# if self.camera_target.planet.intersects(self.target_universe.planet).hit:
if
camera
.
intersects
(
self
.
target_universe
.
planet
).
hit
:
self
.
universe_reset
()
# camera_position = [camera_position[0], camera_position[1], camera_position[2] - 0.01]
self
.
update_text_panel
()
# camera.position = camera_position
def
build_events
(
self
):
def
build_events
(
self
):
# 订阅事件后,上面2个函数功能才会起作用
# 订阅事件后,上面2个函数功能才会起作用
...
@@ -131,9 +452,11 @@ class WormholeSim:
...
@@ -131,9 +452,11 @@ class WormholeSim:
ursina_run
(
self
.
bodies
,
SECONDS_PER_DAY
/
24
,
ursina_run
(
self
.
bodies
,
SECONDS_PER_DAY
/
24
,
# position=(0, AU / 1200, -1.003 * AU),
# position=(0, AU / 1200, -1.003 * AU),
# position=[-AU/100, 0, 0],
# position=[-AU/100, 0, 0],
position
=
[
0
,
0
,
-
AU
/
10
],
# position=[0, 0, -AU / 10],
# position=[0, 0, ],
position
=
[
0
,
self
.
D
,
-
self
.
D
*
2
],
cosmic_bg
=
''
,
cosmic_bg
=
''
,
#
gravity_works=False,
gravity_works
=
False
,
timer_enabled
=
True
,
timer_enabled
=
True
,
show_grid
=
False
,
show_grid
=
False
,
show_trail
=
False
)
show_trail
=
False
)
...
...
sim_lab/wormhole_sim_01.py
0 → 100644
浏览文件 @
0f55a42a
# -*- 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.0001
camera
.
clip_plane_far
=
10000000000
# 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
self
.
worm_hole
.
planet
.
rotation_y
=
100
self
.
ours_universe
.
planet
.
rotation_y
=
200
self
.
ours_universe
.
planet
.
rotation_x
=
30
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.1e-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
()
sim_lab/wormhole_sim_
2
.py
→
sim_lab/wormhole_sim_
03
.py
浏览文件 @
0f55a42a
文件已移动
sim_scenes/wormhole_sim.py
已删除
100644 → 0
浏览文件 @
ba31cad0
# -*- 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
,
create_text_panel
from
ursina
import
camera
,
application
,
lerp
,
Vec3
from
bodies
import
Body
from
simulators.ursina.ursina_event
import
UrsinaEvent
from
dataclasses
import
dataclass
,
field
import
inspect
@
dataclass
(
order
=
True
)
class
WormholeInfo
:
# entity: object
name
:
str
=
field
(
default
=
''
)
position
:
list
[
float
]
=
field
(
default_factory
=
[
0
,
0
,
0
])
camera_target_init_speed
:
int
=
100
camera_init_speed
:
int
=
100
camera_target_speed
:
int
=
2000
camera_target_max_speed
:
int
=
2000
camera_forward_speed
:
int
=
-
0.1
camera_max_speed
:
int
=
5000
camera_acc_speed
:
int
=
1.02
camera_forward_acc_speed
:
int
=
0.01
size_factor
:
float
=
10
rotation_x
:
float
=
None
rotation_y
:
float
=
None
rotation_z
:
float
=
None
around_max_count
:
int
=
300
around_max_speed
:
int
=
-
200
around_min_speed
:
int
=
100
around_direction
:
str
=
"right"
around_acc_speed
:
int
=
-
2
# class WormholeInfoParams:
# def __init__(self):
# self.params = []
#
# def add(self, param_name):
#
# return self
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
*
1e3
).
set_ignore_gravity
(
True
)
self
.
wormholeinfo_default_vals
=
None
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
.
wormhole_infos
=
{}
self
.
create_universes
()
self
.
bodies
=
[
self
.
camera_target
]
+
self
.
universes
def
create_universe
(
self
,
name
,
idx
,
position
):
if
name
is
None
:
name
=
f
"宇宙
{
idx
}
"
universe_body
=
create_universe_body
(
name
,
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
# camera_target_init_speed: int = 100
# camera_init_speed: int = 100
# camera_target_speed: int = 2000
# camera_forward_speed: int = - 0.1
# camera_max_speed: int = 2000
# camera_acc_speed: int = 1.02
# camera_forward_acc_speed: int = 0.01
# size_factor: float = 10
# rotation_x: float = None
# rotation_y: float = None
# rotation_z: float = None
# around_max_count: int = 300
# around_max_speed: int = -200
# around_direction: str = "right"
# around_acc_speed: int = -2
wormhole_infos
=
[
{
"position"
:
[
D
,
0
,
-
D
],
"rotation_y"
:
-
150
},
{
"position"
:
[
D
,
0
,
D
],
"rotation_z"
:
30
,
"around_acc_speed"
:
-
10
,
"around_min_speed"
:
150
},
{
"position"
:
[
-
D
,
-
D
,
D
]},
{
"position"
:
[
-
D
,
0
,
-
D
]},
{
"position"
:
[
D
,
D
,
D
]},
{
"position"
:
[
D
,
-
D
,
D
]},
{
"position"
:
[
-
D
,
-
D
,
-
D
]},
{
"position"
:
[
-
D
,
0
,
D
]},
{
"position"
:
[
D
,
D
,
-
D
]},
{
"position"
:
[
-
D
,
D
,
-
D
]},
{
"position"
:
[
-
D
,
D
,
D
]},
{
"position"
:
[
D
,
-
D
,
-
D
]}
]
def
build_wormhole_info_param
(
wormhole_info
):
# ps = WormholeInfoParams()
if
self
.
wormholeinfo_default_vals
is
None
:
self
.
wormholeinfo_default_vals
=
{}
init_wormholeinfo_default_vals
=
True
else
:
init_wormholeinfo_default_vals
=
False
ps
=
{}
attributes
=
inspect
.
getmembers
(
WormholeInfo
)
for
attr
in
attributes
:
if
not
attr
[
0
].
startswith
(
'_'
):
pn
=
attr
[
0
]
if
init_wormholeinfo_default_vals
:
self
.
wormholeinfo_default_vals
[
pn
]
=
attr
[
1
]
if
pn
not
in
wormhole_info
.
keys
():
continue
ps
[
pn
]
=
wormhole_info
[
pn
]
# attr[1].default
return
ps
for
idx
,
wormhole_info
in
enumerate
(
wormhole_infos
):
pos
=
wormhole_info
.
get
(
"position"
,
[
0
,
0
,
0
])
name
=
wormhole_info
.
get
(
"name"
,
f
"宇宙
{
idx
}
"
)
ps1
=
build_wormhole_info_param
(
wormhole_info
)
ps1
[
"position"
]
=
pos
ps1
[
"name"
]
=
name
universe
=
self
.
create_universe
(
name
,
idx
,
pos
)
self
.
universes
.
append
(
universe
)
self
.
wormhole_infos
[
universe
]
=
WormholeInfo
(
**
ps1
)
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
camera
.
forward_speed
=
0
def
get_wormhole_data
(
self
,
data_name
,
default_val
=
None
,
universe
=
None
):
def
ret_value
():
if
default_val
is
None
:
if
data_name
in
self
.
wormholeinfo_default_vals
.
keys
():
return
self
.
wormholeinfo_default_vals
[
data_name
]
return
default_val
if
universe
is
None
:
universe
=
self
.
current_universe
wormhole_info
=
self
.
wormhole_infos
[
universe
]
if
wormhole_info
is
None
:
return
ret_value
()
if
not
hasattr
(
wormhole_info
,
data_name
):
return
ret_value
()
val
=
getattr
(
wormhole_info
,
data_name
)
if
val
is
None
:
return
ret_value
()
return
val
def
universe_reset
(
self
):
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
]
rotation_x
:
float
=
self
.
get_wormhole_data
(
"rotation_x"
)
rotation_y
:
float
=
self
.
get_wormhole_data
(
"rotation_y"
)
rotation_z
:
float
=
self
.
get_wormhole_data
(
"rotation_z"
)
if
rotation_x
is
not
None
:
self
.
current_universe
.
planet
.
rotation_x
=
rotation_x
if
rotation_y
is
not
None
:
self
.
current_universe
.
planet
.
rotation_y
=
rotation_y
if
rotation_z
is
not
None
:
self
.
current_universe
.
planet
.
rotation_z
=
rotation_z
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_target_init_speed"
)
camera
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
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
.
last_universe
.
planet
.
enabled
=
True
size_factor
=
self
.
get_wormhole_data
(
"size_factor"
,
universe
=
self
.
last_universe
)
self
.
scale_down
(
self
.
last_universe
,
scale_size
=
self
.
SIZE_SCALE
*
size_factor
)
self
.
camera_target
.
go_target_stage
=
"last_universe"
self
.
camera_target
.
go_target_hit
=
False
self
.
scale_down
(
u
)
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_target_speed"
)
camera
.
forward_speed
=
self
.
get_wormhole_data
(
"camera_forward_speed"
)
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
()
# 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
)
self
.
text_panel
=
create_text_panel
(
font
=
"fonts/DroidSansFallback.ttf"
,
font_scale
=
1.3
)
def
update_text_panel
(
self
):
"""
更新文字信息面板
@param d_sun:
@return:
"""
panel_text
=
"虫洞穿越宇宙:
\n\n
当前宇宙:%s "
%
self
.
current_universe
.
name
panel_text
+=
"
\n\n
下站宇宙:%s"
%
self
.
target_universe
.
name
if
self
.
last_universe
is
not
None
:
panel_text
+=
"
\n\n
上站宇宙:%s "
%
self
.
last_universe
.
name
self
.
text_panel
.
text
=
panel_text
def
scale_up
(
self
,
obj
):
if
obj
is
None
:
return
obj
.
planet
.
init_scale
=
self
.
SIZE_SCALE
*
100
def
scale_down
(
self
,
obj
,
scale_size
=
None
):
if
obj
is
None
:
return
if
scale_size
is
None
:
scale_size
=
self
.
SIZE_SCALE
obj
.
planet
.
init_scale
=
scale_size
def
on_timer_changed
(
self
,
time_data
):
self
.
target_universe
.
planet
.
rotation_y
-=
0.5
if
self
.
last_universe
is
not
None
:
self
.
last_universe
.
planet
.
rotation_y
+=
0.3
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
camera_max_speed
=
self
.
get_wormhole_data
(
"camera_max_speed"
)
camera_acc_speed
=
self
.
get_wormhole_data
(
"camera_acc_speed"
)
camera_target_max_speed
=
self
.
get_wormhole_data
(
"camera_target_max_speed"
,
)
if
self
.
camera_target
.
go_target
is
not
None
:
go_target
=
self
.
camera_target
.
go_target
.
planet
if
self
.
camera_target
.
go_target_stage
==
"around_universe"
:
around_max_count
=
self
.
get_wormhole_data
(
"around_max_count"
)
around_max_speed
=
self
.
get_wormhole_data
(
"around_max_speed"
)
around_min_speed
=
self
.
get_wormhole_data
(
"around_min_speed"
)
around_direction
=
self
.
get_wormhole_data
(
"around_direction"
)
around_acc_speed
=
self
.
get_wormhole_data
(
"around_acc_speed"
)
# around_target = camera
around_target
=
go_target
self
.
camera_target
.
planet
.
look_at
(
around_target
)
# print(self.camera_target.planet.rotation_x,self.camera_target.planet.rotation_y,self.camera_target.planet.rotation_z)
planet_direction
=
getattr
(
self
.
camera_target
.
planet
,
around_direction
)
if
not
hasattr
(
self
.
camera_target
,
"around_speed"
):
self
.
camera_target
.
around_speed
=
0
if
not
hasattr
(
self
.
camera_target
,
"around_count"
):
self
.
camera_target
.
around_count
=
0
if
self
.
camera_target
.
around_count
>
around_max_count
:
if
hasattr
(
self
.
camera_target
,
"around_speed"
)
and
\
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
around_min_speed
):
self
.
camera_target
.
around_speed
-=
around_acc_speed
else
:
# delattr(self.camera_target, "around_speed")
delattr
(
self
.
camera_target
,
"around_count"
)
self
.
camera_target
.
go_target_stage
=
"last_universe"
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
else
:
self
.
camera_target
.
around_speed
+=
around_acc_speed
if
hasattr
(
self
.
camera_target
,
"around_speed"
):
if
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
around_max_speed
):
self
.
camera_target
.
around_speed
=
around_max_speed
self
.
camera_target
.
planet
.
position
+=
planet_direction
*
self
.
camera_target
.
around_speed
print
(
"around_speed"
,
self
.
camera_target
.
around_speed
)
if
hasattr
(
self
.
camera_target
,
"around_count"
):
self
.
camera_target
.
around_count
+=
1
# camera.forward_speed = -0.05
if
camera
.
forward_speed
<
0
:
camera_forward_acc_speed
=
self
.
get_wormhole_data
(
"camera_forward_acc_speed"
)
camera
.
forward_speed
+=
camera_forward_acc_speed
else
:
camera
.
forward_speed
=
0
else
:
self
.
camera_target
.
planet
.
look_at
(
go_target
)
self
.
camera_target
.
planet
.
position
=
\
lerp
(
self
.
camera_target
.
planet
.
position
,
go_target
.
position
,
self
.
camera_target
.
speed
*
time
.
dt
)
self
.
camera_target
.
speed
*=
camera_acc_speed
if
self
.
camera_target
.
speed
>
camera_target_max_speed
:
self
.
camera_target
.
speed
=
camera_target_max_speed
if
self
.
camera_target
.
go_target_stage
==
"last_universe"
:
if
self
.
camera_target
.
planet
.
intersects
(
go_target
).
hit
:
if
not
self
.
camera_target
.
go_target_hit
:
self
.
camera_target
.
go_target_hit
=
True
self
.
camera_target
.
go_target_stage
=
"around_universe"
self
.
camera_target
.
go_target
=
self
.
target_universe
self
.
camera_target
.
speed
=
self
.
get_wormhole_data
(
"camera_init_speed"
)
camera
.
speed
=
1
# 在看上一个宇宙时候,停留一会
# # camera.forward_speed = -0.05
# if camera.forward_speed < 0:
# camera_forward_acc_speed = self.get_wormhole_data("camera_forward_acc_speed")
# camera.forward_speed += camera_forward_acc_speed
# else:
# camera.forward_speed = 0
if
hasattr
(
self
.
camera_target
,
"around_speed"
):
if
abs
(
self
.
camera_target
.
around_speed
)
>
abs
(
10
):
around_acc_speed
=
self
.
get_wormhole_data
(
"around_acc_speed"
)
around_direction
=
self
.
get_wormhole_data
(
"around_direction"
)
planet_direction
=
getattr
(
self
.
camera_target
.
planet
,
around_direction
)
self
.
camera_target
.
around_speed
-=
around_acc_speed
self
.
camera_target
.
planet
.
position
+=
planet_direction
*
self
.
camera_target
.
around_speed
else
:
delattr
(
self
.
camera_target
,
"around_speed"
)
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
.
forward_speed
=
0
# camera.speed = 3000 # TODO:这个不能反复执行
# self.camera_target.planet.position += self.camera_target.planet.forward*100
# print(self.camera_target.planet.position)
camera
.
speed
*=
camera_acc_speed
if
camera
.
speed
>
camera_max_speed
:
camera
.
speed
=
camera_max_speed
dd
=
distance
(
camera
.
position
,
self
.
target_universe
.
planet
.
position
)
if
camera
.
speed
!=
0
:
camera
.
position
=
lerp
(
camera
.
position
,
self
.
target_universe
.
planet
.
position
,
camera
.
speed
*
time
.
dt
/
dd
)
if
camera
.
forward_speed
!=
0
:
camera
.
position
+=
camera
.
forward
*
camera
.
forward_speed
# if self.camera_target.planet.intersects(self.target_universe.planet).hit:
if
camera
.
intersects
(
self
.
target_universe
.
planet
).
hit
:
self
.
universe_reset
()
self
.
update_text_panel
()
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
()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录