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

Python超人-宇宙模拟器

上级 99064a26
......@@ -81,6 +81,28 @@ def set_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):
"""
让摄像机看向指定天体
......
......@@ -11,7 +11,7 @@
from bodies import Sun, Earth, Moon
from objs import CoreValagaClas, SciFiBomber, WaterDrop
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.entity_utils import create_directional_light
from simulators.ursina.ursina_config import UrsinaConfig
......@@ -29,18 +29,20 @@ if __name__ == '__main__':
# OFFSETTING = 0.01265
sun = Sun(name="太阳", size_scale=6e1, init_position=[0, 0, -3 * AU]).set_ignore_gravity(True)
earth_size_scale = 2.5e2
resolution = 100
earth = Earth(init_position=[0, -2500000, 0],
texture="earth-huge.jpg",
# rotate_angle=0,
rotation_speed=0,
init_velocity=[OFFSETTING, 0, 0], size_scale=earth_size_scale).set_ignore_gravity(
True) # 地球放大 5 倍,距离保持不变
init_velocity=[OFFSETTING, 0, 0],
size_scale=earth_size_scale).set_ignore_gravity(True).set_resolution(resolution) # 地球放大 5 倍,距离保持不变
# 创建云层(texture纹理图使用了透明云层的图片,云层的 size_scale 要稍微比地球大一点)
clouds = Earth(name="地球云层", texture="transparent_clouds.png",
# rotate_angle=0,
rotation_speed=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],
texture="drops_bright.png",
......@@ -56,6 +58,8 @@ if __name__ == '__main__':
num_x = 10
num_y = 10
num_z = 10
d = 100000
num_x = 2
num_y = 2
num_z = 2
......@@ -104,6 +108,37 @@ if __name__ == '__main__':
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):
"""
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__':
water_drop.planet.rotation_z = 90
water_drop.velocity = [-WATER_SPEED, 0, 0]
else:
velocity = calc_velocity(water_drop.position, ship_list[0].position, 1)
# water_drop.acceleration = [-9.8e-4, 0, 0]
velocity = calc_velocity(water_drop.position, ship_list[0].position, 5)
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.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():
UrsinaConfig.trail_type = 'line'
......@@ -157,11 +210,13 @@ if __name__ == '__main__':
elif isinstance(body, SciFiBomber):
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]
create_main_entity(water_drop, rotation_y=90)
# 订阅事件后,上面2个函数功能才会起作用
# 运行前会触发 on_ready
......
......@@ -93,7 +93,7 @@ class UrsinaSimulator(Simulator):
return body.planet.enabled
# Explosion animation
def body_explode(target=None):
def body_explode(target=None, scale=1, fps=6):
# from panda3d.core import GeomUtils
if body.planet.enabled:
# TODO:下面代码保留,由于运行太快导致两个天体不是在表面碰撞,这样就要进行计算,希望在表面爆炸,但是需要耗费CPU资源,暂时注释
......@@ -107,7 +107,9 @@ class UrsinaSimulator(Simulator):
# explode_pos = body.planet.position
# else:
# print("explode_pos", explode_pos)
if hasattr(body.planet, "main_entity"):
explode_pos = body.planet.main_entity.position
else:
explode_pos = body.planet.position
# 如果爆炸,则静止不动(停止并忽略引力)
body.stop_and_ignore_gravity()
......@@ -117,11 +119,11 @@ class UrsinaSimulator(Simulator):
# 获取体积数据(开三次方)
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)
explode_ani = Animation(explosion_file,
position=explode_pos,
scale=scale, fps=6,
scale=scale, fps=fps,
loop=False, autoplay=True)
explode_ani.set_light_off()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册