Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Python_超人
太阳系三体模拟器
提交
e7b77055
太阳系三体模拟器
项目概览
Python_超人
/
太阳系三体模拟器
通知
1140
Star
132
Fork
129
代码
文件
提交
分支
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看板
提交
e7b77055
编写于
3月 19, 2023
作者:
三月三net
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
太阳系三体模拟器
上级
1d01c0a6
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
18 addition
and
412 deletion
+18
-412
simulators/ursina/ui/control_handler.py
simulators/ursina/ui/control_handler.py
+18
-6
simulators/ursina/ursina_ui.py
simulators/ursina/ursina_ui.py
+0
-406
未找到文件。
simulators/ursina/ui/control_handler.py
浏览文件 @
e7b77055
...
...
@@ -116,16 +116,27 @@ class ControlHandler(EventHandler):
if
hasattr
(
self
,
"bodies_button_list"
):
self
.
bodies_button_list_close
()
self
.
bodies_button_list
=
ButtonList
(
button_dict
,
font
=
UrsinaConfig
.
CN_FONT
,
button_height
=
1.5
)
self
.
bodies_button_list
=
ButtonList
(
button_dict
,
font
=
UrsinaConfig
.
CN_FONT
,
button_height
=
1.5
,
ignore_paused
=
True
)
def
on_reset_button_click
(
self
):
paused
=
application
.
paused
if
paused
:
# 如果是暂停状态,先不暂停,等重新开始后再暂停
application
.
paused
=
False
UrsinaEvent
.
on_reset
()
if
paused
:
def
application_paused
():
application
.
paused
=
True
def
on_buttons_changed
(
self
):
if
self
.
ui
.
buttons
.
value
==
"寻找"
:
self
.
on_searching_bodies_click
()
elif
self
.
ui
.
buttons
.
value
==
"重启"
:
self
.
on_reset_button_click
()
UrsinaEvent
.
on_application_run_callback_subscription
(
application_paused
)
# def on_buttons_changed(self):
# if self.ui.buttons.value == "寻找":
# self.on_searching_bodies_click()
# elif self.ui.buttons.value == "重启":
# self.on_reset_button_click()
def
on_off_switch_changed
(
self
):
if
self
.
ui
.
on_off_switch
.
value
==
self
.
ui
.
pause_button_text
:
...
...
@@ -181,6 +192,7 @@ class ControlHandler(EventHandler):
if
paused
:
def
application_paused
():
application
.
paused
=
True
UrsinaEvent
.
on_application_run_callback_subscription
(
application_paused
)
elif
key
==
'i'
:
# 拖尾开关
...
...
simulators/ursina/ursina_ui.py
已删除
100644 → 0
浏览文件 @
1d01c0a6
# -*- coding:utf-8 -*-
# title :ursina天体运行模拟器UI控制
# description :ursina天体运行模拟器UI控制
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
from
ursina
import
Ursina
,
window
,
Entity
,
Grid
,
Mesh
,
camera
,
Text
,
application
,
color
,
mouse
,
Vec2
,
Vec3
,
\
load_texture
,
held_keys
,
Button
,
ButtonList
,
destroy
,
scene
,
distance
,
Sequence
,
Wait
,
Func
from
ursina.prefabs.first_person_controller
import
FirstPersonController
from
common.consts
import
SECONDS_PER_HOUR
,
SECONDS_PER_HALF_DAY
,
\
SECONDS_PER_DAY
,
SECONDS_PER_WEEK
,
SECONDS_PER_MONTH
,
SECONDS_PER_YEAR
from
common.consts
import
AU
from
simulators.ursina.ui_component
import
UiSlider
,
SwithButton
,
UiButton
,
Buttons
from
simulators.ursina.ursina_config
import
UrsinaConfig
from
simulators.ursina.ursina_event
import
UrsinaEvent
from
ursina
import
WindowPanel
,
InputField
,
Button
,
Slider
,
ButtonGroup
,
Panel
,
invoke
class
UrsinaUI
:
def
ui_component_init
(
self
):
self
.
start_button_text
=
"●"
# 》●▲○◎
self
.
pause_button_text
=
"〓"
# 〓 || ‖
self
.
no_trail_button_text
=
"○ "
self
.
trail_button_text
=
"○--"
# application.time_scale = 0.5
self
.
slider_body_spin_factor
=
UiSlider
(
text
=
'自转速度'
,
min
=
0.01
,
max
=
30
,
default
=
1
)
self
.
slider_body_size_factor
=
UiSlider
(
text
=
'天体缩放'
,
min
=
0.1
,
max
=
100
,
step
=
0.1
,
default
=
1
)
self
.
slider_run_speed_factor
=
UiSlider
(
text
=
"运行速度"
,
min
=
0.01
,
max
=
80
,
default
=
1
)
self
.
slider_control_speed_factor
=
UiSlider
(
text
=
"控制速度"
,
min
=
0.01
,
max
=
20
,
default
=
application
.
time_scale
)
self
.
slider_trail_length
=
UiSlider
(
text
=
"拖尾长度"
,
min
=
30
,
max
=
500
,
step
=
10
,
default
=
UrsinaConfig
.
trail_length
)
self
.
slider_body_size_factor
.
on_value_changed
=
self
.
on_slider_body_size_changed
self
.
slider_body_spin_factor
.
on_value_changed
=
self
.
on_slider_body_spin_changed
self
.
slider_run_speed_factor
.
on_value_changed
=
self
.
on_slider_run_speed_changed
self
.
slider_control_speed_factor
.
on_value_changed
=
self
.
on_slider_control_speed_changed
self
.
slider_trail_length
.
on_value_changed
=
self
.
on_slider_trail_length_changed
self
.
on_off_switch
=
SwithButton
((
self
.
pause_button_text
,
self
.
start_button_text
),
default
=
self
.
start_button_text
,
tooltips
=
(
'暂停(P)'
,
'运行(P)'
))
self
.
on_off_switch
.
selected_color
=
color
.
red
self
.
sec_per_time_switch
=
SwithButton
((
"默认"
,
"天"
,
"周"
,
"月"
,
"年"
,
"十年"
,
"百年"
),
default
=
"默认"
,
tooltips
=
(
"系统默认"
,
"每秒相当于1天"
,
"每秒相当于1周"
,
"每秒相当于1个月"
,
"每秒相当于1年"
,
"每秒相当于十年"
,
"每秒相当于1百年"
))
self
.
sec_per_time_switch
.
on_value_changed
=
self
.
sec_per_time_switch_changed
self
.
on_off_trail
=
SwithButton
((
self
.
no_trail_button_text
,
self
.
trail_button_text
),
default
=
self
.
no_trail_button_text
,
tooltips
=
(
'天体运行无轨迹'
,
'天体运行有拖尾轨迹'
))
self
.
on_off_trail
.
on_value_changed
=
self
.
on_off_trail_changed
# self.buttons = Buttons(("寻找", "重启"), tooltips=("寻找天体(Y)", "重新开始(O)"))
self
.
point_button
=
UiButton
(
text
=
'寻找天体(Y)'
,
on_click
=
self
.
on_searching_bodies_click
)
self
.
reset_button
=
UiButton
(
text
=
'重新开始(O)'
,
on_click
=
self
.
on_reset_button_click
)
# button1 = Button(text='Button 1', scale=(0.1, 0.1), position=(-0.1, 0))
# button2 = Button(text='Button 2', scale=(0.1, 0.1), position=(0.1, 0))
# btn_settings = UiButton(text='操作设置', on_click=self.on_point_button_click)
# btn_settings.position = window.top_left
# btn_settings.y = 0.5
# # btn_settings.scale = (0.1,0.1)
# # btn_settings.y = 0
# btn_settings.scale = (.25, .025),
# btn_settings.origin = (-.5, .5),
# btn_settings.pressed_scale = 1,
# if btn_settings.text_entity:
# btn_settings.text_entity.x = .05
# btn_settings.text_entity.origin = (-.5, 0)
# btn_settings.text_entity.scale *= .8
self
.
on_off_switch
.
on_value_changed
=
self
.
on_off_switch_changed
wp
=
WindowPanel
(
title
=
''
,
content
=
(
# InputField(name='name_field'),
# Button(text='Submit', color=color.azure),
self
.
point_button
,
self
.
reset_button
,
# self.buttons,
self
.
sec_per_time_switch
,
self
.
on_off_switch
,
self
.
on_off_trail
,
self
.
slider_trail_length
,
self
.
slider_body_size_factor
,
self
.
slider_body_spin_factor
,
self
.
slider_run_speed_factor
,
self
.
slider_control_speed_factor
),
ignore_paused
=
True
,
color
=
color
.
rgba
(
0.0
,
0.0
,
0.0
,
0.5
)
# , popup=True
)
self
.
sec_per_time_switch
.
x
=
-
0.4
self
.
on_off_switch
.
x
=
0.2
self
.
on_off_trail
.
x
=
0.2
# -0.4
wp
.
y
=
0.5
# wp.panel.scale_y / 2 * wp.scale_y # center the window panel
wp
.
x
=
0.6
# wp.scale_x + 0.1
# wp.x = 0#wp.panel.scale_x / 2 * wp.scale_x
self
.
wp
=
wp
self
.
wp
.
enabled
=
False
def
__init__
(
self
):
self
.
ui_component_init
()
self
.
settings_handler
=
Entity
(
ignore_paused
=
True
)
# 加载中文字体文件
# text_time_scale = "1"
# self.text_time_scale_info = None
self
.
settings_handler
.
input
=
self
.
settings_handler_input
# self.show_text_time_scale_info()
# Text('方位控制: Q W E A S D + 鼠标右键', font='msyhl.ttc'),
key_info_str
=
"方位控制[键盘QWEASD]+[鼠标右键],按[空格]更多控制"
key_info
=
Text
(
text
=
key_info_str
,
font
=
UrsinaConfig
.
CN_FONT
,
position
=
(
-
1
,
0.5
),
origin
=
(
-
1
,
1
),
background
=
True
)
# # self.show_button()
# slider_text = Text(text='自转速度', scale=1, position=(-0.6, 0.3))
# slider = Slider(scale=0.5, position=(-0.6, 0), min=0, max=10, step=1, text=slider_text)
def
show_message
(
self
,
message
,
close_time
=
3
):
"""
创建消息框
:param message: 消息内容
:param close_time: 定义关闭时间
:return:
"""
# 创建消息框
message_box
=
Text
(
text
=
message
,
font
=
UrsinaConfig
.
CN_FONT
,
background
=
True
,
origin
=
(
0
,
0
),
y
=
.
25
)
# 定义关闭函数
def
close_message
():
destroy
(
message_box
)
s
=
Sequence
(
Wait
(
close_time
),
Func
(
close_message
)
)
s
.
start
()
# # 使用 time 模块来实现定时关闭
# invoke(close_message, delay=close_time)
def
sec_per_time_switch_changed
(
self
):
# ("默认", "天", "周", "月", "年", "十年", "百年")
if
self
.
sec_per_time_switch
.
value
==
"天"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_DAY
elif
self
.
sec_per_time_switch
.
value
==
"周"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_WEEK
elif
self
.
sec_per_time_switch
.
value
==
"月"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_MONTH
elif
self
.
sec_per_time_switch
.
value
==
"年"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_YEAR
elif
self
.
sec_per_time_switch
.
value
==
"十年"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_YEAR
*
10
elif
self
.
sec_per_time_switch
.
value
==
"百年"
:
UrsinaConfig
.
seconds_per
=
SECONDS_PER_YEAR
*
100
else
:
UrsinaConfig
.
seconds_per
=
0
def
on_off_trail_changed
(
self
):
if
self
.
on_off_trail
.
value
==
self
.
trail_button_text
:
UrsinaConfig
.
show_trail
=
True
else
:
UrsinaConfig
.
show_trail
=
False
def
move_camera_to_entity
(
self
,
camera_pos
:
Vec3
,
entity_pos
:
Vec3
,
_distance
:
float
)
->
Vec3
:
# 计算摄像机到实体的向量
direction
=
entity_pos
-
camera_pos
# 计算当前距离
current_distance
=
direction
.
length
()
# 如果当前距离已经小于等于要求的距离,则直接返回实体坐标
if
current_distance
<=
_distance
:
return
camera_pos
# 计算需要移动的距离
_distance
=
current_distance
-
_distance
# 根据需要移动的距离计算移动向量
move_vector
=
direction
.
normalized
()
*
_distance
# 返回摄像机移动后的坐标
return
camera_pos
+
move_vector
def
move_camera_to_entity
(
self
,
entity
,
d
):
import
math
# print("before",camera.position, entity.position)
camera
.
position
=
entity
.
position
# - Vec3(0, 0, d) # 设置摄像机位置
camera
.
world_position
=
entity
.
position
# camera.rotation = (0, 0, 0) # 重置摄像机旋转角度
# print("after",camera.position,entity.position)
# # 获取相机和实体之间的向量
# target_vector = entity.position - camera.position
# target_vector.y = 0 # 假设实体在 x-z 平面上,将 y 坐标设为 0
#
# # 计算旋转角度
# angle = math.degrees(math.atan2(target_vector.z, target_vector.x))
# camera.rotation_y = angle # 旋转相机
# camera.look_at(entity.position) # 对准指定实体
def
bodies_button_list_click
(
self
,
item
):
if
item
is
not
None
:
# TODO: 先找到位置,确定摄像机的位置
# print("select->", item)
# UrsinaConfig.SCALE_FACTOR
# import copy
# camera_rotation = copy.deepcopy(camera.rotation)
try
:
d
=
item
.
planet
.
scale_x
*
20
self
.
move_camera_to_entity
(
item
.
planet
,
d
)
except
Exception
as
e
:
self
.
show_message
(
f
"
{
item
}
飞不见了"
)
# d = distance(camera.position, item.planet.position)
# camera.look_at(item.planet)
# if d > 1.5 * x:
# move_to = self.move_camera_to_entity(camera.position, item.planet.position, x)
# camera.position = move_to
# camera_rotation = copy.deepcopy(camera.rotation)
# camera.rotation = (camera_rotation[0], camera_rotation[1], 0)
# camera.forward = (1, 0, 0) # 设置相机的方向向量为x轴方向
self
.
bodies_button_list_close
()
# my_entity = Entity(model='cube', color=color.red, position=(0, 1, 5))
#
# # 获取当前摄像机
# camera = scene.camera
#
# # 计算 Entity 和摄像机之间的距离
# distance_to_entity = distance(my_entity, camera)
#
# print('距离:', distance_to_entity)
def
bodies_button_list_close
(
self
):
if
hasattr
(
self
,
"bodies_button_list"
):
self
.
bodies_button_list
.
enabled
=
False
destroy
(
self
.
bodies_button_list
)
def
on_searching_bodies_click
(
self
):
results
=
UrsinaEvent
.
on_searching_bodies
()
if
len
(
results
)
>
0
:
sub_name
,
bodies
=
results
[
0
]
if
len
(
bodies
)
==
0
:
self
.
show_message
(
"天体都飞不见了,请重新运行。"
)
# button_dict = {"天体都飞不见了,请重新运行。": lambda: self.bodies_button_list_click(None)}
return
# print(results[0])
button_dict
=
{
"[关闭] == 寻找天体 =="
:
lambda
:
self
.
bodies_button_list_click
(
None
)}
camera
=
scene
.
camera
for
body
in
bodies
:
def
callback_action
(
b
=
body
):
self
.
bodies_button_list_click
(
b
)
if
body
.
appeared
:
distance_to_entity
=
distance
(
body
.
planet
,
camera
)
d
=
distance_to_entity
/
UrsinaConfig
.
SCALE_FACTOR
/
AU
name
=
f
"
{
body
.
name
}
\t
距离:
{
d
:.
4
f
}
天文单位"
button_dict
[
name
]
=
callback_action
else
:
if
hasattr
(
self
,
"bodies_button_list"
):
self
.
bodies_button_list_close
()
name
=
f
"
{
body
.
name
}
\t
距离太远,找不到了"
button_dict
[
name
]
=
lambda
:
self
.
bodies_button_list_click
(
None
)
if
hasattr
(
self
,
"bodies_button_list"
):
self
.
bodies_button_list_close
()
self
.
bodies_button_list
=
ButtonList
(
button_dict
,
font
=
UrsinaConfig
.
CN_FONT
,
button_height
=
1.5
)
# self.bodies_button_list.input = self.bodies_button_list_input
def
on_reset_button_click
(
self
):
UrsinaEvent
.
on_reset
()
def
on_buttons_changed
(
self
):
if
self
.
buttons
.
value
==
"寻找"
:
self
.
on_searching_bodies_click
()
elif
self
.
buttons
.
value
==
"重启"
:
self
.
on_reset_button_click
()
def
on_off_switch_changed
(
self
):
if
self
.
on_off_switch
.
value
==
self
.
pause_button_text
:
self
.
on_off_switch
.
selected_color
=
color
.
green
application
.
paused
=
True
for
c
in
self
.
wp
.
children
:
if
not
c
.
ignore_paused
:
# c.enabled = True
c
.
disabled
=
False
else
:
self
.
on_off_switch
.
selected_color
=
color
.
red
application
.
paused
=
False
for
c
in
self
.
wp
.
children
:
if
not
c
.
ignore_paused
:
# c.enabled = True
c
.
disabled
=
False
def
on_slider_trail_length_changed
(
self
):
UrsinaConfig
.
trail_length
=
int
(
self
.
slider_trail_length
.
value
)
def
on_slider_control_speed_changed
(
self
):
application
.
time_scale
=
self
.
slider_control_speed_factor
.
value
def
on_slider_body_spin_changed
(
self
):
UrsinaConfig
.
body_spin_factor
=
self
.
slider_body_spin_factor
.
value
def
on_slider_body_size_changed
(
self
):
UrsinaConfig
.
body_size_factor
=
self
.
slider_body_size_factor
.
value
def
on_slider_run_speed_changed
(
self
):
UrsinaConfig
.
run_speed_factor
=
self
.
slider_run_speed_factor
.
value
# def show_text_time_scale_info(self):
# if self.text_time_scale_info is not None:
# self.text_time_scale_info.disable()
# text_time_scale = "控制倍率:" + str(application.time_scale).ljust(4, " ")
# text_time_scale_info = Text(text=text_time_scale, position=(-0.8, 0.5), origin=(-1, 1), background=True)
# def show_button(self):
# b = Button(scale=(0, .25), text='zzz')
# if key == "escape":
# if mouse.locked:
# self.on_disable()
# else:
# sys.exit()
# 按空格键则暂停
def
settings_handler_input
(
self
,
key
):
import
sys
if
key
==
"escape"
:
sys
.
exit
()
# print(key)
elif
key
==
'space'
:
self
.
wp
.
enabled
=
not
self
.
wp
.
enabled
elif
key
==
'left mouse down'
:
print
(
key
)
elif
key
==
'y'
:
# 寻找天体
if
hasattr
(
self
,
"bodies_button_list"
):
if
self
.
bodies_button_list
.
enabled
:
self
.
bodies_button_list_close
()
return
self
.
on_searching_bodies_click
()
elif
key
==
'o'
:
# 重新开始
self
.
on_reset_button_click
()
elif
key
==
'i'
:
# 拖尾开关
if
self
.
on_off_trail
.
value
==
self
.
trail_button_text
:
self
.
on_off_trail
.
value
=
self
.
no_trail_button_text
else
:
self
.
on_off_trail
.
value
=
self
.
trail_button_text
self
.
on_off_trail_changed
()
elif
key
==
'p'
:
# 开始、暂停
if
self
.
on_off_switch
.
value
==
self
.
pause_button_text
:
self
.
on_off_switch
.
value
=
self
.
start_button_text
else
:
self
.
on_off_switch
.
value
=
self
.
pause_button_text
self
.
on_off_switch_changed
()
elif
key
==
'+'
or
key
==
"= up"
:
run_speed_factor
=
self
.
slider_run_speed_factor
.
value
+
self
.
slider_run_speed_factor
.
step
*
50
if
run_speed_factor
>
self
.
slider_run_speed_factor
.
max
:
run_speed_factor
=
self
.
slider_run_speed_factor
.
max
self
.
slider_run_speed_factor
.
value
=
run_speed_factor
self
.
slider_run_speed_factor
.
knob
.
drop
()
elif
key
==
'-'
or
key
==
"- up"
:
run_speed_factor
=
self
.
slider_run_speed_factor
.
value
-
self
.
slider_run_speed_factor
.
step
*
50
if
run_speed_factor
<
self
.
slider_run_speed_factor
.
min
:
run_speed_factor
=
self
.
slider_run_speed_factor
.
min
self
.
slider_run_speed_factor
.
value
=
run_speed_factor
self
.
slider_run_speed_factor
.
knob
.
drop
()
# UrsinaConfig.run_speed_factor *= 2
# application.paused = not application.paused # Pause/unpause the game.
# elif key == 'tab':
# # application.time_scale 属性控制游戏时间流逝的速度。
# # 具体来说,它是一个浮点数,用于调整游戏时间流逝速度的比例,其默认值为 1.0,表示正常速度。
# # 当你将它设置为小于 1.0 的值时,游戏时间会变慢,而设置为大于 1.0 的值时,游戏时间则会变快。
# for idx, time_scale in enumerate(time_scales):
# if float(application.time_scale) == time_scale:
# if idx < len(time_scales) - 1:
# application.time_scale = time_scales[idx + 1]
# break
# else:
# application.time_scale = time_scales[0]
# elif key == '+':
# UrsinaConfig.run_speed_factor *= 2
# elif key == "= up":
# UrsinaConfig.body_spin_factor *= 2
# # if application.time_scale in time_scales:
# # idx = time_scales.index(application.time_scale)
# # if idx < len(time_scales) - 1:
# # application.time_scale = time_scales[idx + 1]
# elif key == '-':
# UrsinaConfig.run_speed_factor *= 0.5
# elif key == "- up":
# UrsinaConfig.body_spin_factor *= 0.5
# # if application.time_scale in time_scales:
# # idx = time_scales.index(application.time_scale)
# # if idx > 0:
# # application.time_scale = time_scales[idx - 1]
#
# self.show_text_time_scale_info()
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录