Compare commits

...

4 Commits

Author SHA1 Message Date
3595f98dc1
Merge pull request #51 from shenjackyuanjie/feature/group_camera
Feature/group camera
2023-08-12 01:54:22 +08:00
aa8af9ebef
DR sdk 0.8.7.0 2023-08-12 01:49:01 +08:00
692483320b
fetch up with DR 2023-08-12 01:20:24 +08:00
09e386e0fe
CenterGroupCamera! 2023-08-12 00:49:46 +08:00
7 changed files with 104 additions and 46 deletions

View File

@ -10,7 +10,7 @@ from pathlib import Path
from Difficult_Rocket.api.types import Options, Version from Difficult_Rocket.api.types import Options, Version
sdk_version = Version("0.8.6.0") # SDK 版本 sdk_version = Version("0.8.7.0") # SDK 版本
build_version = Version("2.1.3.0") # 编译文件版本(与游戏本体无关) build_version = Version("2.1.3.0") # 编译文件版本(与游戏本体无关)
Api_version = Version("0.1.1.0") # API 版本 Api_version = Version("0.1.1.0") # API 版本
__version__ = sdk_version __version__ = sdk_version

View File

@ -6,10 +6,12 @@
from Difficult_Rocket.utils.camera import (Camera, from Difficult_Rocket.utils.camera import (Camera,
CenterCamera, CenterCamera,
GroupCamera) GroupCamera,
CenterGroupCamera)
__all__ = [ __all__ = [
'Camera', 'Camera',
'CenterCamera', 'CenterCamera',
'GroupCamera' 'GroupCamera',
'CenterGroupCamera'
] ]

View File

@ -73,6 +73,11 @@ class Camera:
def end(self) -> None: def end(self) -> None:
self.window.view = self._stored_view self.window.view = self._stored_view
def reset(self):
self.zoom = 1
self.dx = 0
self.dy = 0
def __enter__(self): def __enter__(self):
self.begin() self.begin()
return self return self
@ -104,7 +109,6 @@ class CenterCamera(Camera):
y = self.window.height / 2.0 / self.zoom + (self.dy / 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.translate((x * self.zoom, y * self.zoom, 0))
# print(f"camera translation {view_matrix}")
view_matrix = view_matrix.scale((self.zoom, self.zoom, 1)) view_matrix = view_matrix.scale((self.zoom, self.zoom, 1))
self.window.view = view_matrix self.window.view = view_matrix
@ -125,7 +129,9 @@ class GroupCamera(Group):
parent: Optional[Group] = None, parent: Optional[Group] = None,
view_x: Optional[int] = 0, view_x: Optional[int] = 0,
view_y: Optional[int] = 0, view_y: Optional[int] = 0,
zoom: Optional[float] = 1.0, ): zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0):
super().__init__(order=order, parent=parent) super().__init__(order=order, parent=parent)
self._window = window self._window = window
self._previous_view = None self._previous_view = None
@ -135,6 +141,8 @@ class GroupCamera(Group):
self._zoom = zoom self._zoom = zoom
self._zoom_x = self._zoom self._zoom_x = self._zoom
self._zoom_y = self._zoom self._zoom_y = self._zoom
self.min_zoom = min_zoom
self.max_zoom = max_zoom
@property @property
def view_x(self) -> int: def view_x(self) -> int:
@ -159,17 +167,18 @@ class GroupCamera(Group):
@zoom.setter @zoom.setter
def zoom(self, value: float): def zoom(self, value: float):
self._zoom = value self._zoom = value
self._zoom_x = self._zoom
self._zoom_y = self._zoom
def reset(self):
self._view_x = 0
self._view_y = 0
self.zoom = 1
def set_state(self): def set_state(self):
self._previous_view = self._window.view self._previous_view = self._window.view
# print(self._previous_view)
x = self._window.width / 2.0 / self._zoom_x + (self._view_x / self._zoom_x)
y = self._window.height / 2.0 / self._zoom_y + (self._view_y / self._zoom_y)
# view = Mat4.from_translation(Vec3(self._view_x * x, self._view_y * y, 0))
view = Mat4.from_translation(Vec3(self._view_x, self._view_y, 0)) view = Mat4.from_translation(Vec3(self._view_x, self._view_y, 0))
# print(f"group translation {view}")
if self._zoom == 1.0: if self._zoom == 1.0:
self._window.view = view self._window.view = view
else: else:
@ -178,3 +187,27 @@ class GroupCamera(Group):
def unset_state(self): def unset_state(self):
self._window.view = self._previous_view self._window.view = self._previous_view
class CenterGroupCamera(GroupCamera):
"""
A camera by group
can be used by just added to your widget
"""
def set_state(self):
self._previous_view = self._window.view
x = (self._window.width / 2) / self._zoom_x + (self._view_x / self._zoom_x)
y = (self._window.height / 2) / self._zoom_y + (self._view_y / self._zoom_y)
view = Mat4.from_translation(Vec3(x * self._zoom_x, y * self._zoom_y, 0))
# 不懂就问 为啥这里 * zoom 下面还 * zoom
if self._zoom == 1.0 and self._zoom_x == 1.0 and self._zoom_y == 1.0:
self._window.view = view
else:
view = view.scale(Vec3(self._zoom_x, self._zoom_y, 1))
self._window.view = view
def unset_state(self):
self._window.view = self._previous_view

View File

@ -2,9 +2,16 @@
# DR game/DR rs 更新日志 # DR game/DR rs 更新日志
- 最新版本号 - 最新版本号
- DR game: 0.3.2.1 - DR game: 0.3.3.0
- DR rs: 0.2.21.0 - DR rs: 0.2.21.0
## 20230812 DR game 0.3.3.0
### Changes
- 将 `sr1_ship` 渲染器使用的 Camera 改成 `CenterGroupCamera`
- 删除了之前的 Camera 相关代码
## 20230809 DR game 0.3.2.1 ## 20230809 DR game 0.3.2.1
### Fix ### Fix

View File

@ -2,7 +2,30 @@
# DR SDK 更新日志 # DR SDK 更新日志
- 最新版本号 - 最新版本号
- DR sdk: 0.8.6.0 - DR sdk: 0.8.7.0
- DR api: 0.1.1.0
## DR sdk 0.8.7.0
### Add
- 添加了 `Difficult_Rocket.utils.camera.GroupCamera`
- 和 `Difficult_Rocket.utils.camera.CenterGroupCamera`
- 实际上就是使用 `pyglet.graphics.Group` 来实现的 `Camera`
- 具有相同的功能
- 顺便同样在 `api.camera` 里添加了导出
- 这次我一定不会再忘记导出了
- Added `Difficult_Rocket.utils.camera.GroupCamera`
- And `Difficult_Rocket.utils.camera.CenterGroupCamera`
- Actually, it is implemented `Camera` using `pyglet.graphics.Group`
- Has the same function
- By the way, the export was also added in `api.camera`
- This time I will never forget to export it again
- 为所有 `xxCamera` 添加了
- `reset` 方法
- 用于一键重置缩放+平移
- Added `reset` method for all `xxCamera`
- Used to reset zoom + translation with one click
## DR sdk 0.8.6.1 ## DR sdk 0.8.6.1

View File

@ -53,7 +53,7 @@ DR_mod_runtime = _DR_mod_runtime()
class DR_mod(ModInfo): # NOQA class DR_mod(ModInfo): # NOQA
mod_id = "difficult_rocket_mod" mod_id = "difficult_rocket_mod"
name = "Difficult Rocket mod" name = "Difficult Rocket mod"
version = Version("0.3.2.1") version = Version("0.3.3.0")
writer = "shenjackyuanjie" writer = "shenjackyuanjie"
link = "shenjack.top" link = "shenjack.top"

View File

@ -10,26 +10,25 @@ import logging
import traceback import traceback
from pathlib import Path from pathlib import Path
from typing import List, TYPE_CHECKING, Union, Dict, Optional, Generator, Tuple from typing import List, TYPE_CHECKING, Dict, Optional, Generator, Tuple
from pyglet.math import Vec4 from pyglet.math import Vec4
from pyglet.text import Label from pyglet.text import Label
from pyglet.sprite import Sprite from pyglet.sprite import Sprite
# 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 from pyglet.image import Framebuffer, Texture
from . import DR_mod_runtime from . import DR_mod_runtime
from .types import SR1Textures, SR1Rotation
# Difficult Rocket # Difficult Rocket
from Difficult_Rocket import DR_status from Difficult_Rocket import DR_status
from Difficult_Rocket.utils.translate import Tr from Difficult_Rocket.utils.translate import Tr
from Difficult_Rocket.api.camera import CenterCamera, GroupCamera
from Difficult_Rocket.api.types import Fonts, Options from Difficult_Rocket.api.types import Fonts, Options
from Difficult_Rocket.command.line import CommandText from Difficult_Rocket.command.line import CommandText
from Difficult_Rocket.client.screen import BaseScreen from Difficult_Rocket.client.screen import BaseScreen
from .types import SR1Textures, SR1Rotation from Difficult_Rocket.api.camera import CenterGroupCamera
if TYPE_CHECKING: if TYPE_CHECKING:
from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.client import ClientWindow
@ -81,9 +80,12 @@ class SR1ShipRender(BaseScreen):
self.buffer.attach_texture(self.render_texture) self.buffer.attach_texture(self.render_texture)
self.main_batch = Batch() self.main_batch = Batch()
# self.group_camera = GroupCamera(window=main_window, order=10, parent=main_window.main_group) self.group_camera = CenterGroupCamera(window=main_window,
# self.part_group = Group(0, parent=self.group_camera) order=10,
self.part_group = Group(10, parent=main_window.main_group) parent=main_window.main_group,
min_zoom=(1 / 2) ** 10,
max_zoom=10)
self.part_group = Group(0, parent=self.group_camera)
self.debug_label = Label(x=20, y=main_window.height - 100, font_size=DR_status.std_font_size, self.debug_label = Label(x=20, y=main_window.height - 100, font_size=DR_status.std_font_size,
text='SR1 render!', font_name=Fonts.微软等宽无线, text='SR1 render!', font_name=Fonts.微软等宽无线,
@ -96,7 +98,6 @@ class SR1ShipRender(BaseScreen):
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.status.draw_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)
# Optional data # Optional data
self.textures: SR1Textures = SR1Textures() self.textures: SR1Textures = SR1Textures()
@ -255,9 +256,7 @@ class SR1ShipRender(BaseScreen):
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.group_camera.reset()
self.camera.dx = 0
self.camera.dy = 0
# 调用生成器 减少卡顿 # 调用生成器 减少卡顿
try: try:
self.gen_draw = self.gen_sprite() self.gen_draw = self.gen_sprite()
@ -277,16 +276,14 @@ class SR1ShipRender(BaseScreen):
def draw_batch(self, window: "ClientWindow"): def draw_batch(self, window: "ClientWindow"):
if self.status.draw_done: 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.group_camera.view_x} y: {self.group_camera.view_y}'
self.render_d_label.position = self.camera.dx + (self.window_pointer.width / 2), self.camera.dy + ( self.render_d_label.position = self.group_camera.view_x + (self.window_pointer.width / 2), self.group_camera.view_y + (
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.group_camera.view_x
self.render_d_line.y2 = self.camera.dy self.render_d_line.y2 = self.group_camera.view_y
self.buffer.bind() self.buffer.bind()
window.clear() window.clear()
with self.camera: self.main_batch.draw() # use group camera, no need to with
self.main_batch.draw()
# self.main_batch.draw() # use group camera, no need to with
self.buffer.unbind() self.buffer.unbind()
self.render_texture.blit(x=self.dx, y=self.dy, z=0, width=self.width, height=self.height) self.render_texture.blit(x=self.dx, y=self.dy, z=0, width=self.width, height=self.height)
@ -320,24 +317,24 @@ class SR1ShipRender(BaseScreen):
mouse_dx = x - (window.width / 2) mouse_dx = x - (window.width / 2)
mouse_dy = y - (window.height / 2) mouse_dy = y - (window.height / 2)
# 鼠标缩放位置相对于屏幕中心的位置 # 鼠标缩放位置相对于屏幕中心的位置
mouse_dx_d = mouse_dx - self.camera.dx mouse_dx_d = mouse_dx - self.group_camera.view_x
mouse_dy_d = mouse_dy - self.camera.dy mouse_dy_d = mouse_dy - self.group_camera.view_y
# 鼠标相对偏移量的偏移量 # 鼠标相对偏移量的偏移量
if scroll_y == 0: if scroll_y == 0:
zoom_d = 1 zoom_d = 1
else: else:
zoom_d = ((2 ** scroll_y) - 1) * 0.5 + 1 zoom_d = ((2 ** scroll_y) - 1) * 0.5 + 1
# 缩放的变换量 # 缩放的变换量
if not (self.camera.zoom == 10 and scroll_y > 0): if not (self.group_camera.zoom == 10 and scroll_y > 0):
if self.camera.zoom * zoom_d >= 10: if self.group_camera.zoom * zoom_d >= 10:
zoom_d = 10 / self.camera.zoom zoom_d = 10 / self.group_camera.zoom
self.camera.zoom = 10 self.group_camera.zoom = 10
else: else:
self.camera.zoom *= zoom_d self.group_camera.zoom *= zoom_d
mouse_dx_d *= (1 - zoom_d) mouse_dx_d *= (1 - zoom_d)
mouse_dy_d *= (1 - zoom_d) mouse_dy_d *= (1 - zoom_d)
self.camera.dx += mouse_dx_d self.group_camera.view_x += mouse_dx_d
self.camera.dy += mouse_dy_d self.group_camera.view_y += mouse_dy_d
elif self.status.moving: elif self.status.moving:
# 如果是在移动整体渲染位置 # 如果是在移动整体渲染位置
size_x, size_y = self.size size_x, size_y = self.size
@ -354,9 +351,7 @@ class SR1ShipRender(BaseScreen):
self.logger.info(f'command: {command}') self.logger.info(f'command: {command}')
if command.find('render'): if command.find('render'):
if command.find('reset'): if command.find('reset'):
self.camera.zoom = 1 self.group_camera.reset()
self.camera.dx = 0
self.camera.dy = 0
self.window_pointer.view = Vec4() self.window_pointer.view = Vec4()
else: else:
self.status.draw_call = True self.status.draw_call = True
@ -444,8 +439,6 @@ class SR1ShipRender(BaseScreen):
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 self.status.focus: if self.status.focus:
self.camera.dx += dx
self.camera.dy += dy
self.group_camera.view_x += dx self.group_camera.view_x += dx
self.group_camera.view_y += dy self.group_camera.view_y += dy
self.status.update_call = True self.status.update_call = True