From 3a0f31d4be8b617de9b84e40a2825651fd447ae1 Mon Sep 17 00:00:00 2001 From: march3 Date: Tue, 12 Dec 2023 23:32:12 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?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 --- sim_scenes/featured/the_lost_planet.py | 314 ++++---------- sim_scenes/featured/the_lost_planet_2.py | 503 +++++++++++++++++++++++ 2 files changed, 580 insertions(+), 237 deletions(-) create mode 100644 sim_scenes/featured/the_lost_planet_2.py diff --git a/sim_scenes/featured/the_lost_planet.py b/sim_scenes/featured/the_lost_planet.py index ba43f62..4f12090 100644 --- a/sim_scenes/featured/the_lost_planet.py +++ b/sim_scenes/featured/the_lost_planet.py @@ -15,6 +15,7 @@ from objs.battleship import BattleShip from sim_scenes.func import mayavi_run, ursina_run, create_sphere_sky from sim_scenes.universe_sim_scenes import UniverseSimScenes from simulators.func import ext_fun_for_method +from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_event import UrsinaEvent from ursina import camera, Vec3, distance import math @@ -22,7 +23,7 @@ import math class TheLostPlanetSim(UniverseSimScenes): def __init__(self): - self.sun = Sun(size_scale=5e2).set_resolution(60) # 太阳放大 500 倍 + self.sun = Sun(size_scale=6e2).set_resolution(60) # 太阳放大 500 倍 self.sun.glows = (30, 1.005, 0.03) # self.asteroids = Asteroids(size_scale=1.08e2, parent=self.sun) # 小行星模拟(仅 ursina 模拟器支持) @@ -30,23 +31,25 @@ class TheLostPlanetSim(UniverseSimScenes): # inner_radius:内圆半径 outer_radius:外圆半径,subdivisions:细分数,控制圆环的细节和精度 # self.asteroids.torus_zone = 4.7, 5.5, 64 - self.moon = Moon(size_scale=3.5e3, init_position=[0, 0, (0.4 + 2.4) * AU], distance_scale=1.76) + self.moon = Moon(size_scale=3.5e3, init_position=[0, 0, (0.5 + 2.5) * AU], distance_scale=1.76) # ceres = Ceres(size_scale=3e3, distance_scale=1.7) - self.earth = Earth(size_scale=3e3, distance_scale=3.8) - self.mars = Mars(size_scale=3e3, distance_scale=2.9) + self.mercury = Mercury(size_scale=3e3, distance_scale=8.5) + self.venus = Venus(size_scale=3e3, distance_scale=5) + self.earth = Earth(size_scale=3e3, distance_scale=4.05) + self.mars = Mars(size_scale=3e3, distance_scale=2.95) self.jupiter = Jupiter(size_scale=0.68e3, distance_scale=1.12) self.saturn = Saturn(size_scale=0.68e3, distance_scale=0.74) - self.ship = ScifiGunship(name="飞船", mass=1e30, color=(111, 140, 255), - init_position=self.mars.init_position, - init_velocity=[0, 0, 0], - size_scale=2e4, distance_scale=2.9). \ - set_ignore_gravity(True).set_light_disable(True) + # self.ship = ScifiGunship(name="飞船", mass=1e30, color=(111, 140, 255), + # init_position=self.mars.init_position, + # init_velocity=[0, 0, 0], + # size_scale=2e4, distance_scale=2.9). \ + # set_ignore_gravity(True).set_light_disable(True) self.bodies = [ self.sun, - Mercury(size_scale=3e3, distance_scale=7.3), # 水星放大 4000 倍 - Venus(size_scale=3e3, distance_scale=4.5), # 金星放大 4000 倍 + self.mercury, # 水星放大 4000 倍 + self.venus, # 金星放大 4000 倍 self.earth, # 地球放大 4000 倍 self.mars, # 火星放大 4000 倍 # asteroids, @@ -56,7 +59,7 @@ class TheLostPlanetSim(UniverseSimScenes): # Earth(size_scale=3e3, init_position=[0, 0, (3.64) * AU]), # 地球放大 4000 倍 self.jupiter, # 木星放大 680 倍 self.saturn, # 土星放大 680 倍 - Uranus(size_scale=0.8e3, distance_scale=0.42), # 天王星放大 800 倍 + Uranus(size_scale=0.8e3, distance_scale=0.43), # 天王星放大 800 倍 Neptune(size_scale=1e3, distance_scale=0.3), # 海王星放大 1000 倍 ] # 水星 0.4AU @@ -72,6 +75,7 @@ class TheLostPlanetSim(UniverseSimScenes): for idx, body in enumerate(self.bodies): if isinstance(body, Asteroids): continue + body.init_position = [-body.init_position[2], 0, 0] body.rotation_speed = 0 planet_no += 1 # body.init_velocity = [0, 0, 0] @@ -98,7 +102,7 @@ class TheLostPlanetSim(UniverseSimScenes): else: an = 0.4 + 0.3 * pow(2, planet_no - 2) # print(body.name, an, body.position[2] / AU) - self.bodies += [self.ship] + # self.bodies += [self.ship] self.step_index = 0 self.init_steps() @@ -107,16 +111,18 @@ class TheLostPlanetSim(UniverseSimScenes): 事件绑定后,模拟器运行前会触发 @return: """ - from ursina import camera, Vec3,application + from ursina import camera, Vec3, application # 创建天空 - create_sphere_sky(scale=20000, rotation_x=0, rotation_y=80) + create_sphere_sky(scale=20000, rotation_x=0, rotation_y=170) camera.clip_plane_near = 0.1 camera.clip_plane_far = 1000000 - camera.look_at(self.jupiter.planet) + # self.show_grid_axises(50) + + # camera.look_at(self.jupiter.planet) # camera.look_at(sun.planet) - camera.rotation_z -= 90 + # camera.rotation_z -= 90 # # self.moon.planet.update = lambda :None # def moon_update(): @@ -170,84 +176,13 @@ class TheLostPlanetSim(UniverseSimScenes): planet.update = alpha_animation # ext_fun_for_method(planet, after_run_fun=alpha_animation) - # def set_alpha_animation(self, body, begin_alpha, end_alpha, interval, is_destroy=False): - # from ursina import destroy - # if hasattr(body, "planet"): - # planet = body.planet - # else: - # planet = body - # planet.alpha = 0 - # - # def alpha_animation(): - # alpha = planet.alpha - # alpha += interval - # if alpha > 1: - # alpha = 1 - # planet.enabled = (alpha > 0) - # planet.alpha = alpha - # # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) - # # print(body, planet.alpha, planet.rotation_x, planet.rotation_y, planet.rotation_z) - # - # planet.update = alpha_animation - # # ext_fun_for_method(planet, after_run_fun=alpha_animation) - # def moon_fade_in(self): - # """ - # 月球渐渐显示 - # @return: - # """ - # # self.moon.planet.look_at(self.mars.planet) - # self.moon.planet.alpha = 0 - # def alpha_animation(): - # from ursina import Vec2,Vec4 - # planet = self.moon.planet.main_entity - # alpha = planet.alpha - # alpha += 0.01 - # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) - # planet.alpha = alpha - # planet.texture_offset = Vec2(0, 0) - # planet.texture_scale = Vec2(1, 1) - # - # self.moon.planet.update = alpha_animation # lambda: None - # self.set_alpha_animation(self.moon, 0.0, 1.0, 0.005) - # - # def moon_fade_in(self): - # from ursina import Vec4 - # planet = self.moon.planet - # planet.alpha = 0 - # def update_moon(): - # alpha = planet.alpha - # alpha += 0.01 - # if alpha > 1.0: - # alpha = 1.0 - # planet.update = lambda: None - # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) - # planet.alpha = alpha - # - # planet.update = update_moon - - # def earth_fade_in(self): - # """ - # 月球渐渐显示 - # @return: - # """ - # self.earth.planet.look_at(self.mars.planet) - # # self.moon.planet.update = lambda: None - # self.set_alpha_animation(self.earth, 0.0, 1.0, 0.005) - - # def moon_fade_out(self): - # """ - # 月球渐渐显示 - # @return: - # """ - # self.moon.planet.look_at(self.mars.planet) - # # self.moon.planet.update = lambda: None - # self.set_alpha_animation(self.moon, 1.0, 0.0, 0.005) def create_asteroid(self, init_angle=110, smooth=False): from ursina import Entity, color, Vec3 import math import random pos = self.moon.planet.position # + Vec3() - radius = self.moon.planet.position[2] + 50 * random.random() - 15 # * moon.distance_scale + # min(self.moon.planet.position) + radius = min(self.moon.planet.position) + 50 * random.random() - 15 # * moon.distance_scale asteroid = Entity(model='sphere', position=pos, color=color.white, scale=1.5) asteroid.s_angle = init_angle asteroid.init_pos = pos @@ -301,129 +236,68 @@ class TheLostPlanetSim(UniverseSimScenes): for a in self.asteroids: self.set_alpha_animation(a, 1.0, 0.0, 0.01, is_destroy=True) - def ship_go_to_moon(self): - - planet = self.ship.planet - origin_udpate = planet.update - - def go_to_moon(): - # origin_udpate() - self.ship.planet.look_at(self.moon.planet) - planet.position += planet.forward * 20 - planet.rotation_x = 0 - d = distance(planet, self.moon.planet) - if d < 2: - planet.update = lambda: None - planet.enabled = False - self.step_index += 1 - - planet.update = go_to_moon - - def moon_fade_in(self): - """ - 月球渐渐显示 - @return: - """ - self.moon.planet.look_at(self.mars.planet) - self.moon.planet.update = lambda: None - self.set_alpha_animation(self.moon, 0.0, 1.0, 0.005) - - # def moon_fade_out(self): - # """ - # 月球渐渐显示 - # @return: - # """ - # self.moon.planet.look_at(self.mars.planet) - # # self.moon.planet.update = lambda: None - # self.set_alpha_animation(self.moon, 1.0, 0.0, 0.005) - - def moon_renovation(self): - """ - 月球改造中 - @return: - """ - if not hasattr(self, "moon_redesign_last_time"): - self.moon_redesign_last_time = time.time() - self.asteroid_num = 0 - c_time = time.time() - # set_alpha_animation(asteroids, 0.0, 1.0, 0.01) - if c_time - self.moon_redesign_last_time > 0.02: - self.moon_redesign_last_time = c_time - self.create_asteroid(smooth=True) - self.asteroid_num += 1 - - camera.position += camera.forward*0.1 - - def moon_move_to_target_and_rotation(self, target, rotation_radius, end_angle, end_tag, - forward, - angle_val): - - if hasattr(target, "planet"): - target_planet = target.planet.main_entity - else: - target_planet = target.main_entity + def init_steps(self): - if not hasattr(target_planet, "is_forward"): - target_planet.is_forward = True + def earth_orbit_the_sun(): + if not hasattr(self, "moon_aroundearth"): + # setattr(self, "step_04", True) + self.body_orbit_the_sun(self.earth, 90) + self.body_orbit_the_sun(self.mars, 90) + self.body_orbit_the_sun(self.venus, 90) + self.body_orbit_the_sun(self.mercury, 90) - if target_planet.is_forward: - target_pos = target_planet.position + Vec3(-rotation_radius, 0, 0) - self.moon.planet.look_at(target_pos) - d = distance(self.moon.planet, target_pos) - if d > 3: - self.moon.planet.position += self.moon.planet.forward * forward - else: - target_planet.is_forward = False - else: - if not hasattr(target_planet, "moon_angle"): - setattr(target_planet, "moon_angle", 180) - moon_angle = getattr(target_planet, "moon_angle") + def jupter_orbit_the_sun(): + if not hasattr(self, "moon_aroundearth"): + # setattr(self, "step_04", True) + self.body_orbit_the_sun(self.jupiter, 90) + self.body_orbit_the_sun(self.saturn, 90) - angle = math.pi * moon_angle / 180 - x = target_planet.x + rotation_radius * math.cos(angle) - z = target_planet.z + rotation_radius * math.sin(angle) - self.moon.planet.position = (x, 0, z) - setattr(target_planet, "moon_angle", moon_angle + angle_val) + self.steps = [ + (earth_orbit_the_sun, 3, 1), + (jupter_orbit_the_sun, 3, 1), + (self.asteroid_fade_in, 3, 1), + (self.asteroid_fade_out, 3, 1), + # fun, wait_years, run_times + (self.camera_back_1, 3, -1), + (self.camera_back_2, -1, -1), + (lambda: None, -1, -1) + ] - if moon_angle >= end_angle: - setattr(self, end_tag, True) - self.step_index += 1 + def body_orbit_the_sun(self, body, start_angle, angle_speed=0.5): + if not hasattr(body, "orbit_radius"): + body.orbit_radius = body.position[0] * UrsinaConfig.SCALE_FACTOR * body.distance_scale + body.orbit_angle = start_angle - # print("moon_angle", moon_angle) + # origin_update = body.planet.update + def orbit_update(): - def init_steps(self): + if body.orbit_angle > 180: + body.orbit_angle = 180 + body.planet.update = lambda: None - def step_05(): - if not hasattr(self, "moon_around_mars"): - # setattr(self, "step_04", True) - self.moon_move_to_target_and_rotation(target=self.mars, - rotation_radius=12, - end_angle=180 + 360 * 3, - end_tag="moon_around_mars", - forward=0.02, angle_val=0.8) + angle = math.pi * body.orbit_angle / 180 + x = body.orbit_radius * math.cos(angle) + z = body.orbit_radius * math.sin(angle) + body.planet.main_entity.position = Vec3(x, 0, z) + body.orbit_angle += angle_speed + print(body.orbit_angle) - def step_06(): - if not hasattr(self, "moon_around_earth"): - self.moon_move_to_target_and_rotation(target=self.earth, - rotation_radius=15, - end_angle=7200, - end_tag="moon_around_earth", - forward=0.02, angle_val=1) + body.planet.update = orbit_update + def camera_back_1(self): + return + if camera.position[0] < 460: + camera.position += camera.back - self.steps = [ - (self.asteroid_fade_in, 3, 1), - (self.asteroid_fade_out, 3, 1), - (self.moon_fade_in, 3, 1), - # (self.ship_go_to_moon, -1, 1), - (self.moon_renovation, 10, -1), - (step_05, -1, -1), - (step_06, 50, -1), - (lambda: exit(0), -1, -1) - ] + def camera_back_2(self): + return + if camera.position[0] < 550: + # camera.position += camera.right + camera.position += camera.back def on_timer_changed(self, time_data): + # camera.position += camera.right if time_data.years > 1: if self.step_index > len(self.steps) - 1: self.step_index = len(self.steps) - 1 @@ -440,46 +314,11 @@ class TheLostPlanetSim(UniverseSimScenes): self.step_index += 1 # print(self.step_index, fun.__name__) - def on_timer_changed2(self, time_data): - from ursina import camera, Vec3, distance - import math - - if time_data.years > 1 and not hasattr(self, "step_01"): - # 小行星群渐渐显示,运行一次 - self.asteroid_fade_in() - setattr(self, "step_01", True) # 控制运行一次 - elif time_data.years > 6 and not hasattr(self, "step_02"): - # 小行星群渐渐消失,运行一次 - self.asteroid_fade_out() - setattr(self, "step_02", True) # 控制运行一次 - elif time_data.years > 8 and not hasattr(self.moon, "step_03"): - # 月球渐渐显示,运行一次 - self.moon_fade_in() - setattr(self.moon, "step_03", True) # 控制运行一次 - elif time_data.years > 10 and not hasattr(self, "step_04"): - # 月球改造中,运行多次 - self.moon_renovation() - - if time_data.years > 25 and not hasattr(self, "moon_around_mars"): - setattr(self, "step_04", True) - self.moon_move_to_target_and_rotation(target=self.mars, - rotation_radius=12, - end_angle=720, - end_tag="moon_around_mars", - forward=0.03, angle_val=3) - - elif hasattr(self, "moon_around_mars") and not hasattr(self, "moon_around_earth"): - self.moon_move_to_target_and_rotation(target=self.earth, - rotation_radius=15, - end_angle=720, - end_tag="moon_around_earth", - forward=0.03, angle_val=3) - if __name__ == '__main__': sim = TheLostPlanetSim() - UniverseSimScenes.set_window_size((1920, 1079), False) + # UniverseSimScenes.set_window_size((1920, 1079), False) # 运行前会触发 on_ready UrsinaEvent.on_ready_subscription(sim.on_ready) # UrsinaEvent.after_ready_subscription(after_ready) @@ -495,7 +334,8 @@ if __name__ == '__main__': show_camera_info=False, # position=(0, 2 * AU, -11 * AU), # position=(0, 20 * AU, 10 * AU), - position=(5.5 * AU, AU, 5 * AU), + # position=(4.5 * AU, AU, 5 * AU), + position=(5 * AU, AU/2, -5 * AU), timer_enabled=True, # show_timer=True, cosmic_bg='', diff --git a/sim_scenes/featured/the_lost_planet_2.py b/sim_scenes/featured/the_lost_planet_2.py new file mode 100644 index 0000000..ba43f62 --- /dev/null +++ b/sim_scenes/featured/the_lost_planet_2.py @@ -0,0 +1,503 @@ +# -*- coding:utf-8 -*- +# title :太阳系中消失的行星 +# description :太阳系中消失的行星 +# author :Python超人 +# date :2023-12-05 +# link :https://gitcode.net/pythoncr/ +# python_version :3.9 +# ============================================================================== +import time + +from bodies import Sun, Mercury, Venus, Earth, Mars, Moon, Ceres, Jupiter, Saturn, Uranus, Neptune, Pluto, Asteroids +from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, SECONDS_PER_MONTH, SECONDS_PER_YEAR, AU +from objs import CoreValagaClas, ScifiGunship, SpaceShip, StarWarsSpeeder, SciFiBomber +from objs.battleship import BattleShip +from sim_scenes.func import mayavi_run, ursina_run, create_sphere_sky +from sim_scenes.universe_sim_scenes import UniverseSimScenes +from simulators.func import ext_fun_for_method +from simulators.ursina.ursina_event import UrsinaEvent +from ursina import camera, Vec3, distance +import math + + +class TheLostPlanetSim(UniverseSimScenes): + def __init__(self): + self.sun = Sun(size_scale=5e2).set_resolution(60) # 太阳放大 500 倍 + self.sun.glows = (30, 1.005, 0.03) + # self.asteroids = Asteroids(size_scale=1.08e2, parent=self.sun) # 小行星模拟(仅 ursina 模拟器支持) + + # 环状星群带(inner_radius, outer_radius, subdivisions) + # inner_radius:内圆半径 outer_radius:外圆半径,subdivisions:细分数,控制圆环的细节和精度 + # self.asteroids.torus_zone = 4.7, 5.5, 64 + + self.moon = Moon(size_scale=3.5e3, init_position=[0, 0, (0.4 + 2.4) * AU], distance_scale=1.76) + # ceres = Ceres(size_scale=3e3, distance_scale=1.7) + self.earth = Earth(size_scale=3e3, distance_scale=3.8) + self.mars = Mars(size_scale=3e3, distance_scale=2.9) + self.jupiter = Jupiter(size_scale=0.68e3, distance_scale=1.12) + self.saturn = Saturn(size_scale=0.68e3, distance_scale=0.74) + + self.ship = ScifiGunship(name="飞船", mass=1e30, color=(111, 140, 255), + init_position=self.mars.init_position, + init_velocity=[0, 0, 0], + size_scale=2e4, distance_scale=2.9). \ + set_ignore_gravity(True).set_light_disable(True) + + self.bodies = [ + self.sun, + Mercury(size_scale=3e3, distance_scale=7.3), # 水星放大 4000 倍 + Venus(size_scale=3e3, distance_scale=4.5), # 金星放大 4000 倍 + self.earth, # 地球放大 4000 倍 + self.mars, # 火星放大 4000 倍 + # asteroids, + self.moon, + # ceres, + # Earth(size_scale=3e3, init_position=[0, 0, (2.17) * AU]), # 地球放大 4000 倍 + # Earth(size_scale=3e3, init_position=[0, 0, (3.64) * AU]), # 地球放大 4000 倍 + self.jupiter, # 木星放大 680 倍 + self.saturn, # 土星放大 680 倍 + Uranus(size_scale=0.8e3, distance_scale=0.42), # 天王星放大 800 倍 + Neptune(size_scale=1e3, distance_scale=0.3), # 海王星放大 1000 倍 + ] + # 水星 0.4AU + # 金星 0.4+0.3 AU + # 地球 0.4+0.6 AU + # 火星 0.4+1.2 AU + # 木星 0.4+4.8 AU + # 土星 0.4+9.6 AU + # 天王星 0.4+19.2 AU + # d = (n+4)/10 + # an = 0.4+0.3×(2n-2) + planet_no = -1 + for idx, body in enumerate(self.bodies): + if isinstance(body, Asteroids): + continue + body.rotation_speed = 0 + planet_no += 1 + # body.init_velocity = [0, 0, 0] + # an = 0.4 + 0.3 * pow(2,idx) + # an = (idx+4)/10 + # 其中k=0,1,2,4,8,16,32,64,128 (0以后数字为2的2次方) + # 行星 公式推得值 实测值 + # 金星 0.7 0.72 + # 地球 1 1 + # 火星 1.6 1.52 + # 谷神星 2.8 2.9 [1] + # 木星 5.2 5.2 + # 土星 10 9.54 + # 天王星 19.6 19.18 + # 海王星 38.8 30.06 + # 冥王星 77.2 39.44 + # 提丢斯-波得定则 + # https://baike.baidu.com/item/%E6%8F%90%E4%B8%A2%E6%96%AF-%E6%B3%A2%E5%BE%97%E5%AE%9A%E5%88%99/859407 + # 小行星 2.17-3.64天文单位 + if planet_no == 0: + continue + elif planet_no == 1: + an = 0.4 + else: + an = 0.4 + 0.3 * pow(2, planet_no - 2) + # print(body.name, an, body.position[2] / AU) + self.bodies += [self.ship] + self.step_index = 0 + self.init_steps() + + def on_ready(self): + """ + 事件绑定后,模拟器运行前会触发 + @return: + """ + from ursina import camera, Vec3,application + # 创建天空 + create_sphere_sky(scale=20000, rotation_x=0, rotation_y=80) + + camera.clip_plane_near = 0.1 + camera.clip_plane_far = 1000000 + + camera.look_at(self.jupiter.planet) + # camera.look_at(sun.planet) + camera.rotation_z -= 90 + # + # self.moon.planet.update = lambda :None + # def moon_update(): + # self.moon.planet.scale = 80 + # # self.moon.planet.rotation_y += 10 + # + # ext_fun_for_method(self.moon.planet, after_run_fun=moon_update) + + # for i in range(10): + # time.sleep(0.1) + # create_asteroid() + + # UniverseSimScenes.show_grid_axises() + + # self.asteroids.planet.enabled = False + self.moon.planet.enabled = False + application.time_scale = 0.1 + # ceres.planet.enabled = False + # self.moon.planet.look_at(self.mars.planet) + + def set_alpha_animation(self, body, begin_alpha, end_alpha, interval, is_destroy=False): + from ursina import destroy + if hasattr(body, "planet"): + planet = body.planet + else: + planet = body + planet.alpha = begin_alpha + if begin_alpha > end_alpha: + interval = -abs(interval) + else: + interval = abs(interval) + + origin_update = planet.update + + def alpha_animation(): + from ursina import camera, Vec4 + origin_update() + alpha = planet.alpha + alpha += interval + if (interval > 0 and alpha >= end_alpha) or (interval < 0 and alpha <= end_alpha): + alpha = end_alpha + planet.update = origin_update + + planet.enabled = (alpha > 0) + planet.alpha = alpha + if is_destroy and not planet.enabled: + destroy(planet) + # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) + # print(body, planet.alpha, planet.rotation_x, planet.rotation_y, planet.rotation_z) + + planet.update = alpha_animation + # ext_fun_for_method(planet, after_run_fun=alpha_animation) + + # def set_alpha_animation(self, body, begin_alpha, end_alpha, interval, is_destroy=False): + # from ursina import destroy + # if hasattr(body, "planet"): + # planet = body.planet + # else: + # planet = body + # planet.alpha = 0 + # + # def alpha_animation(): + # alpha = planet.alpha + # alpha += interval + # if alpha > 1: + # alpha = 1 + # planet.enabled = (alpha > 0) + # planet.alpha = alpha + # # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) + # # print(body, planet.alpha, planet.rotation_x, planet.rotation_y, planet.rotation_z) + # + # planet.update = alpha_animation + # # ext_fun_for_method(planet, after_run_fun=alpha_animation) + # def moon_fade_in(self): + # """ + # 月球渐渐显示 + # @return: + # """ + # # self.moon.planet.look_at(self.mars.planet) + # self.moon.planet.alpha = 0 + # def alpha_animation(): + # from ursina import Vec2,Vec4 + # planet = self.moon.planet.main_entity + # alpha = planet.alpha + # alpha += 0.01 + # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) + # planet.alpha = alpha + # planet.texture_offset = Vec2(0, 0) + # planet.texture_scale = Vec2(1, 1) + # + # self.moon.planet.update = alpha_animation # lambda: None + # self.set_alpha_animation(self.moon, 0.0, 1.0, 0.005) + # + # def moon_fade_in(self): + # from ursina import Vec4 + # planet = self.moon.planet + # planet.alpha = 0 + # def update_moon(): + # alpha = planet.alpha + # alpha += 0.01 + # if alpha > 1.0: + # alpha = 1.0 + # planet.update = lambda: None + # planet.color = Vec4(planet.color[0], planet.color[1], planet.color[2], alpha) + # planet.alpha = alpha + # + # planet.update = update_moon + + # def earth_fade_in(self): + # """ + # 月球渐渐显示 + # @return: + # """ + # self.earth.planet.look_at(self.mars.planet) + # # self.moon.planet.update = lambda: None + # self.set_alpha_animation(self.earth, 0.0, 1.0, 0.005) + + # def moon_fade_out(self): + # """ + # 月球渐渐显示 + # @return: + # """ + # self.moon.planet.look_at(self.mars.planet) + # # self.moon.planet.update = lambda: None + # self.set_alpha_animation(self.moon, 1.0, 0.0, 0.005) + def create_asteroid(self, init_angle=110, smooth=False): + from ursina import Entity, color, Vec3 + import math + import random + pos = self.moon.planet.position # + Vec3() + radius = self.moon.planet.position[2] + 50 * random.random() - 15 # * moon.distance_scale + asteroid = Entity(model='sphere', position=pos, color=color.white, scale=1.5) + asteroid.s_angle = init_angle + asteroid.init_pos = pos + y = 10 * random.random() - 5 + speed = random.random() / 7 + 0.2 + + def rotation(): + angle = math.pi * asteroid.s_angle / 180 + x = self.sun.planet.x + radius * math.cos(angle) + z = self.sun.planet.z + radius * math.sin(angle) + target_pos = Vec3(x, y, z) + if asteroid.init_pos is None or not smooth: + # angle = math.pi * asteroid.s_angle / 180 + # x = self.sun.planet.x + radius * math.cos(angle) + # z = self.sun.planet.z + radius * math.sin(angle) + asteroid.position = target_pos + else: + asteroid.look_at(target_pos) + asteroid.position += asteroid.forward * 1.5 + d = distance(asteroid.position, target_pos) + if d < 3: + asteroid.init_pos = None + asteroid.s_angle += speed + + asteroid.update = rotation + return asteroid + + def create_asteroids(self): + self.asteroids = [] + for i in range(400): + self.asteroids.append(self.create_asteroid(i)) + + # def clear_asteroids(self): + # for a in self.asteroids: + # a.enabled = False + + def asteroid_fade_in(self): + """ + 小行星群渐渐显示 + @return: + """ + self.create_asteroids() + for a in self.asteroids: + self.set_alpha_animation(a, 0.0, 1.0, 0.01) + + def asteroid_fade_out(self): + """ + 小行星群渐渐消失 + @return: + """ + for a in self.asteroids: + self.set_alpha_animation(a, 1.0, 0.0, 0.01, is_destroy=True) + + def ship_go_to_moon(self): + + planet = self.ship.planet + origin_udpate = planet.update + + def go_to_moon(): + # origin_udpate() + self.ship.planet.look_at(self.moon.planet) + planet.position += planet.forward * 20 + planet.rotation_x = 0 + d = distance(planet, self.moon.planet) + if d < 2: + planet.update = lambda: None + planet.enabled = False + self.step_index += 1 + + planet.update = go_to_moon + + def moon_fade_in(self): + """ + 月球渐渐显示 + @return: + """ + self.moon.planet.look_at(self.mars.planet) + self.moon.planet.update = lambda: None + self.set_alpha_animation(self.moon, 0.0, 1.0, 0.005) + + # def moon_fade_out(self): + # """ + # 月球渐渐显示 + # @return: + # """ + # self.moon.planet.look_at(self.mars.planet) + # # self.moon.planet.update = lambda: None + # self.set_alpha_animation(self.moon, 1.0, 0.0, 0.005) + + def moon_renovation(self): + """ + 月球改造中 + @return: + """ + if not hasattr(self, "moon_redesign_last_time"): + self.moon_redesign_last_time = time.time() + self.asteroid_num = 0 + c_time = time.time() + # set_alpha_animation(asteroids, 0.0, 1.0, 0.01) + if c_time - self.moon_redesign_last_time > 0.02: + self.moon_redesign_last_time = c_time + self.create_asteroid(smooth=True) + self.asteroid_num += 1 + + camera.position += camera.forward*0.1 + + def moon_move_to_target_and_rotation(self, target, rotation_radius, end_angle, end_tag, + forward, + angle_val): + + if hasattr(target, "planet"): + target_planet = target.planet.main_entity + else: + target_planet = target.main_entity + + if not hasattr(target_planet, "is_forward"): + target_planet.is_forward = True + + if target_planet.is_forward: + target_pos = target_planet.position + Vec3(-rotation_radius, 0, 0) + self.moon.planet.look_at(target_pos) + d = distance(self.moon.planet, target_pos) + if d > 3: + self.moon.planet.position += self.moon.planet.forward * forward + else: + target_planet.is_forward = False + else: + if not hasattr(target_planet, "moon_angle"): + setattr(target_planet, "moon_angle", 180) + moon_angle = getattr(target_planet, "moon_angle") + + angle = math.pi * moon_angle / 180 + x = target_planet.x + rotation_radius * math.cos(angle) + z = target_planet.z + rotation_radius * math.sin(angle) + self.moon.planet.position = (x, 0, z) + + setattr(target_planet, "moon_angle", moon_angle + angle_val) + + if moon_angle >= end_angle: + setattr(self, end_tag, True) + self.step_index += 1 + + # print("moon_angle", moon_angle) + + def init_steps(self): + + def step_05(): + if not hasattr(self, "moon_around_mars"): + # setattr(self, "step_04", True) + self.moon_move_to_target_and_rotation(target=self.mars, + rotation_radius=12, + end_angle=180 + 360 * 3, + end_tag="moon_around_mars", + forward=0.02, angle_val=0.8) + + def step_06(): + if not hasattr(self, "moon_around_earth"): + self.moon_move_to_target_and_rotation(target=self.earth, + rotation_radius=15, + end_angle=7200, + end_tag="moon_around_earth", + forward=0.02, angle_val=1) + + + self.steps = [ + (self.asteroid_fade_in, 3, 1), + (self.asteroid_fade_out, 3, 1), + (self.moon_fade_in, 3, 1), + # (self.ship_go_to_moon, -1, 1), + (self.moon_renovation, 10, -1), + (step_05, -1, -1), + (step_06, 50, -1), + (lambda: exit(0), -1, -1) + ] + + def on_timer_changed(self, time_data): + if time_data.years > 1: + if self.step_index > len(self.steps) - 1: + self.step_index = len(self.steps) - 1 + fun, wait_years, run_times = self.steps[self.step_index] + if not hasattr(self, f"{fun.__name__}_wait_years"): + setattr(self, f"{fun.__name__}_wait_years", time_data.years) + setattr(self, f"{fun.__name__}_run_times", 0) + fun_run_times = getattr(self, f"{fun.__name__}_run_times") + if fun_run_times < run_times or run_times < 0: + fun() + setattr(self, f"{fun.__name__}_run_times", fun_run_times + 1) + fun_wait_years = getattr(self, f"{fun.__name__}_wait_years") + if wait_years + fun_wait_years < time_data.years and wait_years > 0: + self.step_index += 1 + # print(self.step_index, fun.__name__) + + def on_timer_changed2(self, time_data): + from ursina import camera, Vec3, distance + import math + + if time_data.years > 1 and not hasattr(self, "step_01"): + # 小行星群渐渐显示,运行一次 + self.asteroid_fade_in() + setattr(self, "step_01", True) # 控制运行一次 + elif time_data.years > 6 and not hasattr(self, "step_02"): + # 小行星群渐渐消失,运行一次 + self.asteroid_fade_out() + setattr(self, "step_02", True) # 控制运行一次 + elif time_data.years > 8 and not hasattr(self.moon, "step_03"): + # 月球渐渐显示,运行一次 + self.moon_fade_in() + setattr(self.moon, "step_03", True) # 控制运行一次 + elif time_data.years > 10 and not hasattr(self, "step_04"): + # 月球改造中,运行多次 + self.moon_renovation() + + if time_data.years > 25 and not hasattr(self, "moon_around_mars"): + setattr(self, "step_04", True) + self.moon_move_to_target_and_rotation(target=self.mars, + rotation_radius=12, + end_angle=720, + end_tag="moon_around_mars", + forward=0.03, angle_val=3) + + elif hasattr(self, "moon_around_mars") and not hasattr(self, "moon_around_earth"): + self.moon_move_to_target_and_rotation(target=self.earth, + rotation_radius=15, + end_angle=720, + end_tag="moon_around_earth", + forward=0.03, angle_val=3) + + +if __name__ == '__main__': + sim = TheLostPlanetSim() + + UniverseSimScenes.set_window_size((1920, 1079), False) + # 运行前会触发 on_ready + UrsinaEvent.on_ready_subscription(sim.on_ready) + # UrsinaEvent.after_ready_subscription(after_ready) + UrsinaEvent.on_timer_changed_subscription(sim.on_timer_changed) + # 使用 ursina 查看的运行效果 + # 常用快捷键: P:运行和暂停 O:重新开始 I:显示天体轨迹 + # position = 左-右+、上+下-、前+后- + ursina_run(sim.bodies, + SECONDS_PER_YEAR, + gravity_works=False, + show_exit_button=False, + show_control_info=False, + show_camera_info=False, + # position=(0, 2 * AU, -11 * AU), + # position=(0, 20 * AU, 10 * AU), + position=(5.5 * AU, AU, 5 * AU), + timer_enabled=True, + # show_timer=True, + cosmic_bg='', + # show_trail=True, + show_grid=False) -- GitLab