提交 3a0f31d4 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 c6ef8540
......@@ -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='',
......
# -*- 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)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册