From 7904d98f42ba1072c19bdc12f2c30f06a5044cca Mon Sep 17 00:00:00 2001 From: march3 Date: Thu, 16 Mar 2023 16:44:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=AA=E9=98=B3=E7=B3=BB=E4=B8=89=E4=BD=93?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bodies/body.py | 9 +- simulators/ursina/ursina_config.py | 13 ++- simulators/ursina/ursina_event.py | 33 +++++++ simulators/ursina/ursina_ui.py | 145 +++++++++++++++++++++++++++++ simulators/ursina_simulator.py | 113 +++++++++++----------- simulators/views/ursina_view.py | 36 +++++-- 6 files changed, 280 insertions(+), 69 deletions(-) create mode 100644 simulators/ursina/ursina_event.py create mode 100644 simulators/ursina/ursina_ui.py diff --git a/bodies/body.py b/bodies/body.py index 27ee938..2809c22 100644 --- a/bodies/body.py +++ b/bodies/body.py @@ -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): # """ diff --git a/simulators/ursina/ursina_config.py b/simulators/ursina/ursina_config.py index e03ff01..c707b5a 100644 --- a/simulators/ursina/ursina_config.py +++ b/simulators/ursina/ursina_config.py @@ -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 diff --git a/simulators/ursina/ursina_event.py b/simulators/ursina/ursina_event.py new file mode 100644 index 0000000..449fd60 --- /dev/null +++ b/simulators/ursina/ursina_event.py @@ -0,0 +1,33 @@ +# -*- 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() diff --git a/simulators/ursina/ursina_ui.py b/simulators/ursina/ursina_ui.py new file mode 100644 index 0000000..5d3921b --- /dev/null +++ b/simulators/ursina/ursina_ui.py @@ -0,0 +1,145 @@ +# -*- 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() diff --git a/simulators/ursina_simulator.py b/simulators/ursina_simulator.py index 118e599..d59e3f9 100644 --- a/simulators/ursina_simulator.py +++ b/simulators/ursina_simulator.py @@ -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() diff --git a/simulators/views/ursina_view.py b/simulators/views/ursina_view.py index c481970..9e54800 100644 --- a/simulators/views/ursina_view.py +++ b/simulators/views/ursina_view.py @@ -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 -- GitLab