From 8b490aac17c9acc6e5a2afd1acda840e99592983 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 22 Jun 2023 14:52:10 +0800 Subject: [PATCH 1/9] update docs --- README.md | 4 ++-- docs/README-en.md | 4 ++-- docs/src/change_log/dr_sdk.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c13bef1..905cfae 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ [关于版本号的说明](./docs/src/version.md) -[![Generic badge](https://img.shields.io/badge/Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) +[![Generic badge](https://img.shields.io/badge/Release-0.8.4.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) [![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.4.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) -[![Generic badge](https://img.shields.io/badge/Devloping-0.8.4-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) +[![Generic badge](https://img.shields.io/badge/Devloping-0.8.5-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) [![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark) diff --git a/docs/README-en.md b/docs/README-en.md index deed982..0ec4c85 100644 --- a/docs/README-en.md +++ b/docs/README-en.md @@ -19,9 +19,9 @@ [About Versions](src/version.md) -[![Generic badge](https://img.shields.io/badge/Release-0.8.3.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) +[![Generic badge](https://img.shields.io/badge/Release-0.8.4.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) [![Generic badge](https://img.shields.io/badge/Pre_Release-0.8.4.0-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) -[![Generic badge](https://img.shields.io/badge/Devloping-0.8.4-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) +[![Generic badge](https://img.shields.io/badge/Devloping-0.8.5-blue.svg)](https://github.com/shenjackyuanjie/Difficult-Rocket/releases) [![language badge](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark)](https://stats.deeptrain.net/repo/shenjackyuanjie/Difficult-Rocket?theme=dark) diff --git a/docs/src/change_log/dr_sdk.md b/docs/src/change_log/dr_sdk.md index 5620ab7..34e437a 100644 --- a/docs/src/change_log/dr_sdk.md +++ b/docs/src/change_log/dr_sdk.md @@ -2,7 +2,7 @@ # DR SDK 更新日志 - 最新版本号 - - DR sdk: 0.8.3.0 + - DR sdk: 0.8.4.0 ## DR sdk 0.8.4.0 From c55eaffa5dd0606877d46e189aff921f4e075caa Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 22 Jun 2023 20:13:26 +0800 Subject: [PATCH 2/9] ready to sync pyglet --- README.md | 2 +- docs/README-en.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 905cfae..8acf609 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ 996.icu [![Generic badge](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/) [![Generic badge](https://img.shields.io/badge/编写于_Python_版本-3.8.10-blue.svg)](https://Python.org) -[![Generic badge](https://img.shields.io/badge/编写于_Pyglet_版本-2.0.7-blue.svg)](https://pyglet.org) +[![Generic badge](https://img.shields.io/badge/编写于_Pyglet_版本-2.0.8-blue.svg)](https://pyglet.org) [![Generic badge](https://img.shields.io/badge/Python-_3.8_|_3.9_|_3.10_|_3.11_-blue.svg)](https://Python.org) ## 版本 diff --git a/docs/README-en.md b/docs/README-en.md index 0ec4c85..e6bf020 100644 --- a/docs/README-en.md +++ b/docs/README-en.md @@ -12,7 +12,7 @@ 996.icu [![Generic badge](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/) [![Generic badge](https://img.shields.io/badge/Write_with_Python-3.8.10-blue.svg)](https://Python.org) -[![Generic badge](https://img.shields.io/badge/Write_with_Pyglet-2.0.5-blue.svg)](https://pyglet.org) +[![Generic badge](https://img.shields.io/badge/Write_with_Pyglet-2.0.8-blue.svg)](https://pyglet.org) [![Generic badge](https://img.shields.io/badge/Python-_3.8_|_3.9_|_3.10_|_3.11_-blue.svg)](https://Python.org) ## Version From 1b2936070104360c7d490c1d4d2875831393c783 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 22 Jun 2023 20:13:59 +0800 Subject: [PATCH 3/9] sync last commit before release --- libs/pyglet/input/linux/evdev.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libs/pyglet/input/linux/evdev.py b/libs/pyglet/input/linux/evdev.py index 9b53b1f..5c00fee 100644 --- a/libs/pyglet/input/linux/evdev.py +++ b/libs/pyglet/input/linux/evdev.py @@ -4,6 +4,7 @@ import fcntl import ctypes import warnings +from os import readv from ctypes import c_uint16 as _u16 from ctypes import c_int16 as _s16 from ctypes import c_uint32 as _u32 @@ -306,7 +307,6 @@ class EvdevDevice(XlibSelectDevice, Device): self._filename = filename fileno = os.open(filename, os.O_RDONLY) - # event_version = EVIOCGVERSION(fileno).value self._id = EVIOCGID(fileno) self.id_bustype = self._id.bustype @@ -357,6 +357,9 @@ class EvdevDevice(XlibSelectDevice, Device): self.controls.sort(key=lambda c: c._event_code) os.close(fileno) + self._event_size = ctypes.sizeof(InputEvent) + self._event_buffer = (InputEvent * 64)() + super().__init__(display, name) def get_guid(self): @@ -405,17 +408,16 @@ class EvdevDevice(XlibSelectDevice, Device): return try: - events = (InputEvent * 64)() - bytes_read = os.readv(self._fileno, events) + bytes_read = readv(self._fileno, self._event_buffer) except OSError: self.close() return - n_events = bytes_read // ctypes.sizeof(InputEvent) - for event in events[:n_events]: + n_events = bytes_read // self._event_size + + for event in self._event_buffer[:n_events]: try: - control = self.control_map[(event.type, event.code)] - control.value = event.value + self.control_map[(event.type, event.code)].value = event.value except KeyError: pass @@ -651,5 +653,4 @@ def _create_controller(device): def get_controllers(display=None): return [controller for controller in - [_create_controller(device) for device in get_devices(display)] - if controller is not None] + [_create_controller(device) for device in get_devices(display)] if controller] From f1abeb430e60d2adb759e5f4766309ed6b011866 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 22 Jun 2023 20:16:24 +0800 Subject: [PATCH 4/9] bump version of pyglet --- configs/main.toml | 4 ++-- libs/pyglet/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/main.toml b/configs/main.toml index 3e89e77..3490821 100644 --- a/configs/main.toml +++ b/configs/main.toml @@ -7,8 +7,8 @@ fonts_folder = "libs/fonts" [window] style = "None" -width = 1041 -height = 1050 +width = 1918 +height = 2088 visible = true gui_scale = 1 caption = "Difficult Rocket v{DR_version}" diff --git a/libs/pyglet/__init__.py b/libs/pyglet/__init__.py index 6a71f88..7f743b1 100644 --- a/libs/pyglet/__init__.py +++ b/libs/pyglet/__init__.py @@ -9,7 +9,7 @@ import sys from typing import TYPE_CHECKING #: The release version -version = '2.0.7' +version = '2.0.8' __version__ = version MIN_PYTHON_VERSION = 3, 8 From 43966ec573494fe08a43955f06bbd25f09f5b5c7 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Fri, 23 Jun 2023 00:21:59 +0800 Subject: [PATCH 5/9] sync pyglet update --- libs/pyglet/media/codecs/base.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/libs/pyglet/media/codecs/base.py b/libs/pyglet/media/codecs/base.py index d65b23a..652a8a8 100644 --- a/libs/pyglet/media/codecs/base.py +++ b/libs/pyglet/media/codecs/base.py @@ -135,17 +135,6 @@ class AudioData: self.duration -= num_bytes / audio_format.bytes_per_second self.timestamp += num_bytes / audio_format.bytes_per_second - def get_string_data(self): - """Return data as a bytestring. - - Returns: - bytes: Data as a (byte)string. - """ - if self.data is None: - return b'' - - return memoryview(self.data).tobytes()[:self.length] - class SourceInfo: """Source metadata information. @@ -409,7 +398,7 @@ class StaticSource(Source): audio_data = source.get_audio_data(buffer_size) if not audio_data: break - data.write(audio_data.get_string_data()) + data.write(audio_data.data) self._data = data.getvalue() self._duration = len(self._data) / self.audio_format.bytes_per_second From 85c2e4b21c3432c3b96302f27bd7196a16e8eb1b Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Fri, 23 Jun 2023 01:12:33 +0800 Subject: [PATCH 6/9] rua --- mods/dr_game/Difficult_Rocket_rs/__init__.py | 18 ++++- .../Difficult_Rocket_rs/src/src/lib.rs | 3 +- .../Difficult_Rocket_rs/src/src/python.rs | 66 +++++++++++++++---- .../Difficult_Rocket_rs/src/src/simulator.rs | 32 ++++++++- .../Difficult_Rocket_rs/src/src/sr1_data.rs | 11 ++++ .../Difficult_Rocket_rs/src/src/translate.rs | 16 ----- .../Difficult_Rocket_rs/src/src/types.rs | 35 +++++++--- mods/dr_game/__init__.py | 2 +- mods/dr_game/lang/zh-CN.toml | 1 - mods/dr_game/sr1_ship.py | 8 +++ 10 files changed, 148 insertions(+), 44 deletions(-) delete mode 100644 mods/dr_game/Difficult_Rocket_rs/src/src/translate.rs diff --git a/mods/dr_game/Difficult_Rocket_rs/__init__.py b/mods/dr_game/Difficult_Rocket_rs/__init__.py index ab367f7..ee6ba0a 100644 --- a/mods/dr_game/Difficult_Rocket_rs/__init__.py +++ b/mods/dr_game/Difficult_Rocket_rs/__init__.py @@ -6,7 +6,7 @@ from .lib import * -from typing import TYPE_CHECKING, Dict, Tuple, Optional +from typing import TYPE_CHECKING, Dict, Tuple, Optional, List, Tuple if TYPE_CHECKING: @@ -107,6 +107,20 @@ if TYPE_CHECKING: def get_part_type(self, name: str) -> SR1PartType_rs: ... + class SR1PartData_rs: + """ 用于从 rust 中读取 SR1PartData (其实好像也没啥用哈) + """ + @property + def part_type_id(self) -> str: ... + @property + def pos(self) -> Tuple[float, float]: ... + @property + def angle(self) -> float: ... + @property + def flip_x(self) -> bool: ... + @property + def flip_y(self) -> bool: ... + class SR1Ship_rs: """ 用于高效且省内存的读取 SR1Ship """ def __init__(self, file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip'): ... @@ -122,6 +136,8 @@ if TYPE_CHECKING: def img_pos(self) -> Tuple[int, int, int, int]: ... """ -x -y +x +y 左下右上 """ def get_part_box(self, part_id: int) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ... + def as_dict(self) -> Dict[int, List[Tuple[SR1PartType_rs, SR1PartData]]]: + """用于返回一个包含所有已连接零件的字典""" class Console_rs: def __init__(self) -> None: ... diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs index 25031ab..0d831d3 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs @@ -12,7 +12,6 @@ mod python; mod render; mod simulator; mod sr1_data; -mod translate; mod types; use pyo3::prelude::*; @@ -27,7 +26,7 @@ enum LoadState { } #[pyfunction] -fn get_version_str() -> String { "0.2.11.0".to_string() } +fn get_version_str() -> String { "0.2.12.0".to_string() } #[pyfunction] fn test_call(py_obj: &PyAny) -> PyResult { diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs index 8e88f87..b13307e 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs @@ -74,7 +74,7 @@ pub mod data { } fn get_part_type(&self, name: String) -> Option { - let part_type = self.data.get_part_type(name.clone()); + let part_type = self.data.get_part_type(&name); if let Some(part_type) = part_type { Some(PySR1PartType::new(part_type.clone())) } else { @@ -89,6 +89,28 @@ pub mod data { pub data: SR1PartData, } + impl PySR1PartData { + pub fn new(data: SR1PartData) -> Self { Self { data } } + } + + #[pymethods] + impl PySR1PartData { + #[getter] + fn get_part_type_id(&self) -> String { self.data.part_type_id.clone() } + + #[getter] + fn get_pos(&self) -> (f64, f64) { (self.data.x, self.data.y) } + + #[getter] + fn get_angle(&self) -> f64 { self.data.angle } + + #[getter] + fn get_flip_x(&self) -> bool { self.data.flip_x } + + #[getter] + fn get_flip_y(&self) -> bool { self.data.flip_y } + } + #[pyclass] #[pyo3(name = "SR1Ship_rs")] #[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")] @@ -101,8 +123,9 @@ pub mod data { impl PySR1Ship { #[new] fn new(file_path: String, part_list: String, ship_name: String) -> Self { - let ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap(); + let mut ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap(); let part_list = SR1PartList::from_file(part_list).unwrap(); + ship.parse_part_list_to_part(&part_list); // Self { ship, part_list } } @@ -132,14 +155,28 @@ pub mod data { #[getter] fn get_touch_ground(&self) -> bool { self.ship.touch_ground.to_owned() } - fn iter_parts(&self) -> HashMap { - let mut parts = HashMap::new(); + #[getter] + fn get_mass(&self) -> f64 { + let mut mass = 0_f64; for part_data in self.ship.parts.iter() { - let part_type = self.part_list.get_part_type(part_data.part_type_id.clone()).unwrap(); - parts.insert( - part_data.id, - (PySR1PartType::new(part_type), PySR1PartData { data: part_data.clone() }), - ); + let part_type = self.part_list.get_part_type(&part_data.part_type_id).unwrap(); + mass += part_type.mass + } + mass + } + + fn as_dict(&self) -> HashMap> { + let mut parts: HashMap> = HashMap::new(); + for part_data in self.ship.parts.iter() { + if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) { + let part_type = PySR1PartType::new(part_type.clone()); + let py_part_data = PySR1PartData::new(part_data.clone()); + if let Some(part_list) = parts.get_mut(&part_data.id) { + part_list.push((part_type, py_part_data)); + } else { + parts.insert(part_data.id, vec![(part_type, py_part_data)]); + } + } } parts } @@ -147,7 +184,7 @@ pub mod data { fn get_part_box(&self, part_id: i64) -> 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 { - let part_type = self.part_list.get_part_type(part_data.part_type_id.clone()).unwrap(); + let part_type = self.part_list.get_part_type(&part_data.part_type_id).unwrap(); // rotate let radius = part_data.angle; let ((x1, y1), (x2, y2)) = part_type.get_box(); @@ -162,11 +199,12 @@ pub mod data { } None } - } -} -pub mod translate { - use crate::translate; + fn save(&self, file_path: String) -> PyResult<()> { + self.ship.save(file_path).unwrap(); + Ok(()) + } + } } pub mod console { diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/simulator.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/simulator.rs index 67f4737..1dad45f 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/simulator.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/simulator.rs @@ -64,8 +64,38 @@ pub fn simulation() -> () { } } -#[allow(unused)] +pub struct Simulator { + pub rigid_body_set: RigidBodySet, + pub collider_set: ColliderSet, + pub gravity: Vector, + pub integration_parameters: IntegrationParameters, + pub physics_pipeline: PhysicsPipeline, + pub island_manager: IslandManager, + pub broad_phase: BroadPhase, + pub narrow_phase: NarrowPhase, + pub impulse_joint_set: ImpulseJointSet, + pub multibody_joint_set: MultibodyJointSet, + pub ccd_solver: CCDSolver, + pub physics_hooks: (), + pub event_handler: (), +} + pub mod python { use pyo3::prelude::*; use rapier2d_f64::prelude::*; + + #[pyclass] + pub struct PyIntegrationParameters { + pub data: IntegrationParameters, + } + + #[pymethods] + impl PyIntegrationParameters { + #[new] + fn new() -> Self { + PyIntegrationParameters { + data: IntegrationParameters::default(), + } + } + } } diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs index b4c6794..9397ab6 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs @@ -607,6 +607,17 @@ pub mod ship { } } } + + #[inline] + pub fn save(&self, file_name: String) -> Option<()> { + let part_list_file = serde_xml_rs::to_string(self); + if let Ok(part_list_file) = part_list_file { + fs::write(file_name, part_list_file).unwrap(); + Some(()) + } else { + None + } + } } #[pyfunction] diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/translate.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/translate.rs deleted file mode 100644 index 586097b..0000000 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/translate.rs +++ /dev/null @@ -1,16 +0,0 @@ -/* - * ------------------------------- - * Difficult Rocket - * Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com - * All rights reserved - * ------------------------------- - */ - -use std::collections::HashMap; - -type TranslateMapper = HashMap>>; - -pub struct Translater { - pub data: TranslateMapper, - pub language: String, -} diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs index 63b739a..4c45ff1 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs @@ -246,9 +246,9 @@ pub mod sr1 { } #[inline] - pub fn get_part_type(&self, type_name: String) -> Option { + pub fn get_part_type(&self, type_name: &String) -> Option { let cache = self.get_cache(); - match cache.get(&type_name) { + match cache.get(type_name) { Some(part) => Some(part.clone()), None => None, } @@ -699,11 +699,10 @@ pub mod sr1 { Some(ship.to_sr_ship(ship_name)) } - pub fn parse_part_list_to_part(&mut self, part_list: SR1PartList) { + pub fn parse_part_list_to_part(&mut self, part_list: &SR1PartList) { // parse parts for part in self.parts.iter_mut() { - let part_type_id = part.part_type_id.clone(); - if let Some(part_type) = part_list.get_part_type(part_type_id) { + if let Some(part_type) = part_list.get_part_type(&part.part_type_id) { part.part_type = part_type.p_type; } else { part.part_type = SR1PartTypeEnum::strut; @@ -712,8 +711,7 @@ pub mod sr1 { for disconnects in self.disconnected.iter_mut() { for (parts, _) in disconnects.iter_mut() { for part in parts.iter_mut() { - let part_type_id = part.part_type_id.clone(); - if let Some(part_type) = part_list.get_part_type(part_type_id) { + if let Some(part_type) = part_list.get_part_type(&part.part_type_id) { part.part_type = part_type.p_type; } else { part.part_type = SR1PartTypeEnum::strut; @@ -722,6 +720,27 @@ pub mod sr1 { } } } + + pub fn part_as_hashmap(&self) -> HashMap> { + // 返回一个 HashMap 用于快速查找 + // 同时为了 防止出现多个相同的 PartID 造成的数据丢失 + // 采用 Vec 存储 + let mut result: HashMap> = HashMap::new(); + for part_data in self.parts.iter() { + if let Some(part_vec) = result.get_mut(&part_data.id) { + part_vec.push(part_data.clone()); + } else { + result.insert(part_data.id, vec![part_data.clone()]); + } + } + result + } + + pub fn save(&self, file_name: String) -> Option<()> { + let raw_ship = self.to_raw_ship(); + raw_ship.save(file_name); + Some(()) + } } impl SR1ShipTrait for SR1Ship { @@ -780,7 +799,7 @@ pub mod sr1 { pub fn get_max_box(parts: &Vec, part_list: &SR1PartList) -> (f64, f64, f64, f64) { let mut max_box = (0_f64, 0_f64, 0_f64, 0_f64); for part in parts.iter() { - let part_type = part_list.get_part_type(part.part_type_id.clone()).unwrap(); + let part_type = part_list.get_part_type(&part.part_type_id).unwrap(); let ((x1, y1), (x2, y2)) = part_type.get_box(); // rotate let mut p1 = Point2D::new(x1, y1); diff --git a/mods/dr_game/__init__.py b/mods/dr_game/__init__.py index a930e96..55238fe 100644 --- a/mods/dr_game/__init__.py +++ b/mods/dr_game/__init__.py @@ -17,7 +17,7 @@ from Difficult_Rocket.api.mod import ModInfo from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.api.types import Options, Version -DR_rust_version = Version("0.2.11.0") # DR_mod 的 Rust 编写部分的兼容版本 +DR_rust_version = Version("0.2.12.0") # DR_mod 的 Rust 编写部分的兼容版本 logger = logging.getLogger('client.dr_game') diff --git a/mods/dr_game/lang/zh-CN.toml b/mods/dr_game/lang/zh-CN.toml index a1baf37..cf38f64 100644 --- a/mods/dr_game/lang/zh-CN.toml +++ b/mods/dr_game/lang/zh-CN.toml @@ -8,6 +8,5 @@ xml.load_done = "XML 文件加载完成" xml.load_time = "XML 文件加载消耗时间: {} 秒" ship.load = "正在加载飞船: {}" ship.load_time = "飞船加载消耗时间: {} 秒" -#ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}\n- 文件大小: {}" ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}" ship.render.done = "飞船渲染完成" diff --git a/mods/dr_game/sr1_ship.py b/mods/dr_game/sr1_ship.py index 3c56220..4b20680 100644 --- a/mods/dr_game/sr1_ship.py +++ b/mods/dr_game/sr1_ship.py @@ -430,6 +430,14 @@ class SR1ShipRender(BaseScreen): img.paste(pil_image, (int(self.part_data[part].x * 60 + img_center[0]), int(-self.part_data[part].y * 60 + img_center[1])), pil_image) img.save(f'test{time.time()}.png', 'PNG') + elif command.find('test'): + if command.find('save'): + if not self.rendered: + return + if not DR_mod_runtime.use_DR_rust: + return + self.rust_ship.save('./test-save.xml') + def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"): if not self.focus: return From bbdc5d98ac0ae974f98f39313c55803baf294299 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sat, 24 Jun 2023 21:16:32 +0800 Subject: [PATCH 7/9] add some xml test --- mods/dr_game/Difficult_Rocket_rs/__init__.py | 9 +- .../Difficult_Rocket_rs/src/Cargo.lock | 44 +++--- .../Difficult_Rocket_rs/src/Cargo.toml | 10 +- .../Difficult_Rocket_rs/src/src/lib.rs | 2 + .../Difficult_Rocket_rs/src/src/python.rs | 136 +++++++++++++++++- .../Difficult_Rocket_rs/src/src/sr1_data.rs | 1 + mods/dr_game/lang/zh-CN.toml | 1 + mods/dr_game/sr1_ship.py | 9 +- 8 files changed, 179 insertions(+), 33 deletions(-) diff --git a/mods/dr_game/Difficult_Rocket_rs/__init__.py b/mods/dr_game/Difficult_Rocket_rs/__init__.py index ee6ba0a..2f19ca3 100644 --- a/mods/dr_game/Difficult_Rocket_rs/__init__.py +++ b/mods/dr_game/Difficult_Rocket_rs/__init__.py @@ -18,16 +18,11 @@ if TYPE_CHECKING: def get_version_str() -> str: ... - - def simluation() -> None: ... - - - """ 用来测试 rust 的物理模拟能不能用 """ - - def part_list_read_test(file_name: Optional[str] = "./configs/PartList.xml") -> None: ... def read_ship_test(path: Optional[str] = "./configs/dock1.xml") -> None: ... + + def load_and_save_test(file_name: str): ... class Camera_rs: """ 用于闲的没事 用 rust 写一个 camera """ diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock index d40428d..59acc84 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock @@ -91,7 +91,7 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", + "memoffset", "scopeguard", ] @@ -119,6 +119,7 @@ name = "difficult_rocket_rs" version = "0.2.5" dependencies = [ "pyo3", + "quick-xml", "rapier2d-f64", "serde", "serde-xml-rs", @@ -182,13 +183,10 @@ dependencies = [ ] [[package]] -name = "memoffset" -version = "0.8.0" +name = "memchr" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -350,14 +348,14 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b1ac5b3731ba34fdaa9785f8d74d17448cd18f30cf19e0c7e7b1fdb5272109" +checksum = "cffef52f74ec3b1a1baf295d9b8fcc3070327aefc39a6d00656b13c1d0b8885c" dependencies = [ "cfg-if", "indoc", "libc", - "memoffset 0.8.0", + "memoffset", "parking_lot", "pyo3-build-config", "pyo3-ffi", @@ -367,9 +365,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cb946f5ac61bb61a5014924910d936ebd2b23b705f7a4a3c40b05c720b079a3" +checksum = "713eccf888fb05f1a96eb78c0dbc51907fee42b3377272dc902eb38985f418d5" dependencies = [ "once_cell", "target-lexicon", @@ -377,9 +375,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4d7c5337821916ea2a1d21d1092e8443cf34879e53a0ac653fbb98f44ff65c" +checksum = "5b2ecbdcfb01cbbf56e179ce969a048fd7305a66d4cdf3303e0da09d69afe4c3" dependencies = [ "libc", "pyo3-build-config", @@ -387,9 +385,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d39c55dab3fc5a4b25bbd1ac10a2da452c4aca13bb450f22818a002e29648d" +checksum = "b78fdc0899f2ea781c463679b20cb08af9247febc8d052de941951024cd8aea0" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -399,15 +397,25 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.18.3" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97daff08a4c48320587b5224cc98d609e3c27b6d437315bd40b605c98eeb5918" +checksum = "60da7b84f1227c3e2fe7593505de274dcf4c8928b4e0a1c23d551a14e4e80a0f" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "quick-xml" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.28" diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml index c787117..de5b5f3 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml @@ -16,11 +16,11 @@ opt-level = 3 [profile.release] strip = true opt-level = "s" -codegen-units = 1 +# codegen-units = 1 -#[dependencies.quick-xml] -#version = "0.27.1" -#features = ["serialize"] +[dependencies.quick-xml] +version = "0.29.0" +features = ["serialize"] [dependencies.serde] version = "1.0.164" @@ -37,5 +37,5 @@ version = "0.17.2" features = ["simd-stable"] [dependencies.pyo3] -version = "0.18.3" +version = "0.19.0" features = ["extension-module"] diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs index 0d831d3..ec4bd7a 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs @@ -44,6 +44,8 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(test_call, m)?)?; m.add_function(wrap_pyfunction!(sr1_data::part_list::read_part_list_py, m)?)?; m.add_function(wrap_pyfunction!(sr1_data::ship::py_raw_ship_from_file, m)?)?; + m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?; + m.add_function(wrap_pyfunction!(python::serde_test::test_ship_read_and_write, m)?)?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs index b13307e..894a194 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs @@ -55,7 +55,6 @@ pub mod data { #[pyclass] #[pyo3(name = "SR1PartList_rs")] - #[pyo3(text_signature = "(file_path = './configs/PartList.xml', list_name = 'NewPartList')")] pub struct PySR1PartList { pub data: SR1PartList, } @@ -63,6 +62,7 @@ pub mod data { #[pymethods] impl PySR1PartList { #[new] + #[pyo3(text_signature = "(file_path = './configs/PartList.xml', list_name = 'NewPartList')")] fn new(file_path: String, list_name: String) -> Self { let raw_part_list: RawPartList = RawPartList::from_file(file_path).unwrap(); let data = raw_part_list.to_sr_part_list(Some(list_name)); @@ -113,7 +113,6 @@ pub mod data { #[pyclass] #[pyo3(name = "SR1Ship_rs")] - #[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")] pub struct PySR1Ship { pub ship: SR1Ship, pub part_list: SR1PartList, @@ -122,6 +121,7 @@ pub mod data { #[pymethods] impl PySR1Ship { #[new] + #[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")] fn new(file_path: String, part_list: String, ship_name: String) -> Self { let mut ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap(); let part_list = SR1PartList::from_file(part_list).unwrap(); @@ -205,6 +205,15 @@ pub mod data { Ok(()) } } + + #[pyfunction] + pub fn load_and_save_test(file_name: String) -> PyResult<()> { + use crate::sr1_data::ship::RawShip; + use serde_xml_rs::to_string; + let ship = RawShip::from_file(file_name).unwrap(); + let _save_string = to_string(&ship); + Ok(()) + } } pub mod console { @@ -276,3 +285,126 @@ pub mod console { } } } + +pub mod serde_test { + use pyo3::prelude::*; + use quick_xml::de::from_str; + use quick_xml::se::to_string; + use serde::{Deserialize, Serialize}; + use std::fs; + + type IdType = i64; + + #[derive(Serialize, Deserialize, Debug, Clone)] + #[serde(rename = "Ship")] + pub struct TestShip { + #[serde(rename = "@version")] + pub version: i32, + #[serde(rename = "@liftedOff")] + pub lift_off: i8, + #[serde(rename = "@touchingGround")] + pub touching_ground: i8, + #[serde(rename = "Connections")] + pub connections: Connections, + #[serde(rename = "DisconnectedParts")] + pub disconnected_parts: Option, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct DisconnectedParts { + #[serde(rename = "DisconnectedPart")] + pub disconnected_part: Option>, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct DisconnectedPart { + #[serde(rename = "Parts")] + pub parts: Parts, + #[serde(rename = "Connections")] + pub connections: Connections, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct Connections { + #[serde(rename = "Connection")] + pub connection: Option>, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct Connection { + #[serde(rename = "@parentAttachPoint")] + pub parent_attach_point: i32, + #[serde(rename = "@childAttachPoint")] + pub child_attach_point: i32, + #[serde(rename = "@parentPart")] + pub parent_part: IdType, + #[serde(rename = "@childPart")] + pub child_part: IdType, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct Parts { + #[serde(rename = "Part")] + pub part: Vec, + } + + #[derive(Serialize, Deserialize, Debug, Clone)] + pub struct Part { + // #[serde(rename = "@Tank")] + // pub tank: Option, + // #[serde(rename = "@Engine")] + // pub engine: Option, + // #[serde(rename = "@Pod")] + // pub pod: Option, + #[serde(rename = "@partType")] + pub part_type_id: String, + #[serde(rename = "@id")] + pub id: i64, + #[serde(rename = "@x")] + pub x: f64, + #[serde(rename = "@y")] + pub y: f64, + #[serde(rename = "@editorAngle")] + pub editor_angle: i32, + #[serde(rename = "@angle")] + pub angle: f64, + #[serde(rename = "@angleV")] + pub angle_v: f64, + #[serde(rename = "@flippedX")] + pub flip_x: Option, + #[serde(rename = "@flippedY")] + pub flip_y: Option, + #[serde(rename = "@chuteX")] + pub chute_x: Option, + #[serde(rename = "@chuteY")] + pub chute_y: Option, + #[serde(rename = "@chuteAngle")] + pub chute_angle: Option, + #[serde(rename = "@chuteHeight")] + pub chute_height: Option, + #[serde(rename = "@extension")] + pub extension: Option, + #[serde(rename = "@inflate")] + pub inflate: Option, + #[serde(rename = "@inflation")] + pub inflation: Option, + #[serde(rename = "@exploded")] + pub exploded: Option, + #[serde(rename = "@rope")] + pub rope: Option, + #[serde(rename = "@activated")] + pub activated: Option, + #[serde(rename = "@deployed")] + pub deployed: Option, + } + + #[pyfunction] + #[pyo3(name = "test_ship_read_and_write")] + pub fn test_ship_read_and_write(file_name: String) -> PyResult<()> { + let file = fs::read_to_string(file_name).unwrap(); + let ship: TestShip = from_str(&file).unwrap(); + let save_string = to_string(&ship).unwrap(); + fs::write("./test-xml-rs.xml", save_string).unwrap(); + Ok(()) + } +} diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs index 9397ab6..e80160a 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs @@ -611,6 +611,7 @@ pub mod ship { #[inline] pub fn save(&self, file_name: String) -> Option<()> { let part_list_file = serde_xml_rs::to_string(self); + print!("{:?}", part_list_file); if let Ok(part_list_file) = part_list_file { fs::write(file_name, part_list_file).unwrap(); Some(()) diff --git a/mods/dr_game/lang/zh-CN.toml b/mods/dr_game/lang/zh-CN.toml index cf38f64..b124803 100644 --- a/mods/dr_game/lang/zh-CN.toml +++ b/mods/dr_game/lang/zh-CN.toml @@ -10,3 +10,4 @@ ship.load = "正在加载飞船: {}" ship.load_time = "飞船加载消耗时间: {} 秒" ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}" ship.render.done = "飞船渲染完成" +save.start = "正在保存飞船: {}" diff --git a/mods/dr_game/sr1_ship.py b/mods/dr_game/sr1_ship.py index 4b20680..e92b810 100644 --- a/mods/dr_game/sr1_ship.py +++ b/mods/dr_game/sr1_ship.py @@ -36,7 +36,11 @@ if TYPE_CHECKING: from Difficult_Rocket.client import ClientWindow if DR_mod_runtime.use_DR_rust: - from .Difficult_Rocket_rs import CenterCamera_rs, SR1PartList_rs, SR1Ship_rs + from .Difficult_Rocket_rs import (CenterCamera_rs, + SR1PartList_rs, + SR1Ship_rs, + load_and_save_test, + test_ship_read_and_write) logger = logging.getLogger('client.dr_game_sr1_ship') sr_tr = Tr(lang_path=Path('./mods/dr_game/lang')) @@ -150,6 +154,8 @@ class SR1ShipRender(BaseScreen): self.xml_name = file_path if DR_mod_runtime.use_DR_rust: try: + load_and_save_test(self.xml_name) + test_ship_read_and_write(self.xml_name) self.rust_ship = SR1Ship_rs(file_path, 'configs/PartList.xml', 'a_new_ship') print(self.rust_ship.name) print(self.rust_ship.img_pos) @@ -436,6 +442,7 @@ class SR1ShipRender(BaseScreen): return if not DR_mod_runtime.use_DR_rust: return + logger.info(sr_tr().sr1.ship.save.start().format(self.rust_ship)) self.rust_ship.save('./test-save.xml') def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"): From 67a9dddb309033e9b51e04e9737aee647901a74d Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 25 Jun 2023 15:00:37 +0800 Subject: [PATCH 8/9] add python camera --- Difficult_Rocket/utils/camera.py | 123 +++++++++++++++++++++++++++++++ mods/dr_game/sr1_ship.py | 57 +++++++------- 2 files changed, 151 insertions(+), 29 deletions(-) create mode 100644 Difficult_Rocket/utils/camera.py diff --git a/Difficult_Rocket/utils/camera.py b/Difficult_Rocket/utils/camera.py new file mode 100644 index 0000000..7a48b50 --- /dev/null +++ b/Difficult_Rocket/utils/camera.py @@ -0,0 +1,123 @@ +# ------------------------------- +# Difficult Rocket +# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com +# All rights reserved +# ------------------------------- + +# Huge thanks to pyglet developers + +from typing import Tuple, Optional + + +class Camera: + """ + + >>> from pyglet.window import Window + >>> window = Window() + + >>> camera = Camera(window) + >>> @window.event + + >>> def on_draw(): + >>> camera.begin() + >>> window.clear() + >>> camera.end() + + """ + def __init__(self, + window, + zoom: Optional[float] = 1.0, + dx: Optional[float] = 1.0, + dy: Optional[float] = 1.0, + min_zoom: Optional[float] = 1.0, + max_zoom: Optional[float] = 1.0) -> None: + self.window = window + self.dx = dx + self.dy = dy + self.zoom = zoom + self.min_zoom = min_zoom + self.max_zoom = max_zoom + + def get_view(self): + return self.window.view + + @property + def position(self) -> Tuple[float, float]: + return self.dx, self.dy + + @position.setter + def position(self, value: Tuple[float, float]): + self.dx, self.dy = value + + @property + def zoom_level(self) -> float: + return self.zoom + + @zoom_level.setter + def zoom_level(self, value: float) -> None: + self.zoom = min(max(value, self.min_zoom), self.max_zoom) + + def begin(self) -> None: + view = self.window.view + x = self.window.width / self.zoom + (self.dx / self.zoom) + y = self.window.height / self.zoom + (self.dy / self.zoom) + + view_matrix = view.translate((x * self.zoom, y * self.zoom, 0)) + view_matrix = view_matrix.scale((self.zoom, self.zoom, 1)) + + self.window.view = view_matrix + + def end(self) -> None: + view = self.window.view + x = self.window.width / self.zoom + (self.dx / self.zoom) + y = self.window.height / self.zoom + (self.dy / self.zoom) + + view_matrix = view.scale((1.0 / self.zoom, 1.0 / self.zoom, 1)) + view_matrix = view_matrix.translate((-x * self.zoom, -y * self.zoom, 0)) + + self.window.view = view_matrix + + def __enter__(self): + self.begin() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.end() + + +class CenterCamera(Camera): + """ + A camera that centers the view on the center of the window + + >>> from pyglet.window import Window + >>> window = Window() + + >>> camera = CenterCamera(window) + >>> @window.event + + >>> def on_draw(): + >>> camera.begin() + >>> window.clear() + >>> camera.end() + + """ + def begin(self) -> None: + view = self.window.view + x = self.window.width / 2.0 / self.zoom + (self.dx / self.zoom) + y = self.window.height / 2.0 / self.zoom + (self.dy / self.zoom) + + view_matrix = view.translate((x * self.zoom, y * self.zoom, 0)) + view_matrix = view_matrix.scale((self.zoom, self.zoom, 1)) + + self.window.view = view_matrix + + def end(self) -> None: + view = self.window.view + x = self.window.width / 2.0 / self.zoom + (self.dx / self.zoom) + y = self.window.height / 2.0 / self.zoom + (self.dy / self.zoom) + + view_matrix = view.scale((1.0 / self.zoom, 1.0 / self.zoom, 1)) + view_matrix = view_matrix.translate((-x * self.zoom, -y * self.zoom, 0)) + + self.window.view = view_matrix + \ No newline at end of file diff --git a/mods/dr_game/sr1_ship.py b/mods/dr_game/sr1_ship.py index e92b810..cf4d87e 100644 --- a/mods/dr_game/sr1_ship.py +++ b/mods/dr_game/sr1_ship.py @@ -30,14 +30,14 @@ from Difficult_Rocket.utils.translate import Tr from Difficult_Rocket.api.types import Fonts, Options from Difficult_Rocket.command.line import CommandText from Difficult_Rocket.client.screen import BaseScreen +from Difficult_Rocket.utils.camera import CenterCamera from .types import SR1Textures, SR1PartTexture, SR1PartData, SR1Rotation, xml_bool if TYPE_CHECKING: from Difficult_Rocket.client import ClientWindow if DR_mod_runtime.use_DR_rust: - from .Difficult_Rocket_rs import (CenterCamera_rs, - SR1PartList_rs, + from .Difficult_Rocket_rs import (SR1PartList_rs, SR1Ship_rs, load_and_save_test, test_ship_read_and_write) @@ -138,9 +138,9 @@ class SR1ShipRender(BaseScreen): load_end_time = time.time_ns() logger.info(sr_tr().mod.info.setup.use_time().format( (load_end_time - load_start_time) / 1000000000)) + self.camera = CenterCamera(main_window, + min_zoom=(1 / 2) ** 10, max_zoom=10) if DR_mod_runtime.use_DR_rust: - self.camera_rs = CenterCamera_rs(main_window, - min_zoom=(1 / 2) ** 10, max_zoom=10) self.rust_parts = None self.part_list_rs = SR1PartList_rs('configs/PartList.xml', 'default_part_list') @@ -234,10 +234,9 @@ class SR1ShipRender(BaseScreen): self.part_data: Dict[int, SR1PartData] = {} self.parts_sprite: Dict[int, Sprite] = {} self.part_line_box = {} - self.camera_rs.zoom = 1.0 - if DR_mod_runtime.use_DR_rust: - self.camera_rs.dx = 0 - self.camera_rs.dy = 0 + self.camera.zoom = 1.0 + self.camera.dx = 0 + self.camera.dy = 0 parts = self.xml_root.find('Parts') for part_xml in parts: if part_xml.tag != 'Part': @@ -266,11 +265,11 @@ class SR1ShipRender(BaseScreen): def update_parts(self) -> bool: if not self.rendered: return False - self.debug_line.x2, self.debug_line.y2 = self.camera_rs.dx + ( - self.window_pointer.width / 2), self.camera_rs.dy + ( + self.debug_line.x2, self.debug_line.y2 = self.camera.dx + ( + self.window_pointer.width / 2), self.camera.dy + ( self.window_pointer.height / 2) - self.debug_d_pos_label.text = f'x: {self.camera_rs.dx} y: {self.camera_rs.dy}' - self.debug_d_pos_label.position = self.camera_rs.dx + (self.window_pointer.width / 2), self.camera_rs.dy + ( + self.debug_d_pos_label.text = f'x: {self.camera.dx} y: {self.camera.dy}' + self.debug_d_pos_label.position = self.camera.dx + (self.window_pointer.width / 2), self.camera.dy + ( self.window_pointer.height / 2) + 10, 0 self.need_update_parts = False @@ -289,7 +288,7 @@ class SR1ShipRender(BaseScreen): self.update_parts() self.need_update_parts = False - with self.camera_rs: + with self.camera: self.part_box_batch.draw() self.part_batch.draw() self.part_box_batch.draw() @@ -323,29 +322,29 @@ class SR1ShipRender(BaseScreen): mouse_dx = x - (window.width / 2) mouse_dy = y - (window.height / 2) # 鼠标缩放位置相对于屏幕中心的位置 - mouse_dx_d = mouse_dx - self.camera_rs.dx - mouse_dy_d = mouse_dy - self.camera_rs.dy + mouse_dx_d = mouse_dx - self.camera.dx + mouse_dy_d = mouse_dy - self.camera.dy # 鼠标相对偏移量的偏移量 if scroll_y == 0: zoom_d = 1 else: zoom_d = ((2 ** scroll_y) - 1) * 0.5 + 1 # 缩放的变换量 - if not (self.camera_rs.zoom == 10 and scroll_y > 0): - if self.camera_rs.zoom * zoom_d >= 10: - zoom_d = 10 / self.camera_rs.zoom - self.camera_rs.zoom = 10 + if not (self.camera.zoom == 10 and scroll_y > 0): + if self.camera.zoom * zoom_d >= 10: + zoom_d = 10 / self.camera.zoom + self.camera.zoom = 10 else: - self.camera_rs.zoom *= zoom_d + self.camera.zoom *= zoom_d mouse_dx_d *= (1 - zoom_d) mouse_dy_d *= (1 - zoom_d) - self.camera_rs.dx += mouse_dx_d - self.camera_rs.dy += mouse_dy_d + self.camera.dx += mouse_dx_d + self.camera.dy += mouse_dy_d self.debug_mouse_line.x2, self.debug_mouse_line.y2 = x, y - self.debug_mouse_delta_line.x2 = (mouse_dx - self.camera_rs.dx) * (1 - (0.5 ** scroll_y)) + ( + self.debug_mouse_delta_line.x2 = (mouse_dx - self.camera.dx) * (1 - (0.5 ** scroll_y)) + ( window.width / 2) - self.debug_mouse_delta_line.y2 = (mouse_dy - self.camera_rs.dy) * (1 - (0.5 ** scroll_y)) + ( + self.debug_mouse_delta_line.y2 = (mouse_dy - self.camera.dy) * (1 - (0.5 ** scroll_y)) + ( window.height / 2) self.debug_mouse_label.text = f'x: {mouse_dx} y: {mouse_dy}' self.debug_mouse_label.position = x, y + 10, 0 @@ -355,9 +354,9 @@ class SR1ShipRender(BaseScreen): def on_command(self, command: CommandText, window: "ClientWindow"): if command.find('render'): if command.find('reset'): - self.camera_rs.zoom = 1 - self.camera_rs.dx = 0 - self.camera_rs.dy = 0 + self.camera.zoom = 1 + self.camera.dx = 0 + self.camera.dy = 0 self.window_pointer.view = Vec4() else: self.need_draw = True @@ -448,8 +447,8 @@ class SR1ShipRender(BaseScreen): def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"): if not self.focus: return - self.camera_rs.dx += dx - self.camera_rs.dy += dy + self.camera.dx += dx + self.camera.dy += dy self.need_update_parts = True # self.update_parts() From 45cfa76d240590adb5eab8242d47cf03d7305468 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 25 Jun 2023 15:42:49 +0800 Subject: [PATCH 9/9] upadte dr game --- docs/src/change_log/dr_game.md | 22 +- docs/src/change_log/dr_sdk.md | 12 +- mods/dr_game/Difficult_Rocket_rs/__init__.py | 40 ---- .../Difficult_Rocket_rs/src/src/lib.rs | 6 +- .../Difficult_Rocket_rs/src/src/python.rs | 1 + .../Difficult_Rocket_rs/src/src/render.rs | 212 ------------------ 6 files changed, 34 insertions(+), 259 deletions(-) delete mode 100644 mods/dr_game/Difficult_Rocket_rs/src/src/render.rs diff --git a/docs/src/change_log/dr_game.md b/docs/src/change_log/dr_game.md index 14630c6..3315aee 100644 --- a/docs/src/change_log/dr_game.md +++ b/docs/src/change_log/dr_game.md @@ -3,7 +3,27 @@ - 最新版本号 - DR game: 0.2.0.0 - - DR rs: 0.2.11.0 + - DR rs: 0.2.13.0 + +## DR game 0.2.1.0 + +### 修改 + +- 将 `sr1_ship` 中的 `Camera_rs` 改为 `Difficult_Rocket.utils.camera.Camera` + +## DR rs 0.2.13.0 + +### 删除 + +- 删除了 `render.rs` + - 没必要拿 rust 写这玩意( + - 用 `DR game` 的 `camera` 代替 + +## DR rs 0.2.12.0 + +### 添加 + +- 添加了 xml 的读取测试 ## DR game 0.1.2.0 diff --git a/docs/src/change_log/dr_sdk.md b/docs/src/change_log/dr_sdk.md index 34e437a..bca9a98 100644 --- a/docs/src/change_log/dr_sdk.md +++ b/docs/src/change_log/dr_sdk.md @@ -4,11 +4,21 @@ - 最新版本号 - DR sdk: 0.8.4.0 +## DR sdk 0.8.4.1 + +### Add + +- `utils.camera` + - `Camera` + - 一个 2D 摄影机,可以用于高效变换渲染坐标 + - `CenterCamera` + - 一个中心对器的 2D 摄影机,可以用于高效变换渲染坐标 + ## DR sdk 0.8.4.0 ### Fix -- issue #33 (https://github.com/shenjackyuanjie/Difficult-Rocket/issues/33) +- issue #33 () - 修复了实际上并不会加载 `.otf` 格式的字体文件的问题 ### language diff --git a/mods/dr_game/Difficult_Rocket_rs/__init__.py b/mods/dr_game/Difficult_Rocket_rs/__init__.py index 2f19ca3..d3ac426 100644 --- a/mods/dr_game/Difficult_Rocket_rs/__init__.py +++ b/mods/dr_game/Difficult_Rocket_rs/__init__.py @@ -24,46 +24,6 @@ if TYPE_CHECKING: def load_and_save_test(file_name: str): ... - class Camera_rs: - """ 用于闲的没事 用 rust 写一个 camera """ - - def __new__(cls, window: Window, - zoom: float = 1.0, - dx: float = 1.0, dy: float = 1.0, - min_zoom: float = 1.0, - max_zoom: float = 1.0): ... - - @property - def dx(self) -> float: ... - @property - def dy(self) -> float: ... - @property - def zoom(self) -> float: ... - @property - def position(self) -> Tuple[float, float]: ... - @dx.setter - def dx(self, value: float) -> None: ... - @dy.setter - def dy(self, value: float) -> None: ... - @zoom.setter - def zoom(self, value: float) -> None: ... - - def begin(self) -> None: ... - - def end(self) -> None: ... - - def __enter__(self, window) -> None: ... - - def __exit__(self, exc_type, exc_val, exc_tb) -> None: ... - - - class CenterCamera_rs(Camera_rs): - """ 用于依旧闲的没事 用 rust 写一个中央对齐的 camera """ - - - class PartFrame_rs: - ... - class SR1PartType_rs: """ 用于从 rust 中读取 SR1PartType diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs index ec4bd7a..767b240 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs @@ -9,7 +9,6 @@ mod logger; mod plugin; mod python; -mod render; mod simulator; mod sr1_data; mod types; @@ -26,7 +25,7 @@ enum LoadState { } #[pyfunction] -fn get_version_str() -> String { "0.2.12.0".to_string() } +fn get_version_str() -> String { "0.2.13.0".to_string() } #[pyfunction] fn test_call(py_obj: &PyAny) -> PyResult { @@ -46,9 +45,6 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(sr1_data::ship::py_raw_ship_from_file, m)?)?; m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?; m.add_function(wrap_pyfunction!(python::serde_test::test_ship_read_and_write, m)?)?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs index 894a194..f36ada7 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs @@ -290,6 +290,7 @@ pub mod serde_test { use pyo3::prelude::*; use quick_xml::de::from_str; use quick_xml::se::to_string; + use quick_xml::Writer; use serde::{Deserialize, Serialize}; use std::fs; diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/render.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/render.rs deleted file mode 100644 index 7d560f6..0000000 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/render.rs +++ /dev/null @@ -1,212 +0,0 @@ -/* - * ------------------------------- - * Difficult Rocket - * Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com - * All rights reserved - * ------------------------------- - */ - -pub mod camera { - - use pyo3::intern; - use pyo3::prelude::*; - - #[pyclass(name = "Camera_rs", subclass)] - pub struct CameraRs { - pub window: Py, - #[pyo3(get, set)] - pub dx: f64, - #[pyo3(get, set)] - pub dy: f64, - pub zoom: f64, - #[pyo3(get, set)] - pub max_zoom: f64, - #[pyo3(get, set)] - pub min_zoom: f64, - } - - #[pyclass(extends = CameraRs, name = "CenterCamera_rs")] - pub struct CenterCameraRs; - - #[pymethods] - impl CenterCameraRs { - #[new] - #[pyo3(signature = (window, zoom=1.0, dx=1.0, dy=1.0, min_zoom=1.0, max_zoom=1.0))] - pub fn py_new(window: &PyAny, zoom: f64, dx: f64, dy: f64, min_zoom: f64, max_zoom: f64) -> PyResult<(Self, CameraRs)> { - return Ok(( - CenterCameraRs {}, - CameraRs { - dx, - dy, - zoom, - min_zoom, - max_zoom, - window: window.into(), - }, - )); - } - - // pub fn __enter__(py_self: PyRef) -> PyResult> { - // // println!("enter!"); - // CenterCameraRs::begin()?; - // Ok(py_self) - // } - - pub fn begin(self_: PyRef<'_, Self>) -> PyResult<()> { - println!("begin!"); - let super_: &CameraRs = self_.as_ref(); - // 获取父类 - Python::with_gil(|py| -> PyResult<()> { - let view = super_.window.getattr(py, intern!(py, "view"))?; - // 获取存储的 view - let x: f64 = super_.window.getattr(py, intern!(py, "width"))?.extract(py)?; - let y: f64 = super_.window.getattr(py, intern!(py, "height"))?.extract(py)?; - let x: f64 = x / 2.0 / super_.zoom + (super_.dx / super_.zoom); - let y: f64 = y / 2.0 / super_.zoom + (super_.dy / super_.zoom); - // 计算中心点 - - // view.call_method1(py, "translate", (x, y))?; - // view.call_method1(py, "scale", (super_.zoom, super_.zoom))?; - - let args = ((x * super_.zoom, y * super_.zoom, 0),); - let view_matrix = view.call_method1(py, intern!(py, "translate"), args)?; - // view_matrix = self.view.translate((x * zoom, y * zoom, 0)) - - let args = ((super_.zoom, super_.zoom, 1),); - let view_matrix = view_matrix.call_method1(py, intern!(py, "scale"), args)?; - // view_matrix = view_matrix.scale((zoom, zoom, 1)) - - super_.window.setattr(py, intern!(py, "view"), view_matrix)?; - // self.view = view_matrix - Ok(()) - })?; - Ok(()) - } - } - - #[pymethods] - impl CameraRs { - #[new] - #[pyo3(signature = (window, zoom=1.0, dx=1.0, dy=1.0, min_zoom=1.0, max_zoom=1.0))] - pub fn py_new(window: &PyAny, zoom: f64, dx: f64, dy: f64, min_zoom: f64, max_zoom: f64) -> PyResult { - return Ok(CameraRs { - dx, - dy, - zoom, - min_zoom, - max_zoom, - window: window.into(), - }); - } - - pub fn get_view(&self) -> PyResult { - Ok(Python::with_gil(|py| -> PyResult { - Ok(self.window.getattr(py, intern!(py, "view"))?) - })?) - } - - #[getter] - pub fn get_position(&self) -> (f64, f64) { return (self.dx, self.dy); } - - #[setter] - pub fn set_position(&mut self, value: (f64, f64)) -> () { - self.dx = value.0; - self.dy = value.1; - } - - #[getter] - pub fn get_zoom(&self) -> PyResult { Ok(self.zoom) } - - #[setter] - pub fn set_zoom(&mut self, value: f64) -> PyResult<()> { - self.zoom = value.min(self.max_zoom).max(self.min_zoom); - Ok(()) - } - - pub fn begin(&self) -> PyResult<()> { - Python::with_gil(|py| -> PyResult<()> { - let view = self.window.getattr(py, intern!(py, "view"))?; - - let x: f64 = self.window.getattr(py, intern!(py, "width"))?.extract(py)?; - let y: f64 = self.window.getattr(py, intern!(py, "height"))?.extract(py)?; - let x: f64 = x / 2.0 / self.zoom + (self.dx / self.zoom); - let y: f64 = y / 2.0 / self.zoom + (self.dy / self.zoom); - // use to get center of the screen - - let args = ((x * self.zoom, y * self.zoom, 0),); - let view_matrix = view.call_method1(py, intern!(py, "translate"), args)?; - // view_matrix = self.view.translate((x * zoom, y * zoom, 0)) - - let args = ((self.zoom, self.zoom, 1),); - let view_matrix = view_matrix.call_method1(py, intern!(py, "scale"), args)?; - // view_matrix = view_matrix.scale((zoom, zoom, 1)) - - self.window.setattr(py, intern!(py, "view"), view_matrix)?; - // self.view = view_matrix - Ok(()) - })?; - return Ok(()); - } - - pub fn end(&self) -> PyResult<()> { - Python::with_gil(|py| -> PyResult<()> { - let view = self.window.getattr(py, intern!(py, "view"))?; - - let x: f64 = self.window.getattr(py, intern!(py, "width"))?.extract(py)?; - let y: f64 = self.window.getattr(py, intern!(py, "height"))?.extract(py)?; - let x: f64 = x / 2.0 / self.zoom + (self.dx / self.zoom); - let y: f64 = y / 2.0 / self.zoom + (self.dy / self.zoom); - - let args = ((1.0 / self.zoom, 1.0 / self.zoom, 1),); - let view_matrix = view.call_method1(py, intern!(py, "scale"), args)?; - - let args = ((-x * self.zoom, -y * self.zoom, 0),); - let view_matrix = view_matrix.call_method1(py, intern!(py, "translate"), args)?; - - self.window.setattr(py, intern!(py, "view"), view_matrix)?; - Ok(()) - })?; - return Ok(()); - } - - /// https://github.com/PyO3/pyo3/discussions/2931#discussioncomment-4820729 for finding this - /// https://github.com/PyO3/pyo3/issues/1205#issuecomment-1164096251 for advice on `__enter__` - pub fn __enter__(py_self: PyRef) -> PyResult> { - // println!("enter!"); - py_self.begin()?; - Ok(py_self) - } - - pub fn __exit__(&self, _exc_type: PyObject, _exc_value: PyObject, _traceback: PyObject) -> PyResult<()> { - // println!("exit!"); - self.end()?; - return Ok(()); - } - } -} - -pub mod screen { - use pyo3::prelude::*; - // use crate::types::sr1::SR1PartData; - - #[pyclass] - #[pyo3(name = "PartFrame_rs")] - pub struct PartFrame { - pub box_size: i32, - pub width: i64, - pub height: i64, - // pub frame_box: Vec> - } - - #[pymethods] - impl PartFrame { - #[new] - pub fn py_new() -> PyResult { - Ok(PartFrame { - box_size: 111, - width: 111, - height: 111, - }) - } - } -}