diff --git a/mods/dr_game/Difficult_Rocket_rs/__init__.py b/mods/dr_game/Difficult_Rocket_rs/__init__.py index 8b92254..27d27f3 100644 --- a/mods/dr_game/Difficult_Rocket_rs/__init__.py +++ b/mods/dr_game/Difficult_Rocket_rs/__init__.py @@ -162,6 +162,16 @@ if TYPE_CHECKING: 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 def __init__(self, save_default: Optional[bool] = False) -> None: ... @@ -246,7 +256,7 @@ if TYPE_CHECKING: ... def get_part_box( - self, part_id: int + self, part_id: IdType ) -> 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 def __init__(self) -> None: ... diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock index ab5c7d9..8034b42 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock @@ -146,7 +146,7 @@ dependencies = [ [[package]] name = "difficult_rocket_rs" -version = "0.3.5" +version = "0.3.6" dependencies = [ "anyhow", "dict_derive", diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml index 2793b0e..7040e7c 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "difficult_rocket_rs" -version = "0.3.5" +version = "0.3.6" edition = "2021" license-file = '../../LICENSE' authors = ["shenjackyuanjie <3695888@qq.com>"] diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs index 516f2b1..f1ad562 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python/data.rs @@ -204,6 +204,18 @@ impl PySR1PartData { fn get_flip_y(&self) -> bool { 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] @@ -384,6 +396,9 @@ impl PySR1Ship { parts } + /// 待会直接加一个在 SR1 PartData上获取的API得了,现在这样太费劲了 + /// + /// 加好了 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); if let Some(part_data) = part_data { @@ -404,6 +419,23 @@ impl PySR1Ship { None } + /// 通过 part_id 获取 part_data + /// + /// 当然, 支持重叠 ID + fn find_part_by_id(&self, part_id: IdType) -> Vec { + // 先搜链接到的部件 + // 这里的代码是 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) -> PyResult<()> { println!("{:?}", save_status); self.ship.save(file_path, &save_status.unwrap_or_default().status).unwrap(); diff --git a/mods/dr_game/sr1_ship.py b/mods/dr_game/sr1_ship.py index a3233d8..fd43ae5 100644 --- a/mods/dr_game/sr1_ship.py +++ b/mods/dr_game/sr1_ship.py @@ -189,107 +189,90 @@ class SR1ShipRender(BaseScreen): self.logger.error(traceback.format_exc(), tag="load_xml") return False - def draw_parts( + def part_render_init( self, - cache: List[Tuple[SR1PartType_rs, SR1PartData_rs]], - count: int, - each_count: int, - draw_part_box: bool, - draw_alpha: int, - ): - # 渲染传入的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 - 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( - img=self.textures.get_texture(sprite_name), - x=p_data.x * 60, - y=p_data.y * 60, - z=random.random(), - batch=self.main_batch, - group=part_group, - ) - part_sprite.opacity = draw_alpha - part_sprite.rotation = p_data.angle_r - part_sprite.scale_x = -1 if p_data.flip_x else 1 - part_sprite.scale_y = -1 if p_data.flip_y else 1 + part_data: SR1PartData_rs, + part_type: SR1PartType_rs, + part_group: Group, + line_group: Group, + batch: Batch, + ) -> Tuple[Sprite, List[Line]]: + """ + 还是重写一下渲染逻辑 + 把渲染单个部件的逻辑提取出来放到这里 + """ + texture = self.textures.get_texture(part_type.sprite) + part_sprite = Sprite( + img=texture, + x=part_data.x * 60, + y=part_data.y * 60, + z=random.random(), + batch=batch, + group=part_group, + ) + part_sprite.rotation = part_data.angle_r + part_sprite.scale_x = -1 if part_data.flip_x else 1 + part_sprite.scale_y = -1 if part_data.flip_y else 1 + line_colors = ( + random.randrange(0, 255), + random.randrange(0, 255), + random.randrange(0, 255), + 200, + ) + part_line_box = [] + width = 4 + (x, y), (x2, y2) = part_data.get_part_box_by_type(part_type) + part_line_box.append( + Line( + x=x * 30, + y=y * 30, + x2=x * 30, + y2=y2 * 30, + batch=batch, + width=width, + color=line_colors, + group=line_group, + ) + ) + part_line_box.append( + Line( + x=x * 30, + y=y2 * 30, + x2=x2 * 30, + y2=y2 * 30, + batch=batch, + width=width, + color=line_colors, + group=line_group, + ) + ) + part_line_box.append( + Line( + x=x2 * 30, + y=y2 * 30, + x2=x2 * 30, + y2=y * 30, + batch=batch, + width=width, + color=line_colors, + group=line_group, + ) + ) + part_line_box.append( + Line( + x=x2 * 30, + y=y * 30, + x2=x * 30, + y2=y * 30, + batch=batch, + width=width, + color=line_colors, + group=line_group, + ) + ) + return part_sprite, part_line_box - batch.append(part_sprite) - part_box = self.rust_ship.get_part_box(p_id) - if part_box and draw_part_box: - # 线框 - part_line_box = [] - width = 4 - color = ( - 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( - Line( - x=x * 30, - y=y * 30, - x2=x * 30, - y2=y2 * 30, - batch=self.main_batch, - width=width, - color=color, - group=line_box_group, - ) - ) - part_line_box.append( - Line( - x=x * 30, - y=y2 * 30, - x2=x2 * 30, - y2=y2 * 30, - batch=self.main_batch, - width=width, - color=color, - group=line_box_group, - ) - ) - part_line_box.append( - Line( - x=x2 * 30, - y=y2 * 30, - x2=x2 * 30, - y2=y * 30, - batch=self.main_batch, - width=width, - color=color, - group=line_box_group, - ) - ) - part_line_box.append( - Line( - x=x2 * 30, - y=y * 30, - x2=x * 30, - y2=y * 30, - batch=self.main_batch, - width=width, - color=color, - group=line_box_group, - ) - ) - # 直接用循环得了 - 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 通过生成器减少一次性渲染的压力 @@ -300,51 +283,37 @@ class SR1ShipRender(BaseScreen): self.status.draw_done = False # rust 渲染 if DR_mod_runtime.use_DR_rust: - # 渲染所有未连接零件 - all_disconnected_groups = self.rust_ship.disconnected_parts() - for parts_groups, connections in all_disconnected_groups: - 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 + # 渲染连接的部件 + part_group = Group(6, parent=self.part_group) + line_group = Group(5, parent=self.part_group) - # 渲染所有已连接零件 - 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) for connect in self.rust_ship.connections().get_raw_data(): # 连接线 - parent_part_data = cache[connect[2]][0][1] - child_part_data = cache[connect[3]][0][1] - color = ( - random.randrange(100, 255), - random.randrange(0, 255), - random.randrange(0, 255), - 255, - ) - self.part_line_list.append( - Line( - x=parent_part_data.x * 60, - y=parent_part_data.y * 60, - x2=child_part_data.x * 60, - y2=child_part_data.y * 60, - batch=self.main_batch, - group=connect_line_group, - width=1, - color=color, - ) - ) + # parent_part_data = cache[connect[2]][0][1] + # child_part_data = cache[connect[3]][0][1] + # color = ( + # random.randrange(100, 255), + # random.randrange(0, 255), + # random.randrange(0, 255), + # 255, + # ) + # self.part_line_list.append( + # Line( + # x=parent_part_data.x * 60, + # y=parent_part_data.y * 60, + # x2=child_part_data.x * 60, + # y2=child_part_data.y * 60, + # batch=self.main_batch, + # group=connect_line_group, + # width=1, + # color=color, + # ) + # ) count += 1 - if count >= each_count * 3: + if count >= draw_batch * 3: count = 0 yield count @@ -364,7 +333,7 @@ class SR1ShipRender(BaseScreen): self.group_camera.reset() # 调用生成器 减少卡顿 try: - self.gen_draw = self.gen_sprite() + self.gen_draw = self.sprite_batch() if not self.status.draw_done: next(self.gen_draw) except (GeneratorExit, StopIteration):