提交 4118345e 编写于 作者: 三月三net's avatar 三月三net

Python超人-宇宙模拟器

上级 99064a26
...@@ -81,6 +81,28 @@ def set_camera_parent(target): ...@@ -81,6 +81,28 @@ def set_camera_parent(target):
camera.parent = target camera.parent = target
def create_main_entity(target, rotation_x=None, rotation_y=None, rotation_z=None):
from ursina import Entity
if hasattr(target, "planet"):
planet = target.planet
else:
planet = target
main_entity = Entity(position=planet.position)
planet.position = [0, 0, 0]
planet.parent = main_entity
if rotation_x is not None:
planet.rotation_x = rotation_x
if rotation_y is not None:
planet.rotation_y = rotation_y
if rotation_z is not None:
planet.rotation_z = rotation_z
planet.main_entity = main_entity
def camera_look_at(target, rotation_x=None, rotation_y=None, rotation_z=None): def camera_look_at(target, rotation_x=None, rotation_y=None, rotation_z=None):
""" """
让摄像机看向指定天体 让摄像机看向指定天体
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
from bodies import Sun, Earth, Moon from bodies import Sun, Earth, Moon
from objs import CoreValagaClas, SciFiBomber, WaterDrop from objs import CoreValagaClas, SciFiBomber, WaterDrop
from common.consts import AU, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH from common.consts import AU, SECONDS_PER_DAY, SECONDS_PER_WEEK, SECONDS_PER_MONTH
from sim_scenes.func import ursina_run, camera_look_at from sim_scenes.func import ursina_run, camera_look_at, create_main_entity, two_bodies_colliding
from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.entities.body_timer import TimeData
from simulators.ursina.entities.entity_utils import create_directional_light from simulators.ursina.entities.entity_utils import create_directional_light
from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_config import UrsinaConfig
...@@ -29,18 +29,20 @@ if __name__ == '__main__': ...@@ -29,18 +29,20 @@ if __name__ == '__main__':
# OFFSETTING = 0.01265 # OFFSETTING = 0.01265
sun = Sun(name="太阳", size_scale=6e1, init_position=[0, 0, -3 * AU]).set_ignore_gravity(True) sun = Sun(name="太阳", size_scale=6e1, init_position=[0, 0, -3 * AU]).set_ignore_gravity(True)
earth_size_scale = 2.5e2 earth_size_scale = 2.5e2
resolution = 100
earth = Earth(init_position=[0, -2500000, 0], earth = Earth(init_position=[0, -2500000, 0],
texture="earth-huge.jpg", texture="earth-huge.jpg",
# rotate_angle=0, # rotate_angle=0,
rotation_speed=0, rotation_speed=0,
init_velocity=[OFFSETTING, 0, 0], size_scale=earth_size_scale).set_ignore_gravity( init_velocity=[OFFSETTING, 0, 0],
True) # 地球放大 5 倍,距离保持不变 size_scale=earth_size_scale).set_ignore_gravity(True).set_resolution(resolution) # 地球放大 5 倍,距离保持不变
# 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点) # 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点)
clouds = Earth(name="地球云层", texture="transparent_clouds.png", clouds = Earth(name="地球云层", texture="transparent_clouds.png",
# rotate_angle=0, # rotate_angle=0,
rotation_speed=0, rotation_speed=0,
init_position=[0, -2500000, 0], init_position=[0, -2500000, 0],
size_scale=earth_size_scale * 1.01, parent=earth).set_ignore_gravity(True) size_scale=earth_size_scale * 1.01,
parent=earth).set_ignore_gravity(True).set_resolution(resolution)
water_drop = WaterDrop(init_position=[AU / 300, 0, AU / 100], water_drop = WaterDrop(init_position=[AU / 300, 0, AU / 100],
texture="drops_bright.png", texture="drops_bright.png",
...@@ -56,6 +58,8 @@ if __name__ == '__main__': ...@@ -56,6 +58,8 @@ if __name__ == '__main__':
num_x = 10 num_x = 10
num_y = 10 num_y = 10
num_z = 10 num_z = 10
d = 100000
num_x = 2 num_x = 2
num_y = 2 num_y = 2
num_z = 2 num_z = 2
...@@ -104,6 +108,37 @@ if __name__ == '__main__': ...@@ -104,6 +108,37 @@ if __name__ == '__main__':
import math import math
def calc_acceleration(current_pos, to_pos, desired_velocity):
"""
Calculate the acceleration vector components (x, y, z) for an object to move from its current position to a specified position,
considering the desired velocity.
@param current_pos: Current position of the object (in a three-dimensional coordinate system)
@param to_pos: Specified position (in a three-dimensional coordinate system)
@param desired_velocity: Desired velocity of the object
@return: Acceleration vector components (x, y, z)
"""
acceleration = [0, 0, 0]
# Calculate the differences in each dimension
diff_x = to_pos[0] - current_pos[0]
diff_y = to_pos[1] - current_pos[1]
diff_z = to_pos[2] - current_pos[2]
# Calculate the total distance
total_distance = math.sqrt(diff_x ** 2 + diff_y ** 2 + diff_z ** 2)
# Calculate the time required to reach the specified position
time = total_distance / desired_velocity
# Calculate the acceleration required to reach the desired velocity in the calculated time
acceleration_magnitude = desired_velocity / time
# Calculate the acceleration in each dimension
acceleration[0] = diff_x / time
acceleration[1] = diff_y / time
acceleration[2] = diff_z / time
# Adjust the acceleration using the acceleration magnitude
acceleration[0] *= acceleration_magnitude
acceleration[1] *= acceleration_magnitude
acceleration[2] *= acceleration_magnitude
return acceleration
def calc_velocity(current_pos, to_pos, velocity_fact): def calc_velocity(current_pos, to_pos, velocity_fact):
""" """
Calculate the velocity vector components (x, y, z) for an object to move from its current position to a specified position, Calculate the velocity vector components (x, y, z) for an object to move from its current position to a specified position,
...@@ -140,13 +175,31 @@ if __name__ == '__main__': ...@@ -140,13 +175,31 @@ if __name__ == '__main__':
water_drop.planet.rotation_z = 90 water_drop.planet.rotation_z = 90
water_drop.velocity = [-WATER_SPEED, 0, 0] water_drop.velocity = [-WATER_SPEED, 0, 0]
else: else:
velocity = calc_velocity(water_drop.position, ship_list[0].position, 1) velocity = calc_velocity(water_drop.position, ship_list[0].position, 5)
# water_drop.acceleration = [-9.8e-4, 0, 0]
water_drop.velocity = velocity water_drop.velocity = velocity
# acceleration = calc_acceleration(water_drop.position, ship_list[0].position, 1e-4)
# water_drop.acceleration = acceleration # [-9.8e-4, 0, 0]
water_drop.look_at(ship_list[0], rotation_x=None, rotation_y=None, rotation_z=None)
camera_look_at(water_drop, rotation_z=0) camera_look_at(water_drop, rotation_z=0)
# camera.y += UrsinaConfig.SCALE_FACTOR * 100 # camera.y += UrsinaConfig.SCALE_FACTOR * 100
for ship in ship_list:
# 循环判断每个石头与木星是否相碰撞,如果相碰撞就爆炸
if two_bodies_colliding(water_drop, ship):
# velocity = water_drop.velocity
# acceleration = water_drop.acceleration
# 将石头隐藏、设置引力无效后,展示爆炸效果
water_drop.explode(ship, scale=1e1, fps=0.5)
# water_drop.planet.enabled = True
# water_drop.set_ignore_gravity(False)
#
# water_drop.velocity = velocity
# water_drop.acceleration = acceleration
def on_ready(): def on_ready():
UrsinaConfig.trail_type = 'line' UrsinaConfig.trail_type = 'line'
...@@ -157,11 +210,13 @@ if __name__ == '__main__': ...@@ -157,11 +210,13 @@ if __name__ == '__main__':
elif isinstance(body, SciFiBomber): elif isinstance(body, SciFiBomber):
body.planet.rotation_x = -90 body.planet.rotation_x = -90
water_drop.planet.rotation_z = 90 water_drop.planet.main_entity.rotation_z = 90
water_drop.init_position = (0, 0, 0) water_drop.init_position = (0, 0, 2000)
water_drop.init_velocity = [0, 0, 0] water_drop.init_velocity = [0, 0, 0]
create_main_entity(water_drop, rotation_y=90)
# 订阅事件后,上面2个函数功能才会起作用 # 订阅事件后,上面2个函数功能才会起作用
# 运行前会触发 on_ready # 运行前会触发 on_ready
......
...@@ -93,7 +93,7 @@ class UrsinaSimulator(Simulator): ...@@ -93,7 +93,7 @@ class UrsinaSimulator(Simulator):
return body.planet.enabled return body.planet.enabled
# Explosion animation # Explosion animation
def body_explode(target=None): def body_explode(target=None, scale=1, fps=6):
# from panda3d.core import GeomUtils # from panda3d.core import GeomUtils
if body.planet.enabled: if body.planet.enabled:
# TODO:下面代码保留,由于运行太快导致两个天体不是在表面碰撞,这样就要进行计算,希望在表面爆炸,但是需要耗费CPU资源,暂时注释 # TODO:下面代码保留,由于运行太快导致两个天体不是在表面碰撞,这样就要进行计算,希望在表面爆炸,但是需要耗费CPU资源,暂时注释
...@@ -107,8 +107,10 @@ class UrsinaSimulator(Simulator): ...@@ -107,8 +107,10 @@ class UrsinaSimulator(Simulator):
# explode_pos = body.planet.position # explode_pos = body.planet.position
# else: # else:
# print("explode_pos", explode_pos) # print("explode_pos", explode_pos)
if hasattr(body.planet, "main_entity"):
explode_pos = body.planet.position explode_pos = body.planet.main_entity.position
else:
explode_pos = body.planet.position
# 如果爆炸,则静止不动(停止并忽略引力) # 如果爆炸,则静止不动(停止并忽略引力)
body.stop_and_ignore_gravity() body.stop_and_ignore_gravity()
body.planet.enabled = False body.planet.enabled = False
...@@ -117,11 +119,11 @@ class UrsinaSimulator(Simulator): ...@@ -117,11 +119,11 @@ class UrsinaSimulator(Simulator):
# 获取体积数据(开三次方) # 获取体积数据(开三次方)
volume_scale = pow(body.planet.model.get_bounds().volume, 1 / 3) volume_scale = pow(body.planet.model.get_bounds().volume, 1 / 3)
# 根据体积、大小缩放判断爆炸的量 # 根据体积、大小缩放判断爆炸的量
scale = 3 * volume_scale * body.size_scale * UrsinaConfig.SCALE_FACTOR scale = 3 * volume_scale * body.size_scale * UrsinaConfig.SCALE_FACTOR * scale
print(scale, body) print(scale, body)
explode_ani = Animation(explosion_file, explode_ani = Animation(explosion_file,
position=explode_pos, position=explode_pos,
scale=scale, fps=6, scale=scale, fps=fps,
loop=False, autoplay=True) loop=False, autoplay=True)
explode_ani.set_light_off() explode_ani.set_light_off()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册