DR rs 0.3.6 [build rs skip] (我很清楚这玩意过不了(逃

This commit is contained in:
shenjack 2024-05-23 23:52:07 +08:00
parent 297aaf236e
commit 30b4595df3
Signed by: shenjack
GPG Key ID: 7B1134A979775551
5 changed files with 161 additions and 142 deletions

View File

@ -162,6 +162,16 @@ if TYPE_CHECKING:
def flip_y(self) -> bool: def flip_y(self) -> bool:
... ...
def get_part_box_by_type(
self, part_type: SR1PartType_rs
) -> Tuple[Tuple[float, float], Tuple[float, float]]:
"""
当你同时已知一个部件的数据和类型的时候
为啥不直接获取呢
: 0.3.6
"""
...
class SaveStatus_rs: # NOQA class SaveStatus_rs: # NOQA
def __init__(self, save_default: Optional[bool] = False) -> None: def __init__(self, save_default: Optional[bool] = False) -> None:
... ...
@ -246,7 +256,7 @@ if TYPE_CHECKING:
... ...
def get_part_box( def get_part_box(
self, part_id: int self, part_id: IdType
) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]:
"""获取所有零件的盒子""" """获取所有零件的盒子"""
@ -273,6 +283,14 @@ if TYPE_CHECKING:
"""获取所有未连接的零件""" """获取所有未连接的零件"""
... ...
def find_part_by_id(self, part_id: IdType) -> List[SR1PartData_rs]:
"""
通过 id 获取零件
当然, 支持重叠 ID
: 0.3.6
"""
...
class Console_rs: # NOQA class Console_rs: # NOQA
def __init__(self) -> None: def __init__(self) -> None:
... ...

View File

@ -146,7 +146,7 @@ dependencies = [
[[package]] [[package]]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.5" version = "0.3.6"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dict_derive", "dict_derive",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.5" version = "0.3.6"
edition = "2021" edition = "2021"
license-file = '../../LICENSE' license-file = '../../LICENSE'
authors = ["shenjackyuanjie <3695888@qq.com>"] authors = ["shenjackyuanjie <3695888@qq.com>"]

View File

@ -204,6 +204,18 @@ impl PySR1PartData {
fn get_flip_y(&self) -> bool { fn get_flip_y(&self) -> bool {
self.data.flip_y self.data.flip_y
} }
fn get_part_box_by_type(&self, part_type: PySR1PartType) -> ((f64, f64), (f64, f64)) {
let radius = self.data.angle;
let ((x1, y1), (x2, y2)) = part_type.data.get_box();
let mut p1 = Point2D::new(x1, y1);
let mut p2 = Point2D::new(x2, y2);
p1.rotate_radius_mut(radius);
p2.rotate_radius_mut(radius);
p1.add_mut(self.data.x * 2.0, self.data.y * 2.0);
p2.add_mut(self.data.x * 2.0, self.data.y * 2.0);
((p1.x, p1.y), (p2.x, p2.y))
}
} }
#[pyclass] #[pyclass]
@ -384,6 +396,9 @@ impl PySR1Ship {
parts parts
} }
/// 待会直接加一个在 SR1 PartData上获取的API得了现在这样太费劲了
///
/// 加好了
fn get_part_box(&self, part_id: IdType) -> Option<((f64, f64), (f64, f64))> { fn get_part_box(&self, part_id: IdType) -> Option<((f64, f64), (f64, f64))> {
let part_data = self.ship.parts.iter().find(|&x| x.id == part_id); let part_data = self.ship.parts.iter().find(|&x| x.id == part_id);
if let Some(part_data) = part_data { if let Some(part_data) = part_data {
@ -404,6 +419,23 @@ impl PySR1Ship {
None None
} }
/// 通过 part_id 获取 part_data
///
/// 当然, 支持重叠 ID
fn find_part_by_id(&self, part_id: IdType) -> Vec<SR1PartData> {
// 先搜链接到的部件
// 这里的代码是 GitHub Copilot 帮我优化的
// 赞美 GitHub Copilot !()
let unconnected = self.ship.disconnected.as_ref().map_or(vec![], |disconnected| {
disconnected.iter()
.flat_map(|(group, _)| group.iter())
.filter(|part| part.id == part_id)
.collect()
});
// 然后通过一个 chain 直接把他链接到这边
self.ship.parts.iter().filter(|x| x.id == part_id).chain(unconnected).cloned().collect()
}
fn save(&self, file_path: String, save_status: Option<PySaveStatus>) -> PyResult<()> { fn save(&self, file_path: String, save_status: Option<PySaveStatus>) -> PyResult<()> {
println!("{:?}", save_status); println!("{:?}", save_status);
self.ship.save(file_path, &save_status.unwrap_or_default().status).unwrap(); self.ship.save(file_path, &save_status.unwrap_or_default().status).unwrap();

View File

@ -189,59 +189,49 @@ class SR1ShipRender(BaseScreen):
self.logger.error(traceback.format_exc(), tag="load_xml") self.logger.error(traceback.format_exc(), tag="load_xml")
return False return False
def draw_parts( def part_render_init(
self, self,
cache: List[Tuple[SR1PartType_rs, SR1PartData_rs]], part_data: SR1PartData_rs,
count: int, part_type: SR1PartType_rs,
each_count: int, part_group: Group,
draw_part_box: bool, line_group: Group,
draw_alpha: int, batch: Batch,
): ) -> Tuple[Sprite, List[Line]]:
# 渲染传入的parts """
part_group = Group(2, parent=self.part_group) 还是重写一下渲染逻辑
line_box_group = Group(6, parent=self.part_group) 把渲染单个部件的逻辑提取出来放到这里
for p_id, parts in cache: """
p_id: int texture = self.textures.get_texture(part_type.sprite)
parts: List[Tuple[SR1PartType_rs, SR1PartData_rs]]
batch = []
for p_type, p_data in parts:
sprite_name = self.part_list_rs.get_part_type(p_data.part_type_id).sprite
part_sprite = Sprite( part_sprite = Sprite(
img=self.textures.get_texture(sprite_name), img=texture,
x=p_data.x * 60, x=part_data.x * 60,
y=p_data.y * 60, y=part_data.y * 60,
z=random.random(), z=random.random(),
batch=self.main_batch, batch=batch,
group=part_group, group=part_group,
) )
part_sprite.opacity = draw_alpha part_sprite.rotation = part_data.angle_r
part_sprite.rotation = p_data.angle_r part_sprite.scale_x = -1 if part_data.flip_x else 1
part_sprite.scale_x = -1 if p_data.flip_x else 1 part_sprite.scale_y = -1 if part_data.flip_y else 1
part_sprite.scale_y = -1 if p_data.flip_y else 1 line_colors = (
random.randrange(0, 255),
batch.append(part_sprite) random.randrange(0, 255),
part_box = self.rust_ship.get_part_box(p_id) random.randrange(0, 255),
if part_box and draw_part_box: 200,
# 线框 )
part_line_box = [] part_line_box = []
width = 4 width = 4
color = ( (x, y), (x2, y2) = part_data.get_part_box_by_type(part_type)
random.randrange(0, 255),
random.randrange(0, 255),
random.randrange(0, 255),
random.randrange(100, 200),
)
(x, y), (x2, y2) = part_box
part_line_box.append( part_line_box.append(
Line( Line(
x=x * 30, x=x * 30,
y=y * 30, y=y * 30,
x2=x * 30, x2=x * 30,
y2=y2 * 30, y2=y2 * 30,
batch=self.main_batch, batch=batch,
width=width, width=width,
color=color, color=line_colors,
group=line_box_group, group=line_group,
) )
) )
part_line_box.append( part_line_box.append(
@ -250,10 +240,10 @@ class SR1ShipRender(BaseScreen):
y=y2 * 30, y=y2 * 30,
x2=x2 * 30, x2=x2 * 30,
y2=y2 * 30, y2=y2 * 30,
batch=self.main_batch, batch=batch,
width=width, width=width,
color=color, color=line_colors,
group=line_box_group, group=line_group,
) )
) )
part_line_box.append( part_line_box.append(
@ -262,10 +252,10 @@ class SR1ShipRender(BaseScreen):
y=y2 * 30, y=y2 * 30,
x2=x2 * 30, x2=x2 * 30,
y2=y * 30, y2=y * 30,
batch=self.main_batch, batch=batch,
width=width, width=width,
color=color, color=line_colors,
group=line_box_group, group=line_group,
) )
) )
part_line_box.append( part_line_box.append(
@ -274,22 +264,15 @@ class SR1ShipRender(BaseScreen):
y=y * 30, y=y * 30,
x2=x * 30, x2=x * 30,
y2=y * 30, y2=y * 30,
batch=self.main_batch, batch=batch,
width=width, width=width,
color=color, color=line_colors,
group=line_box_group, group=line_group,
) )
) )
# 直接用循环得了 return part_sprite, part_line_box
self.part_line_box[p_id] = part_line_box
self.parts_sprite[p_id] = batch
count += 1
if count >= each_count:
count = 0
return count
return count
def gen_sprite(self, each_count: int = 100) -> Generator: def sprite_batch(self, draw_batch: int = 100) -> Generator:
""" """
生成 sprite 生成 sprite
通过生成器减少一次性渲染的压力 通过生成器减少一次性渲染的压力
@ -300,51 +283,37 @@ class SR1ShipRender(BaseScreen):
self.status.draw_done = False self.status.draw_done = False
# rust 渲染 # rust 渲染
if DR_mod_runtime.use_DR_rust: if DR_mod_runtime.use_DR_rust:
# 渲染所有未连接零件 # 渲染连接的部件
all_disconnected_groups = self.rust_ship.disconnected_parts() part_group = Group(6, parent=self.part_group)
for parts_groups, connections in all_disconnected_groups: line_group = Group(5, parent=self.part_group)
draw_part_box = False
cache = []
for p_type, p_data in parts_groups:
cache.append((p_data.id, parts_groups))
count = self.draw_parts(cache, count, each_count, draw_part_box, 128)
if count >= each_count:
count = 0
yield
# 渲染所有已连接零件 # 渲染未连接的部件
draw_part_box = False
cache = self.rust_ship.as_dict()
count = self.draw_parts(cache.items(), count, each_count, draw_part_box, 255)
if count >= each_count:
count = 0
yield
connect_line_group = Group(7, parent=self.part_group) connect_line_group = Group(7, parent=self.part_group)
for connect in self.rust_ship.connections().get_raw_data(): for connect in self.rust_ship.connections().get_raw_data():
# 连接线 # 连接线
parent_part_data = cache[connect[2]][0][1] # parent_part_data = cache[connect[2]][0][1]
child_part_data = cache[connect[3]][0][1] # child_part_data = cache[connect[3]][0][1]
color = ( # color = (
random.randrange(100, 255), # random.randrange(100, 255),
random.randrange(0, 255), # random.randrange(0, 255),
random.randrange(0, 255), # random.randrange(0, 255),
255, # 255,
) # )
self.part_line_list.append( # self.part_line_list.append(
Line( # Line(
x=parent_part_data.x * 60, # x=parent_part_data.x * 60,
y=parent_part_data.y * 60, # y=parent_part_data.y * 60,
x2=child_part_data.x * 60, # x2=child_part_data.x * 60,
y2=child_part_data.y * 60, # y2=child_part_data.y * 60,
batch=self.main_batch, # batch=self.main_batch,
group=connect_line_group, # group=connect_line_group,
width=1, # width=1,
color=color, # color=color,
) # )
) # )
count += 1 count += 1
if count >= each_count * 3: if count >= draw_batch * 3:
count = 0 count = 0
yield count yield count
@ -364,7 +333,7 @@ class SR1ShipRender(BaseScreen):
self.group_camera.reset() self.group_camera.reset()
# 调用生成器 减少卡顿 # 调用生成器 减少卡顿
try: try:
self.gen_draw = self.gen_sprite() self.gen_draw = self.sprite_batch()
if not self.status.draw_done: if not self.status.draw_done:
next(self.gen_draw) next(self.gen_draw)
except (GeneratorExit, StopIteration): except (GeneratorExit, StopIteration):