Compare commits
6 Commits
ad83def45e
...
364924a7b7
Author | SHA1 | Date | |
---|---|---|---|
364924a7b7 | |||
893872c012 | |||
2ad60e398c | |||
24f17f6d4f | |||
e997633cc5 | |||
7fed4032e0 |
@ -264,7 +264,7 @@ class ClientWindow(Window):
|
|||||||
def start_game(self) -> None:
|
def start_game(self) -> None:
|
||||||
self.set_icon(pyglet.image.load('assets/textures/icon.png'))
|
self.set_icon(pyglet.image.load('assets/textures/icon.png'))
|
||||||
try:
|
try:
|
||||||
pyglet.app.event_loop.run(1 / self.main_config['runtime']['fps'])
|
pyglet.app.run(1 / self.main_config['runtime']['fps'])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
self.logger.warning("==========client stop. KeyboardInterrupt info==========")
|
self.logger.warning("==========client stop. KeyboardInterrupt info==========")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
@ -3,7 +3,43 @@
|
|||||||
|
|
||||||
- 最新版本号
|
- 最新版本号
|
||||||
- DR game: 0.3.2.0
|
- DR game: 0.3.2.0
|
||||||
- DR rs: 0.2.19.0
|
- DR rs: 0.2.20.2
|
||||||
|
|
||||||
|
## 20230724 DR rs 0.2.20.2
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- [#49](https://github.com/shenjackyuanjie/Difficult-Rocket/issues/49)
|
||||||
|
- missing field `touchingGround`
|
||||||
|
- SR1 says: `touchingGround` field is NOT Required
|
||||||
|
- make them happy
|
||||||
|
- SR1 说: `touchingGround` 字段也是可选的
|
||||||
|
- 让他们开心
|
||||||
|
- 我就看看我能发多少个 issue
|
||||||
|
|
||||||
|
## 20230724 DR rs 0.2.20.1
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- [#48](https://github.com/shenjackyuanjie/Difficult-Rocket/issues/48)
|
||||||
|
- `missing field version`
|
||||||
|
- SR1 says: `version` field is NOT Required
|
||||||
|
- make them happy
|
||||||
|
- SR1 说: `version` 字段也是可选的
|
||||||
|
- 让他们开心
|
||||||
|
- 我谢谢您啊 Jundroo
|
||||||
|
- 我就看看我能发多少个 issue
|
||||||
|
|
||||||
|
## 20230724 DR rs 0.2.20.0
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- [#47](https://github.com/shenjackyuanjie/Difficult-Rocket/issues/47)
|
||||||
|
- `editorAngle field is Option<i32>`
|
||||||
|
- SR1 says: `editorAngle` field is Optional
|
||||||
|
- make them happy
|
||||||
|
- SR1 说: `editorAngle` 字段是可选的
|
||||||
|
- 让他们开心
|
||||||
|
|
||||||
## 20230721 DR rs 0.2.19.0
|
## 20230721 DR rs 0.2.19.0
|
||||||
|
|
||||||
|
@ -144,7 +144,14 @@ if TYPE_CHECKING:
|
|||||||
def __init__(self,
|
def __init__(self,
|
||||||
file_path: Optional[str] = './assets/builtin/dock1.xml',
|
file_path: Optional[str] = './assets/builtin/dock1.xml',
|
||||||
part_list: Optional[SR1PartList_rs] = None,
|
part_list: Optional[SR1PartList_rs] = None,
|
||||||
ship_name: Optional[str] = 'NewShip'): ...
|
ship_name: Optional[str] = 'NewShip'):
|
||||||
|
"""
|
||||||
|
读取 SR1Ship
|
||||||
|
:raise ValueError: 读取失败
|
||||||
|
:param file_path:
|
||||||
|
:param part_list:
|
||||||
|
:param ship_name:
|
||||||
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str: ...
|
def name(self) -> str: ...
|
||||||
|
2
mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock
generated
2
mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock
generated
@ -116,7 +116,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "difficult_rocket_rs"
|
name = "difficult_rocket_rs"
|
||||||
version = "0.2.19"
|
version = "0.2.20"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pyo3",
|
"pyo3",
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "difficult_rocket_rs"
|
name = "difficult_rocket_rs"
|
||||||
version = "0.2.19"
|
version = "0.2.20"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license-file = '../../LICENSE'
|
license-file = '../../LICENSE'
|
||||||
authors = [
|
authors = [
|
||||||
|
@ -24,7 +24,7 @@ enum LoadState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn get_version_str() -> String { "0.2.19.0".to_string() }
|
fn get_version_str() -> String { "0.2.20.2".to_string() }
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn test_call(py_obj: &PyAny) -> PyResult<bool> {
|
fn test_call(py_obj: &PyAny) -> PyResult<bool> {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
pub mod data {
|
pub mod data {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use pyo3::exceptions::PyValueError;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::sr1_data::part_list::RawPartList;
|
use crate::sr1_data::part_list::RawPartList;
|
||||||
@ -170,14 +171,19 @@ pub mod data {
|
|||||||
impl PySR1Ship {
|
impl PySR1Ship {
|
||||||
#[new]
|
#[new]
|
||||||
#[pyo3(text_signature = "(file_path = './assets/builtin/dock1.xml', part_list = None, ship_name = 'NewShip')")]
|
#[pyo3(text_signature = "(file_path = './assets/builtin/dock1.xml', part_list = None, ship_name = 'NewShip')")]
|
||||||
fn new(file_path: String, part_list: Option<PySR1PartList>, ship_name: Option<String>) -> Self {
|
fn new(file_path: String, part_list: Option<PySR1PartList>, ship_name: Option<String>) -> PyResult<Self> {
|
||||||
let mut ship = SR1Ship::from_file(file_path, Some(ship_name.unwrap_or("new ship".to_string()))).unwrap();
|
let ship = SR1Ship::from_file(file_path.clone(), Some(ship_name.unwrap_or("new ship".to_string())));
|
||||||
let part_list = match part_list {
|
match ship {
|
||||||
Some(part_list) => part_list.data,
|
Some(mut ship) => {
|
||||||
None => SR1PartList::from_file("./assets/builtin/PartList.xml".to_string()).unwrap(),
|
let part_list = match part_list {
|
||||||
};
|
Some(part_list) => part_list.data,
|
||||||
ship.parse_part_list_to_part(&part_list);
|
None => SR1PartList::from_file("./assets/builtin/PartList.xml".to_string()).unwrap(),
|
||||||
Self { ship, part_list }
|
};
|
||||||
|
ship.parse_part_list_to_part(&part_list);
|
||||||
|
Ok(Self { ship, part_list })
|
||||||
|
}
|
||||||
|
None => Err(PyValueError::new_err(format!("Parse ship failed! {}", file_path))),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
|
@ -377,7 +377,7 @@ pub mod ship {
|
|||||||
|
|
||||||
use super::part_list::SR1PartTypeEnum;
|
use super::part_list::SR1PartTypeEnum;
|
||||||
|
|
||||||
use crate::types::sr1::{i8_to_bool, SR1PartDataTrait, SR1PartTypeAttr, SR1ShipTrait};
|
use crate::types::sr1::{i8_to_bool, option_i8_to_option_bool, SR1PartDataTrait, SR1PartTypeAttr, SR1ShipTrait};
|
||||||
use crate::types::sr1::{IdType, SR1PartData, SR1PartDataAttr, SR1Ship};
|
use crate::types::sr1::{IdType, SR1PartData, SR1PartDataAttr, SR1Ship};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
@ -387,11 +387,15 @@ pub mod ship {
|
|||||||
pub parts: Parts,
|
pub parts: Parts,
|
||||||
#[serde(rename = "Connections")]
|
#[serde(rename = "Connections")]
|
||||||
pub connects: Connections,
|
pub connects: Connections,
|
||||||
pub version: i32,
|
pub version: Option<i32>, // Option for https://github.com/shenjackyuanjie/Difficult-Rocket/issues/48
|
||||||
|
// SR1 says version is also optional, let them happy
|
||||||
|
// it's always 1
|
||||||
#[serde(rename = "liftedOff")]
|
#[serde(rename = "liftedOff")]
|
||||||
pub lift_off: i8,
|
pub lift_off: i8,
|
||||||
#[serde(rename = "touchingGround")]
|
#[serde(rename = "touchingGround")]
|
||||||
pub touch_ground: i8,
|
pub touch_ground: Option<i8>, // Option for https://github.com/shenjackyuanjie/Difficult-Rocket/issues/49
|
||||||
|
// SR1 says it's optional, let them happy
|
||||||
|
// NOT always 0
|
||||||
#[serde(rename = "DisconnectedParts")]
|
#[serde(rename = "DisconnectedParts")]
|
||||||
pub disconnected: Option<DisconnectedParts>,
|
pub disconnected: Option<DisconnectedParts>,
|
||||||
}
|
}
|
||||||
@ -422,7 +426,8 @@ pub mod ship {
|
|||||||
pub x: f64,
|
pub x: f64,
|
||||||
pub y: f64,
|
pub y: f64,
|
||||||
#[serde(rename = "editorAngle")]
|
#[serde(rename = "editorAngle")]
|
||||||
pub editor_angle: i32,
|
pub editor_angle: Option<i32>, // Option for https://github.com/shenjackyuanjie/Difficult-Rocket/issues/47
|
||||||
|
// SR1 says it's optional, let them happy
|
||||||
pub angle: f64,
|
pub angle: f64,
|
||||||
#[serde(rename = "angleV")]
|
#[serde(rename = "angleV")]
|
||||||
pub angle_v: f64,
|
pub angle_v: f64,
|
||||||
@ -515,12 +520,6 @@ pub mod ship {
|
|||||||
pub child_part: IdType,
|
pub child_part: IdType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Part {
|
|
||||||
/// 根据 Part 的原始数据猜测 Part 的类型
|
|
||||||
/// jundroo 我日你先人
|
|
||||||
fn guess_part_type(&self) -> SR1PartTypeEnum { todo!() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SR1PartDataTrait for Part {
|
impl SR1PartDataTrait for Part {
|
||||||
fn to_sr_part_data(&self) -> SR1PartData {
|
fn to_sr_part_data(&self) -> SR1PartData {
|
||||||
let attr = SR1PartDataAttr::from_raw(&self, None, true);
|
let attr = SR1PartDataAttr::from_raw(&self, None, true);
|
||||||
@ -534,7 +533,7 @@ pub mod ship {
|
|||||||
angle_v: self.angle_v.to_owned(),
|
angle_v: self.angle_v.to_owned(),
|
||||||
flip_x: i8_to_bool(self.flip_x.unwrap_or(0_i8)),
|
flip_x: i8_to_bool(self.flip_x.unwrap_or(0_i8)),
|
||||||
flip_y: i8_to_bool(self.flip_y.unwrap_or(0_i8)),
|
flip_y: i8_to_bool(self.flip_y.unwrap_or(0_i8)),
|
||||||
editor_angle: self.editor_angle.to_owned(),
|
editor_angle: self.editor_angle.unwrap_or(0_i32),
|
||||||
part_type,
|
part_type,
|
||||||
part_type_id: self.part_type_id.clone(),
|
part_type_id: self.part_type_id.clone(),
|
||||||
active: i8_to_bool(self.activated.unwrap_or(0_i8)),
|
active: i8_to_bool(self.activated.unwrap_or(0_i8)),
|
||||||
@ -576,11 +575,11 @@ pub mod ship {
|
|||||||
SR1Ship {
|
SR1Ship {
|
||||||
name: name.unwrap_or("NewShip".to_string()),
|
name: name.unwrap_or("NewShip".to_string()),
|
||||||
description: "".to_string(),
|
description: "".to_string(),
|
||||||
version: self.version,
|
version: self.version.unwrap_or(1_i32),
|
||||||
parts,
|
parts,
|
||||||
connections,
|
connections,
|
||||||
lift_off: i8_to_bool(self.lift_off.to_owned()),
|
lift_off: i8_to_bool(self.lift_off.to_owned()),
|
||||||
touch_ground: i8_to_bool(self.touch_ground.to_owned()),
|
touch_ground: option_i8_to_option_bool(self.touch_ground.to_owned()).unwrap_or(true),
|
||||||
disconnected,
|
disconnected,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,7 +470,7 @@ pub mod sr1 {
|
|||||||
id: self.id,
|
id: self.id,
|
||||||
x: self.x,
|
x: self.x,
|
||||||
y: self.y,
|
y: self.y,
|
||||||
editor_angle: self.editor_angle,
|
editor_angle: Some(self.editor_angle),
|
||||||
angle: self.angle,
|
angle: self.angle,
|
||||||
angle_v: self.angle_v,
|
angle_v: self.angle_v,
|
||||||
flip_x: Some(bool_to_i8(self.flip_x)),
|
flip_x: Some(bool_to_i8(self.flip_x)),
|
||||||
@ -708,8 +708,15 @@ pub mod sr1 {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// 解析为 RawShip
|
// 解析为 RawShip
|
||||||
let ship: RawShip = RawShip::from_file(file_name).unwrap();
|
let ship: Option<RawShip> = RawShip::from_file(file_name);
|
||||||
Some(ship.to_sr_ship(ship_name))
|
match ship {
|
||||||
|
Some(ship) => {
|
||||||
|
// 解析为 SR1Ship
|
||||||
|
let sr_ship = ship.to_sr_ship(ship_name);
|
||||||
|
Some(sr_ship)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_part_list_to_part(&mut self, part_list: &SR1PartList) {
|
pub fn parse_part_list_to_part(&mut self, part_list: &SR1PartList) {
|
||||||
@ -970,9 +977,9 @@ pub mod sr1 {
|
|||||||
RawShip {
|
RawShip {
|
||||||
parts: RawParts { parts },
|
parts: RawParts { parts },
|
||||||
connects: connections,
|
connects: connections,
|
||||||
version: self.version,
|
version: Some(self.version),
|
||||||
lift_off: bool_to_i8(self.lift_off),
|
lift_off: bool_to_i8(self.lift_off),
|
||||||
touch_ground: bool_to_i8(self.touch_ground),
|
touch_ground: Some(bool_to_i8(self.touch_ground)),
|
||||||
disconnected,
|
disconnected,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ from Difficult_Rocket.api.mod import ModInfo
|
|||||||
from Difficult_Rocket.client import ClientWindow
|
from Difficult_Rocket.client import ClientWindow
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
DR_rust_version = Version("0.2.19.0") # DR_mod 的 Rust 编写部分的兼容版本
|
DR_rust_version = Version("0.2.20.2") # DR_mod 的 Rust 编写部分的兼容版本
|
||||||
|
|
||||||
logger = logging.getLogger('client.dr_game')
|
logger = logging.getLogger('client.dr_game')
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
# -------------------------------
|
# -------------------------------
|
||||||
|
|
||||||
# import math
|
# import math
|
||||||
|
import re
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
@ -21,6 +22,7 @@ from pyglet.sprite import Sprite
|
|||||||
# from pyglet.image import Texture
|
# from pyglet.image import Texture
|
||||||
from pyglet.graphics import Batch, Group
|
from pyglet.graphics import Batch, Group
|
||||||
from pyglet.shapes import Line, Rectangle
|
from pyglet.shapes import Line, Rectangle
|
||||||
|
from pyglet.image import Framebuffer, Texture
|
||||||
# pyglet OpenGL
|
# pyglet OpenGL
|
||||||
from pyglet.gl import glViewport
|
from pyglet.gl import glViewport
|
||||||
|
|
||||||
@ -50,12 +52,19 @@ logger.level = logging.DEBUG
|
|||||||
sr_tr = Tr(lang_path=Path(__file__).parent / 'lang')
|
sr_tr = Tr(lang_path=Path(__file__).parent / 'lang')
|
||||||
|
|
||||||
|
|
||||||
class SR1ShipRender_Option(Options): # NOQA
|
class SR1ShipRenderStatus(Options): # NOQA
|
||||||
# debug option
|
name = "SR1ShipRenderStatus"
|
||||||
debug_d_pos: bool = False
|
# main status
|
||||||
debug_mouse_pos: bool = False
|
draw_done: bool = False
|
||||||
debug_mouse_d_pos: bool = False
|
draw_call: bool = False
|
||||||
draw_size: Tuple[int, int] = (100, 100)
|
update_call: bool = False
|
||||||
|
focus: bool = True
|
||||||
|
moving: bool = False
|
||||||
|
|
||||||
|
# debug status
|
||||||
|
draw_d_pos: bool = False
|
||||||
|
draw_mouse_pos: bool = False
|
||||||
|
draw_mouse_d_pos: bool = False
|
||||||
|
|
||||||
|
|
||||||
class SR1ShipRender(BaseScreen):
|
class SR1ShipRender(BaseScreen):
|
||||||
@ -67,16 +76,16 @@ class SR1ShipRender(BaseScreen):
|
|||||||
self.logger = logger
|
self.logger = logger
|
||||||
logger.info(sr_tr().mod.info.setup.start())
|
logger.info(sr_tr().mod.info.setup.start())
|
||||||
load_start_time = time.time_ns()
|
load_start_time = time.time_ns()
|
||||||
self.rendered = False
|
# status
|
||||||
self.focus = True
|
self.status = SR1ShipRenderStatus()
|
||||||
self.need_draw = False
|
|
||||||
self.drawing = False
|
|
||||||
self.need_update_parts = False
|
|
||||||
self.render_option = SR1ShipRender_Option()
|
|
||||||
self.dx = 0
|
self.dx = 0
|
||||||
self.dy = 0
|
self.dy = 0
|
||||||
self.width = main_window.width
|
self.width = main_window.width - 100
|
||||||
self.height = main_window.height
|
self.height = main_window.height - 100
|
||||||
|
self.buffer = Framebuffer()
|
||||||
|
self.render_texture = Texture.create(self.width, self.height)
|
||||||
|
self.buffer.attach_texture(self.render_texture)
|
||||||
|
|
||||||
self.main_batch = Batch()
|
self.main_batch = Batch()
|
||||||
self.part_group = Group(10, parent=main_window.main_group)
|
self.part_group = Group(10, parent=main_window.main_group)
|
||||||
@ -88,10 +97,10 @@ class SR1ShipRender(BaseScreen):
|
|||||||
batch=self.main_batch, group=Group(5, parent=self.part_group))
|
batch=self.main_batch, group=Group(5, parent=self.part_group))
|
||||||
self.render_d_line = Line(0, 0, 0, 0, width=5, color=(200, 200, 10, 255),
|
self.render_d_line = Line(0, 0, 0, 0, width=5, color=(200, 200, 10, 255),
|
||||||
batch=self.main_batch, group=Group(5, parent=self.part_group))
|
batch=self.main_batch, group=Group(5, parent=self.part_group))
|
||||||
self.render_d_line.visible = self.render_option.debug_mouse_d_pos
|
self.render_d_line.visible = self.status.draw_d_pos
|
||||||
self.render_d_label = Label('debug label NODATA', font_name=Fonts.微软等宽无线,
|
self.render_d_label = Label('debug label NODATA', font_name=Fonts.微软等宽无线,
|
||||||
x=main_window.width / 2, y=main_window.height / 2)
|
x=main_window.width / 2, y=main_window.height / 2)
|
||||||
self.render_d_label.visible = self.render_option.debug_d_pos
|
self.render_d_label.visible = self.status.draw_d_pos
|
||||||
self.camera = CenterCamera(main_window, min_zoom=(1 / 2) ** 10, max_zoom=10)
|
self.camera = CenterCamera(main_window, min_zoom=(1 / 2) ** 10, max_zoom=10)
|
||||||
|
|
||||||
# Optional data
|
# Optional data
|
||||||
@ -115,6 +124,18 @@ class SR1ShipRender(BaseScreen):
|
|||||||
load_end_time = time.time_ns()
|
load_end_time = time.time_ns()
|
||||||
logger.info(sr_tr().mod.info.setup.use_time().format((load_end_time - load_start_time) / 1000000000))
|
logger.info(sr_tr().mod.info.setup.use_time().format((load_end_time - load_start_time) / 1000000000))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self) -> Tuple[int, int]:
|
||||||
|
""" 渲染器的渲染大小 """
|
||||||
|
return self.width, self.height
|
||||||
|
|
||||||
|
@size.setter
|
||||||
|
def size(self, value: Tuple[int, int]):
|
||||||
|
if not self.width == value[0] or not self.height == value[1]:
|
||||||
|
self.width, self.height = value
|
||||||
|
self.render_texture = Texture.create(self.width, self.height)
|
||||||
|
self.buffer.attach_texture(self.render_texture)
|
||||||
|
|
||||||
def load_xml(self, file_path: str) -> bool:
|
def load_xml(self, file_path: str) -> bool:
|
||||||
"""
|
"""
|
||||||
加载 xml 文件
|
加载 xml 文件
|
||||||
@ -131,8 +152,9 @@ class SR1ShipRender(BaseScreen):
|
|||||||
logger.info(sr_tr().sr1.ship.xml.load_time().format(
|
logger.info(sr_tr().sr1.ship.xml.load_time().format(
|
||||||
(time.time_ns() - start_time) / 1000000000))
|
(time.time_ns() - start_time) / 1000000000))
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception:
|
||||||
print(e)
|
traceback.print_exc()
|
||||||
|
self.logger.error(traceback.format_exc())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def gen_sprite(self, each_count: int = 100) -> Generator:
|
def gen_sprite(self, each_count: int = 100) -> Generator:
|
||||||
@ -143,7 +165,7 @@ class SR1ShipRender(BaseScreen):
|
|||||||
:return: 生成器
|
:return: 生成器
|
||||||
"""
|
"""
|
||||||
count = 0
|
count = 0
|
||||||
self.drawing = True
|
self.status.draw_done = False
|
||||||
# rust 渲染
|
# rust 渲染
|
||||||
if DR_mod_runtime.use_DR_rust:
|
if DR_mod_runtime.use_DR_rust:
|
||||||
cache = self.rust_ship.as_dict()
|
cache = self.rust_ship.as_dict()
|
||||||
@ -226,72 +248,80 @@ class SR1ShipRender(BaseScreen):
|
|||||||
# if count >= each_count:
|
# if count >= each_count:
|
||||||
# count = 0
|
# count = 0
|
||||||
# yield count
|
# yield count
|
||||||
self.drawing = False
|
self.status.draw_done = True
|
||||||
raise GeneratorExit
|
raise GeneratorExit
|
||||||
|
|
||||||
def render_ship(self):
|
def render_ship(self):
|
||||||
"""
|
"""
|
||||||
渲染船
|
渲染船
|
||||||
"""
|
"""
|
||||||
|
self.status.draw_done = False
|
||||||
logger.info(sr_tr().sr1.ship.ship.load().format(self.ship_name))
|
logger.info(sr_tr().sr1.ship.ship.load().format(self.ship_name))
|
||||||
start_time = time.perf_counter_ns()
|
start_time = time.perf_counter_ns()
|
||||||
self.parts_sprite: Dict[int, Sprite] = {}
|
self.parts_sprite: Dict[int, Sprite] = {}
|
||||||
self.part_line_box = {}
|
self.part_line_box = {}
|
||||||
self.part_line_list = []
|
self.part_line_list = []
|
||||||
# self.camera.zoom = 1.0
|
self.camera.zoom = 1.0
|
||||||
# self.camera.dx = 0
|
self.camera.dx = 0
|
||||||
# self.camera.dy = 0
|
self.camera.dy = 0
|
||||||
# 调用生成器 减少卡顿
|
# 调用生成器 减少卡顿
|
||||||
try:
|
try:
|
||||||
self.gen_draw = self.gen_sprite()
|
self.gen_draw = self.gen_sprite()
|
||||||
next(self.gen_draw)
|
if not self.status.draw_done:
|
||||||
|
next(self.gen_draw)
|
||||||
except (GeneratorExit, StopIteration):
|
except (GeneratorExit, StopIteration):
|
||||||
self.drawing = False
|
self.status.draw_done = True
|
||||||
self.need_draw = False
|
self.status.draw_call = False
|
||||||
full_mass = 0
|
full_mass = 0
|
||||||
if DR_mod_runtime.use_DR_rust:
|
if DR_mod_runtime.use_DR_rust:
|
||||||
full_mass = self.rust_ship.mass
|
full_mass = self.rust_ship.mass
|
||||||
logger.info(sr_tr().sr1.ship.ship.load_time().format(
|
logger.info(sr_tr().sr1.ship.ship.load_time().format(
|
||||||
(time.perf_counter_ns() - start_time) / 1000000000))
|
(time.perf_counter_ns() - start_time) / 1000000000))
|
||||||
logger.info(sr_tr().sr1.ship.ship.info().format(
|
logger.info(sr_tr().sr1.ship.ship.info().format(
|
||||||
len(self.rust_ship.as_list()), f'{full_mass}kg' if DR_mod_runtime.use_DR_rust else sr_tr().game.require_DR_rs()))
|
len(self.rust_ship.as_list()),
|
||||||
self.rendered = True
|
f'{full_mass}kg' if DR_mod_runtime.use_DR_rust else sr_tr().game.require_DR_rs()))
|
||||||
|
|
||||||
def draw_batch(self, window: "ClientWindow"):
|
def draw_batch(self, window: "ClientWindow"):
|
||||||
if self.rendered:
|
if self.status.draw_done:
|
||||||
self.render_d_label.text = f'x: {self.camera.dx} y: {self.camera.dy}'
|
self.render_d_label.text = f'x: {self.camera.dx} y: {self.camera.dy}'
|
||||||
self.render_d_label.position = self.camera.dx + (self.window_pointer.width / 2), self.camera.dy + (
|
self.render_d_label.position = self.camera.dx + (self.window_pointer.width / 2), self.camera.dy + (
|
||||||
self.window_pointer.height / 2) + 10, 0 # 0 for z
|
self.window_pointer.height / 2) + 10, 0 # 0 for z
|
||||||
self.render_d_line.x2 = self.camera.dx
|
self.render_d_line.x2 = self.camera.dx
|
||||||
self.render_d_line.y2 = self.camera.dy
|
self.render_d_line.y2 = self.camera.dy
|
||||||
|
self.buffer.bind()
|
||||||
|
window.clear()
|
||||||
with self.camera:
|
with self.camera:
|
||||||
# glViewport(int(self.camera.dx), int(self.camera.dy), window.width // 2, window.height // 2)
|
# glViewport(int(self.camera.dx), int(self.camera.dy), window.width // 2, window.height // 2)
|
||||||
self.main_batch.draw()
|
self.main_batch.draw()
|
||||||
# glViewport(0, 0, window.width, window.height)
|
# glViewport(0, 0, window.width, window.height)
|
||||||
|
self.buffer.unbind()
|
||||||
|
self.render_texture.blit(x=0, y=0, z=0, width=self.width, height=self.height)
|
||||||
|
|
||||||
def on_draw(self, window: "ClientWindow"):
|
def on_draw(self, window: "ClientWindow"):
|
||||||
if self.need_draw:
|
if self.status.draw_call:
|
||||||
self.render_ship()
|
self.render_ship()
|
||||||
|
|
||||||
if self.drawing:
|
if not self.status.draw_done:
|
||||||
try:
|
try:
|
||||||
next(self.gen_draw)
|
next(self.gen_draw)
|
||||||
except (GeneratorExit, StopIteration):
|
except (GeneratorExit, StopIteration):
|
||||||
self.drawing = False
|
self.status.draw_done = True
|
||||||
self.logger.info(sr_tr().sr1.ship.ship.render.done())
|
self.logger.info(sr_tr().sr1.ship.ship.render.done())
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
self.debug_label.draw()
|
self.debug_label.draw()
|
||||||
|
|
||||||
def on_resize(self, width: int, height: int, window: "ClientWindow"):
|
def on_resize(self, width: int, height: int, window: "ClientWindow"):
|
||||||
self.debug_label.y = height - 100
|
self.debug_label.y = height - 100
|
||||||
if not self.rendered:
|
if not self.status.draw_done:
|
||||||
return
|
return
|
||||||
self.render_d_line.x2 = width // 2
|
self.render_d_line.x2 = width // 2
|
||||||
self.render_d_line.y2 = height // 2
|
self.render_d_line.y2 = height // 2
|
||||||
self.render_option.draw_size = (width, height)
|
self.size = width - 100, height - 100
|
||||||
|
|
||||||
def on_mouse_scroll(self, x: int, y: int, scroll_x: int, scroll_y: int, window: "ClientWindow"):
|
def on_mouse_scroll(self, x: int, y: int, scroll_x: int, scroll_y: int, window: "ClientWindow"):
|
||||||
if not self.rendered:
|
if not self.status.draw_done:
|
||||||
return
|
return
|
||||||
mouse_dx = x - (window.width / 2)
|
mouse_dx = x - (window.width / 2)
|
||||||
mouse_dy = y - (window.height / 2)
|
mouse_dy = y - (window.height / 2)
|
||||||
@ -325,15 +355,16 @@ class SR1ShipRender(BaseScreen):
|
|||||||
self.camera.dy = 0
|
self.camera.dy = 0
|
||||||
self.window_pointer.view = Vec4()
|
self.window_pointer.view = Vec4()
|
||||||
else:
|
else:
|
||||||
self.need_draw = True
|
self.status.draw_call = True
|
||||||
print('应该渲染飞船的')
|
print('应该渲染飞船的')
|
||||||
|
|
||||||
elif command.find('debug'):
|
elif command.find('debug'):
|
||||||
if command.find('delta'):
|
if command.find('delta'):
|
||||||
self.render_d_line.visible = not self.render_d_line.visible
|
self.render_d_line.visible = not self.render_d_line.visible
|
||||||
self.render_option.debug_mouse_d_pos = self.render_d_line.visible
|
self.status.draw_mouse_d_pos = self.render_d_line.visible
|
||||||
self.logger.info(f'sr1 mouse {self.render_option.debug_mouse_d_pos}')
|
self.logger.info(f'sr1 mouse {self.status.draw_mouse_d_pos}')
|
||||||
elif command.find('ship'):
|
elif command.find('ship'):
|
||||||
if self.rendered:
|
if self.status.draw_done:
|
||||||
for index, sprite in self.parts_sprite.items():
|
for index, sprite in self.parts_sprite.items():
|
||||||
sprite.visible = not sprite.visible
|
sprite.visible = not sprite.visible
|
||||||
|
|
||||||
@ -345,8 +376,7 @@ class SR1ShipRender(BaseScreen):
|
|||||||
:param window:
|
:param window:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
from pyglet.gl import GLubyte, GL_RGBA, GL_UNSIGNED_BYTE, \
|
from pyglet.gl import GLubyte, GL_RGBA, GL_UNSIGNED_BYTE, glReadPixels
|
||||||
glReadPixels
|
|
||||||
import pyglet
|
import pyglet
|
||||||
format_str = "RGBA"
|
format_str = "RGBA"
|
||||||
buf = (GLubyte * (len(format_str) * window.width * window.height))()
|
buf = (GLubyte * (len(format_str) * window.width * window.height))()
|
||||||
@ -356,13 +386,13 @@ class SR1ShipRender(BaseScreen):
|
|||||||
image_data = screenshot(self.window_pointer)
|
image_data = screenshot(self.window_pointer)
|
||||||
image_data.save('test.png')
|
image_data.save('test.png')
|
||||||
elif command.find('gen_img'):
|
elif command.find('gen_img'):
|
||||||
if not self.rendered:
|
if not self.status.draw_done:
|
||||||
return
|
return
|
||||||
if not DR_mod_runtime.use_DR_rust:
|
if not DR_mod_runtime.use_DR_rust:
|
||||||
# 这个功能依赖于 DR rs (简称,我懒得在Python端实现)
|
# 这个功能依赖于 DR rs (简称,我懒得在Python端实现)
|
||||||
return
|
return
|
||||||
img_box = self.rust_ship.img_pos
|
img_box = self.rust_ship.img_pos
|
||||||
img_size = (img_box[2] - img_box[0] + 1000, img_box[3] - img_box[1] + 1000)
|
img_size = (img_box[2] - img_box[0], img_box[3] - img_box[1])
|
||||||
# 中心点是左上角坐标
|
# 中心点是左上角坐标
|
||||||
img_center = (abs(img_box[0]), abs(img_box[3]))
|
img_center = (abs(img_box[0]), abs(img_box[3]))
|
||||||
try:
|
try:
|
||||||
@ -372,29 +402,37 @@ class SR1ShipRender(BaseScreen):
|
|||||||
print('PIL not found')
|
print('PIL not found')
|
||||||
return
|
return
|
||||||
img = Image.new('RGBA', img_size)
|
img = Image.new('RGBA', img_size)
|
||||||
for part, sprite in self.parts_sprite.items():
|
part_data = self.rust_ship.as_dict()
|
||||||
sprite_img = sprite.image
|
for part, sprites in self.parts_sprite.items():
|
||||||
print(f"sprite_img: {sprite_img} {sprite_img.width} {sprite_img.height}")
|
for index, sprite in enumerate(sprites):
|
||||||
img_data = sprite_img.get_image_data()
|
sprite_img = sprite.image
|
||||||
fmt = img_data.format
|
print(
|
||||||
if fmt != 'RGB':
|
f"sprite_img: {sprite_img} {part_data[part][index][1].x * 60} {part_data[part][index][1].y * 60}")
|
||||||
fmt = 'RGBA'
|
img_data = sprite_img.get_image_data()
|
||||||
pitch = -(img_data.width * len(fmt))
|
fmt = img_data.format
|
||||||
pil_image = Image.frombytes(fmt, (img_data.width, img_data.height), img_data.get_data(fmt, pitch))
|
if fmt != 'RGB':
|
||||||
pil_image = pil_image.rotate(SR1Rotation.get_rotation(self.part_data[part].angle), expand=True)
|
fmt = 'RGBA'
|
||||||
if self.part_data[part].flip_y:
|
pitch = -(img_data.width * len(fmt))
|
||||||
pil_image.transpose(Image.FLIP_TOP_BOTTOM)
|
pil_image = Image.frombytes(fmt, (img_data.width, img_data.height), img_data.get_data(fmt, pitch))
|
||||||
if self.part_data[part].flip_x:
|
|
||||||
pil_image.transpose(Image.FLIP_LEFT_RIGHT)
|
pil_image = pil_image.rotate(-SR1Rotation.get_rotation(part_data[part][index][1].angle),
|
||||||
img.paste(pil_image, (
|
expand=True)
|
||||||
int(self.part_data[part].x * 60 + img_center[0]),
|
|
||||||
int(-self.part_data[part].y * 60 + img_center[1])),
|
if part_data[part][index][1].flip_y:
|
||||||
pil_image)
|
pil_image.transpose(Image.FLIP_TOP_BOTTOM)
|
||||||
|
if part_data[part][index][1].flip_x:
|
||||||
|
pil_image.transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
|
||||||
|
img.paste(pil_image, (
|
||||||
|
int(part_data[part][index][1].x * 60 + img_center[0]),
|
||||||
|
int(-part_data[part][index][1].y * 60 + img_center[1])))
|
||||||
|
|
||||||
|
img.show("???")
|
||||||
img.save(f'test{time.time()}.png', 'PNG')
|
img.save(f'test{time.time()}.png', 'PNG')
|
||||||
|
|
||||||
elif command.find('test'):
|
elif command.find('test'):
|
||||||
if command.find('save'):
|
if command.find('save'):
|
||||||
if not self.rendered:
|
if not self.status.draw_done:
|
||||||
return
|
return
|
||||||
if not DR_mod_runtime.use_DR_rust:
|
if not DR_mod_runtime.use_DR_rust:
|
||||||
return
|
return
|
||||||
@ -404,21 +442,35 @@ class SR1ShipRender(BaseScreen):
|
|||||||
glViewport(0, 0, 1000, 1000)
|
glViewport(0, 0, 1000, 1000)
|
||||||
|
|
||||||
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"):
|
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"):
|
||||||
if not self.focus:
|
if not self.status.focus:
|
||||||
return
|
return
|
||||||
self.camera.dx += dx
|
self.camera.dx += dx
|
||||||
self.camera.dy += dy
|
self.camera.dy += dy
|
||||||
self.need_update_parts = True
|
self.status.update_call = True
|
||||||
# self.update_parts()
|
|
||||||
|
|
||||||
def on_file_drop(self, x: int, y: int, paths: List[str], window: "ClientWindow"):
|
def on_file_drop(self, x: int, y: int, paths: List[str], window: "ClientWindow"):
|
||||||
for path in paths:
|
if len(paths) > 1:
|
||||||
if self.load_xml(path): # 加载成功一个就停下
|
for path in paths:
|
||||||
break
|
try:
|
||||||
self.render_ship()
|
self.load_xml(path)
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
if Path(paths[0]).is_dir():
|
||||||
|
for path in Path(paths[0]).glob('*.xml'):
|
||||||
|
try:
|
||||||
|
self.load_xml(str(path))
|
||||||
|
except ValueError:
|
||||||
|
traceback.print_exc()
|
||||||
|
if self.load_xml(paths[0]):
|
||||||
|
self.render_ship()
|
||||||
|
# for path in paths:
|
||||||
|
# if self.load_xml(path): # 加载成功一个就停下
|
||||||
|
# break
|
||||||
|
# self.render_ship()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from objprint import op
|
from objprint import op
|
||||||
|
|
||||||
op(SR1ShipRender_Option())
|
op(SR1ShipRenderStatus())
|
||||||
|
Loading…
Reference in New Issue
Block a user