go for group cam

This commit is contained in:
shenjack 2023-08-12 00:28:31 +08:00
parent 7278368b4c
commit 55e83b708f
Signed by: shenjack
GPG Key ID: 7B1134A979775551
6 changed files with 108 additions and 27 deletions

View File

@ -4,9 +4,12 @@
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
from Difficult_Rocket.utils.camera import (Camera, CenterCamera) from Difficult_Rocket.utils.camera import (Camera,
CenterCamera,
GroupCamera)
__all__ = [ __all__ = [
'Camera', 'Camera',
'CenterCamera' 'CenterCamera',
'GroupCamera'
] ]

View File

@ -112,6 +112,7 @@ class BaseScreen(EventDispatcher):
:event: :event:
""" """
# def on_draw(self, dt: float, window: ClientWindow): # TODO: wait for pyglet 2.1
def on_draw(self, window: ClientWindow): def on_draw(self, window: ClientWindow):
"""The window contents must be redrawn. """The window contents must be redrawn.

View File

@ -275,7 +275,10 @@ 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.run(1 / self.main_config['runtime']['fps']) # pyglet.clock.schedule_interval(self.on_draw, float(self.SPF))
# pyglet.app.run()
# TODO: wait for pyglet 2.1
pyglet.app.run(float(self.SPF))
except KeyboardInterrupt: except KeyboardInterrupt:
self.logger.warning("==========client stop. KeyboardInterrupt info==========") self.logger.warning("==========client stop. KeyboardInterrupt info==========")
traceback.print_exc() traceback.print_exc()
@ -314,11 +317,13 @@ class ClientWindow(Window):
self.fps_log.update_tick(now_FPS, decimal_tick) self.fps_log.update_tick(now_FPS, decimal_tick)
@_call_screen_after @_call_screen_after
def on_draw(self, *dt): # def on_draw(self, dt: float): # TODO: wait for pyglet 2.1
def on_draw(self):
while (command := self.game.console.get_command()) is not None: while (command := self.game.console.get_command()) is not None:
self.on_command(line.CommandText(command)) self.on_command(line.CommandText(command))
pyglet.gl.glClearColor(0.1, 0, 0, 0.0) pyglet.gl.glClearColor(0.1, 0, 0, 0.0)
self.clear() self.clear()
# self.draw_update(dt) # TODO: wait for pyglet 2.1
self.draw_update(float(self.SPF)) self.draw_update(float(self.SPF))
self.draw_batch() self.draw_batch()

View File

@ -26,29 +26,25 @@ from pyglet.text.caret import Caret
from pyglet.text.document import UnformattedDocument from pyglet.text.document import UnformattedDocument
from pyglet.text.layout import IncrementalTextLayout from pyglet.text.layout import IncrementalTextLayout
# from libs import pyperclip from Difficult_Rocket.api.types import Fonts
# from libs.pyperclip import paste
from Difficult_Rocket.api.types import FontData, Fonts
# from Difficult_Rocket.client.guis.format import html
from Difficult_Rocket import DR_status from Difficult_Rocket import DR_status
__all__ = ['InputBox']
class TextButton(widgets.WidgetBase): class TextButton(widgets.WidgetBase):
""" """
自带字符的按钮就不用单独做材质了 自带 字符 + 材质 的按钮就不用单独做材质了
""" """
def __init__(self, def __init__(self,
x: int, y: int, width: int, height: int, x: int,
y: int,
width: int,
height: int,
text: str, text: str,
font: str = Fonts.鸿蒙简体, font_size: int = 13): font: str = Fonts.鸿蒙简体, font_size: int = 13):
super().__init__(x, y, width, height) super().__init__(x, y, width, height)
self.text = text self.text = text
self.text_label = Label( self.text_label = Label(font_name=font, font_size=font_size)
font_name=font, font_size=font_size)
@property @property
def value(self): def value(self):

View File

@ -3,11 +3,14 @@
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com # Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
# Huge thanks to pyglet developers # Huge thanks to pyglet developers
from typing import Tuple, Optional from typing import Tuple, Optional
from pyglet.gl import gl
from pyglet.math import Mat4, Vec3
from pyglet.graphics import Group
class Camera: class Camera:
""" """
@ -24,6 +27,7 @@ class Camera:
>>> camera.end() >>> camera.end()
""" """
def __init__(self, def __init__(self,
window, window,
zoom: Optional[float] = 1.0, zoom: Optional[float] = 1.0,
@ -91,8 +95,8 @@ class CenterCamera(Camera):
>>> camera.begin() >>> camera.begin()
>>> window.clear() >>> window.clear()
>>> camera.end() >>> camera.end()
""" """
def begin(self) -> None: def begin(self) -> None:
view = self.window.view view = self.window.view
self._stored_view = view self._stored_view = view
@ -100,6 +104,7 @@ 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
@ -107,3 +112,69 @@ class CenterCamera(Camera):
def end(self) -> None: def end(self) -> None:
self.window.view = self._stored_view self.window.view = self._stored_view
class GroupCamera(Group):
"""
A camera by group
can be used by just added to your widget
"""
def __init__(self,
window,
order: int = 0,
parent: Optional[Group] = None,
view_x: Optional[int] = 0,
view_y: Optional[int] = 0,
zoom: Optional[float] = 1.0, ):
super().__init__(order=order, parent=parent)
self._window = window
self._previous_view = None
self._view_x = view_x
self._view_y = view_y
self._zoom = zoom
self._zoom_x = self._zoom
self._zoom_y = self._zoom
@property
def view_x(self) -> int:
return self._view_x
@view_x.setter
def view_x(self, value: int):
self._view_x = value
@property
def view_y(self) -> int:
return self._view_y
@view_y.setter
def view_y(self, value: int):
self._view_y = value
@property
def zoom(self) -> float:
return self._zoom
@zoom.setter
def zoom(self, value: float):
self._zoom = value
def set_state(self):
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))
# print(f"group translation {view}")
if self._zoom == 1.0:
self._window.view = view
else:
view = view.scale(Vec3(self._zoom, self._zoom, 1))
self._window.view = view
def unset_state(self):
self._window.view = self._previous_view

View File

@ -25,7 +25,7 @@ from . import DR_mod_runtime
# 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 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
@ -38,8 +38,7 @@ if DR_mod_runtime.use_DR_rust:
from .Difficult_Rocket_rs import (SR1PartList_rs, from .Difficult_Rocket_rs import (SR1PartList_rs,
SR1Ship_rs, SR1Ship_rs,
SR1PartData_rs, SR1PartData_rs,
SR1PartType_rs, SR1PartType_rs)
map_ptype_textures)
logger = logging.getLogger('client.dr_game_sr1_ship') logger = logging.getLogger('client.dr_game_sr1_ship')
logger.level = logging.DEBUG logger.level = logging.DEBUG
@ -82,6 +81,8 @@ 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.part_group = Group(0, parent=self.group_camera)
self.part_group = Group(10, parent=main_window.main_group) self.part_group = Group(10, parent=main_window.main_group)
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,
@ -163,10 +164,11 @@ class SR1ShipRender(BaseScreen):
# 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()
part_group = Group(2, parent=self.part_group)
line_box_group = Group(6, parent=self.part_group)
for p_id, parts in cache.items(): for p_id, parts in cache.items():
p_id: int p_id: int
parts: List[Tuple[SR1PartType_rs, SR1PartData_rs]] parts: List[Tuple[SR1PartType_rs, SR1PartData_rs]]
part_group = Group(2, parent=self.part_group)
batch = [] batch = []
for p_type, p_data in parts: for p_type, p_data in parts:
sprite_name = self.part_list_rs.get_part_type(p_data.part_type_id).sprite sprite_name = self.part_list_rs.get_part_type(p_data.part_type_id).sprite
@ -178,7 +180,6 @@ class SR1ShipRender(BaseScreen):
part_sprite.scale_y = -1 if p_data.flip_y else 1 part_sprite.scale_y = -1 if p_data.flip_y else 1
batch.append(part_sprite) batch.append(part_sprite)
line_box_group = Group(6, parent=self.part_group)
part_box = self.rust_ship.get_part_box(p_id) part_box = self.rust_ship.get_part_box(p_id)
if part_box: if part_box:
# 线框 # 线框
@ -285,9 +286,11 @@ class SR1ShipRender(BaseScreen):
window.clear() window.clear()
with self.camera: with self.camera:
self.main_batch.draw() 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)
# def on_draw(self, dt: float, window): # TODO: wait for pyglet 2.1
def on_draw(self, window: "ClientWindow"): def on_draw(self, window: "ClientWindow"):
if self.status.draw_call: if self.status.draw_call:
self.render_ship() self.render_ship()
@ -443,6 +446,8 @@ class SR1ShipRender(BaseScreen):
if self.status.focus: if self.status.focus:
self.camera.dx += dx self.camera.dx += dx
self.camera.dy += dy self.camera.dy += dy
self.group_camera.view_x += dx
self.group_camera.view_y += dy
self.status.update_call = True self.status.update_call = True
elif self.status.moving: elif self.status.moving:
# 如果是在移动整体渲染位置 # 如果是在移动整体渲染位置