提交 7904d98f 编写于 作者: 三月三net's avatar 三月三net

太阳系三体模拟器

上级 d3ac3ff8
......@@ -11,6 +11,7 @@ import json
import numpy as np
import math
from common.consts import AU
import copy
class Body(metaclass=ABCMeta):
......@@ -51,8 +52,8 @@ class Body(metaclass=ABCMeta):
self.init_position = np.array(init_position, dtype='float32')
self.init_velocity = np.array(init_velocity, dtype='float32')
self.__position = self.init_position
self.__velocity = self.init_velocity
self.__position = copy.deepcopy(self.init_position)
self.__velocity = copy.deepcopy(self.init_velocity)
self.__density = density
self.__rotation_speed = rotation_speed
......@@ -278,8 +279,8 @@ class Body(metaclass=ABCMeta):
重新设置初始速度和初始位置
:return:
"""
self.position = self.init_position
self.velocity = self.init_velocity
self.position = copy.deepcopy(self.init_position)
self.velocity = copy.deepcopy(self.init_velocity)
# def kinetic_energy(self):
# """
......
......@@ -15,7 +15,7 @@ class UrsinaConfig:
SCALE_FACTOR = 5e-10
# 旋转因子为1,则为正常的转速
ROTATION_SPEED_FACTOR = 1.0
ROTATION_SPEED_FACTOR = 0.01
# ROTATION_SPEED_FACTOR = 0.01
# 速度的倍数
__run_speed_factor = 1.0
......@@ -26,6 +26,8 @@ class UrsinaConfig:
# 摄像机
__camera_factor = 1.0
__on_reset_funcs = []
@property
@classmethod
def run_speed_factor(cls):
......@@ -46,6 +48,15 @@ class UrsinaConfig:
def body_spin_factor(cls, value):
cls.__body_spin_factor = value
@classmethod
def on_reset_subscription(cls, fun):
cls.__on_reset_funcs.append(fun)
@classmethod
def on_reset(cls):
for f in cls.__on_reset_funcs:
f()
# 初始化
UrsinaConfig.run_speed_factor = 1.0
......
# -*- coding:utf-8 -*-
# title :ursina天体运行模拟器
# description :ursina天体运行模拟器
# author :Python超人
# date :2023-02-11
# link :https://gitcode.net/pythoncr/
# python_version :3.8
# ==============================================================================
# pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.douban.com ursina
class UrsinaEvent:
"""
"""
@staticmethod
def init():
if hasattr(UrsinaEvent, "on_reset_funcs"):
return
UrsinaEvent.on_reset_funcs = []
@staticmethod
def on_reset_subscription(fun):
UrsinaEvent.on_reset_funcs.append(fun)
@staticmethod
def on_reset():
for f in UrsinaEvent.on_reset_funcs:
f()
UrsinaEvent.init()
# -*- 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
from ursina.prefabs.first_person_controller import FirstPersonController
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
from ursina import WindowPanel, InputField, Button, Slider, ButtonGroup
class UrsinaUI:
def __init__(self):
Text.default_font = 'simsun.ttc'
# self.pause_handler = Entity(ignore_paused=True)
# 加载中文字体文件
# text_time_scale = "1"
# self.text_time_scale_info = None
# self.pause_handler.input = self.pause_handler_input
# self.show_text_time_scale_info()
# key_info_str = "退出[按2次ESC] 方位控制[鼠标QWEASD] 开始暂停[空格] 控制倍率[Tab - +]"
# key_info = Text(text=key_info_str, position=(-0.8, 0.5), origin=(-1, 1), background=True)
# # self.show_button()
self.slider_body_spin_factor = Slider(text="自转速度", y=-.6, step=.01, min=0.01, max=3, default=1,
color=color.rgba(0.0, 0.0, 0.0, 0.5))
self.slider_run_speed_factor = Slider(text="运行速度", y=-.1, step=.01, min=0.01, max=500, default=1,
color=color.rgba(0.0, 0.0, 0.0, 0.5))
application.time_scale = 0.5
self.slider_control_speed_factor = Slider(text="控制速度", y=-.1, step=.01, min=0.01, max=30, default=0.5,
color=color.rgba(0.0, 0.0, 0.0, 0.5))
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.on_off_switch = ButtonGroup(('||', '○'), min_selection=1, y=0, default='○',
selected_color=color.green, ignore_paused=True,
color=color.rgba(0.0, 0.0, 0.0, 0.5))
self.on_off_switch.selected_color = color.red
self.point_button = Button(text='寻找', origin=(0, 0), y=2,
on_click=self.on_point_button_click, color=color.rgba(0.0, 0.0, 0.0, 0.5))
self.reset_button = Button(text='重置', origin=(0, 0), y=2,
on_click=self.on_reset_button_click, color=color.rgba(0.0, 0.0, 0.0, 0.5))
self.on_off_switch.on_value_changed = self.on_off_switch_changed
wp = WindowPanel(
title='',
content=(
Text('方位控制: Q W E A S D + 鼠标右键'),
# InputField(name='name_field'),
# Button(text='Submit', color=color.azure),
self.point_button,
self.reset_button,
self.on_off_switch,
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)
)
wp.y = 0.5 # wp.panel.scale_y / 2 * wp.scale_y # center the window panel
wp.x = -wp.scale_x
self.wp = wp
def on_point_button_click(self):
pass
def on_reset_button_click(self):
UrsinaEvent.on_reset()
def on_off_switch_changed(self):
if self.on_off_switch.value == "||":
self.on_off_switch.selected_color = color.green
application.paused = True
else:
self.on_off_switch.selected_color = color.red
application.paused = False
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_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 pause_handler_input(self, key):
import sys
time_scales = [0.05, 0.1, 0.2, 0.5, 1, 5, 10, 20, 30]
if key == "escape":
sys.exit()
# print(key)
elif key == 'space':
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()
......@@ -11,6 +11,7 @@ from ursina import Ursina, window, Entity, Grid, Mesh, camera, Text, application
load_texture, held_keys
from ursina.prefabs.first_person_controller import FirstPersonController
from simulators.ursina.ursina_ui import UrsinaUI
from simulators.views.ursina_view import UrsinaView, UrsinaPlayer
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.simulator import Simulator
......@@ -186,62 +187,64 @@ class UrsinaSimulator(Simulator):
# self.create_asteroids()
EditorCamera(ignore_paused=True)
pause_handler = Entity(ignore_paused=True)
# 加载中文字体文件
Text.default_font = 'simsun.ttc'
# text_time_scale = "1"
text_time_scale_info = None
def show_text_time_scale_info():
nonlocal text_time_scale_info
if text_time_scale_info is not None:
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 pause_handler_input(key):
nonlocal text_time_scale_info
time_scales = [0.05, 0.1, 0.2, 0.5, 1, 5, 10, 20, 30]
# print(key)
if key == 'space':
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]
show_text_time_scale_info()
pause_handler.input = pause_handler_input
show_text_time_scale_info()
key_info_str = "退出[按2次ESC] 方位控制[鼠标QWEASD] 开始暂停[空格] 控制倍率[Tab - +]"
key_info = Text(text=key_info_str, position=(-0.8, 0.5), origin=(-1, 1), background=True)
ui = UrsinaUI()
# mouse.visible = True
EditorCamera(ignore_paused=True)
# pause_handler = Entity(ignore_paused=True)
# # 加载中文字体文件
# Text.default_font = 'simsun.ttc'
# # text_time_scale = "1"
# text_time_scale_info = None
#
# def show_text_time_scale_info():
# nonlocal text_time_scale_info
# if text_time_scale_info is not None:
# 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 pause_handler_input(key):
# nonlocal text_time_scale_info
# time_scales = [0.05, 0.1, 0.2, 0.5, 1, 5, 10, 20, 30]
# # print(key)
# if key == 'space':
# 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]
#
# show_text_time_scale_info()
#
# pause_handler.input = pause_handler_input
# show_text_time_scale_info()
# key_info_str = "退出[按2次ESC] 方位控制[鼠标QWEASD] 开始暂停[空格] 控制倍率[Tab - +]"
# key_info = Text(text=key_info_str, position=(-0.8, 0.5), origin=(-1, 1), background=True)
self.app.run()
......
......@@ -16,6 +16,7 @@ import sys
from bodies import Body
from simulators.ursina.ursina_config import UrsinaConfig
from simulators.ursina.ursina_event import UrsinaEvent
from common.color_utils import adjust_brightness, conv_to_vec4_color
from simulators.views.body_view import BodyView
from simulators.views.ursina_mesh import create_sphere, create_torus
......@@ -58,20 +59,36 @@ class UrsinaPlayer(FirstPersonController):
# self.vspeed = 400
# self.speed = 1000
# self.mouse_sensitivity = Vec2(160, 160)
self.on_enable()
# self.on_enable()
# self.rotation_speed = 80
self.on_disable()
def input(self, key):
if key == "escape":
if mouse.locked:
self.on_disable()
else:
sys.exit()
return super().input(key)
# def input(self, key):
# if key == "escape":
# if mouse.locked:
# self.on_disable()
# else:
# sys.exit()
# return super().input(key)
class Planet(Entity):
def on_reset(self):
# 删除拖尾
for entity, pos in self.trails.items():
destroy(entity)
self.body_view.body.reset()
# pos = body.init_position * body.distance_scale * UrsinaConfig.SCALE_FACTOR
# vel = body.init_velocity
# self.x = -pos[1]
# self.y = pos[2]
# self.z = pos[0]
# self.x = pos[0]
# self.y = pos[1]
# self.z = pos[2]
def __init__(self, body_view: BodyView):
self.body_view = body_view
self.rotation_speed = self.body_view.body.rotation_speed
......@@ -95,6 +112,8 @@ class Planet(Entity):
model = create_sphere(0.5, 32)
rotation = (0, 0, 0)
UrsinaEvent.on_reset_subscription(self.on_reset)
super().__init__(
# model="sphere",
model=model,
......@@ -233,7 +252,6 @@ class Planet(Entity):
if len(self.body_view.body.his_position()) > 1:
self.create_trails()
def follow_parent(self):
if not hasattr(self.body_view, "bodies_system"):
return
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册