feat: main project update

This commit is contained in:
shenjack 2022-12-25 23:15:49 +08:00
parent 161594e627
commit af08153b86
9 changed files with 590 additions and 451 deletions

View File

@ -38,11 +38,12 @@ class DR_option(Options):
use_cProfile: bool = False
use_local_logging: bool = False
report_translate_no_found: bool = True
use_muitprocess: bool = False
# tests
playing: bool = False
debugging: bool = False
crash_report_test: bool = True
crash_report_test: bool = False
# window option
gui_scale: int = 1 # default 1 2 -> 2x 3 -> 3x
@ -58,7 +59,8 @@ class _DR_runtime(Options):
DR_long_version: int = long_version
# run status
start_time_ns: int = None
running: bool = False
start_time_ns: int = None
client_setup_cause_ns: int = None
server_setup_cause_ns: int = None

View File

@ -0,0 +1,430 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2021-2022 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
import typing
from typing import List
# from pyglet.window import Window
from pyglet.event import EventDispatcher
# Difficult Rocket function
if typing.TYPE_CHECKING:
from Difficult_Rocket.client import ClientWindow
class BaseScreen(EventDispatcher):
"""
DR 页面API
"""
def __init__(self, main_window: "ClientWindow"):
super().__init__()
self.window_pointer = main_window
if typing.TYPE_CHECKING:
def on_key_press(self, symbol: int, modifiers: int):
"""一个键盘按键被按下
:param:
`symbol` : int
按下按键的标识符
`modifiers` : int
每一位(二进制)表示一个修饰键的启用情况
"""
def on_key_release(self, symbol: int, modifiers: int):
"""一个键盘按键被松开
:param:
`symbol` : int
放下按键的标识符
`modifiers` : int
每一位(二进制)表示一个修饰键的启用情况
"""
def on_text(self, text: str):
"""用户输入了一个字符
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is held down (key repeating); or called without key presses if
another input method was used (e.g., a pen input).
You should always use this method for interpreting text, as the
key symbols often have complex mappings to their unicode
representation which this event takes care of.
:param:
`text` : unicode
用户输入的 unicode 编码的内容
"""
def on_text_motion(self, motion: int):
"""The user moved the text input cursor.
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is help down (key repeating).
You should always use this method for moving the text input cursor
(caret), as different platforms have different default keyboard
mappings, and key repeats are handled correctly.
The values that `motion` can take are defined in
:py:mod:`pyglet.window.key`:
* MOTION_UP
* MOTION_RIGHT
* MOTION_DOWN
* MOTION_LEFT
* MOTION_NEXT_WORD
* MOTION_PREVIOUS_WORD
* MOTION_BEGINNING_OF_LINE
* MOTION_END_OF_LINE
* MOTION_NEXT_PAGE
* MOTION_PREVIOUS_PAGE
* MOTION_BEGINNING_OF_FILE
* MOTION_END_OF_FILE
* MOTION_BACKSPACE
* MOTION_DELETE
:param:
`motion` : int
The direction of motion; see remarks.
"""
def on_text_motion_select(self, motion: int):
"""The user moved the text input cursor while extending the
selection.
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is help down (key repeating).
You should always use this method for responding to text selection
events rather than the raw :py:meth:`~pyglet.window.Window.on_key_press`, as different platforms
have different default keyboard mappings, and key repeats are
handled correctly.
The values that `motion` can take are defined in :py:mod:`pyglet.window.key`:
* MOTION_UP
* MOTION_RIGHT
* MOTION_DOWN
* MOTION_LEFT
* MOTION_NEXT_WORD
* MOTION_PREVIOUS_WORD
* MOTION_BEGINNING_OF_LINE
* MOTION_END_OF_LINE
* MOTION_NEXT_PAGE
* MOTION_PREVIOUS_PAGE
* MOTION_BEGINNING_OF_FILE
* MOTION_END_OF_FILE
:param:
`motion` : int
The direction of selection motion; see remarks.
"""
def on_mouse_motion(self, x: int, y: int, dx: int, dy: int):
"""The mouse was moved with no buttons held down.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`dx` : int
Relative X position from the previous mouse position.
`dy` : int
Relative Y position from the previous mouse position.
"""
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int):
"""The mouse was moved with one or more mouse buttons pressed.
This event will continue to be fired even if the mouse leaves
the window, so long as the drag buttons are continuously held down.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`dx` : int
Relative X position from the previous mouse position.
`dy` : int
Relative Y position from the previous mouse position.
`buttons` : int
Bitwise combination of the mouse buttons currently pressed.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_press(self, x: int, y: int, button: int, modifiers: int):
"""A mouse button was pressed (and held down).
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`button` : int
The mouse button that was pressed.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int):
"""A mouse button was released.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`button` : int
The mouse button that was released.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_scroll(self, x: int, y: int, scroll_x: int, scroll_y: int):
"""The mouse wheel was scrolled.
Note that most mice have only a vertical scroll wheel, so
`scroll_x` is usually 0. An exception to this is the Apple Mighty
Mouse, which has a mouse ball in place of the wheel which allows
both `scroll_x` and `scroll_y` movement.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`scroll_x` : float
Amount of movement on the horizontal axis.
`scroll_y` : float
Amount of movement on the vertical axis.
"""
def on_close(self):
"""The user attempted to close the window.
This event can be triggered by clicking on the "X" control box in
the window title bar, or by some other platform-dependent manner.
The default handler sets `has_exit` to ``True``. In pyglet 1.1, if
`pyglet.app.event_loop` is being used, `close` is also called,
closing the window immediately.
"""
def on_mouse_enter(self, x: int, y: int):
"""The mouse was moved into the window.
This event will not be triggered if the mouse is currently being
dragged.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
"""
def on_mouse_leave(self, x: int, y: int):
"""The mouse was moved outside of the window.
This event will not be triggered if the mouse is currently being
dragged. Note that the coordinates of the mouse pointer will be
outside of the window rectangle.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
"""
def on_expose(self):
"""A portion of the window needs to be redrawn.
This event is triggered when the window first appears, and any time
the contents of the window is invalidated due to another window
obscuring it.
There is no way to determine which portion of the window needs
redrawing. Note that the use of this method is becoming
increasingly uncommon, as newer window managers composite windows
automatically and keep a backing store of the window contents.
"""
def on_resize(self, width: int, height: int):
"""The window was resized.
The window will have the GL context when this event is dispatched;
there is no need to call `switch_to` in this handler.
:param:
`width` : int
The new width of the window, in pixels.
`height` : int
The new height of the window, in pixels.
"""
def on_move(self, x: int, y: int):
"""The window was moved.
:param:
`x` : int
Distance from the left edge of the screen to the left edge
of the window.
`y` : int
Distance from the top edge of the screen to the top edge of
the window. Note that this is one of few methods in pyglet
which use a Y-down coordinate system.
"""
def on_activate(self):
"""The window was activated.
This event can be triggered by clicking on the title bar, bringing
it to the foreground; or by some platform-specific method.
When a window is "active" it has the keyboard focus.
"""
def on_deactivate(self):
"""The window was deactivated.
This event can be triggered by clicking on another application
window. When a window is deactivated it no longer has the
keyboard focus.
"""
def on_show(self):
"""The window was shown.
This event is triggered when a window is restored after being
minimised, hidden, or after being displayed for the first time.
"""
def on_hide(self):
"""The window was hidden.
This event is triggered when a window is minimised
or hidden by the user.
"""
def on_context_lost(self):
"""The window's GL context was lost.
When the context is lost no more GL methods can be called until it
is recreated. This is a rare event, triggered perhaps by the user
switching to an incompatible video mode. When it occurs, an
application will need to reload all objects (display lists, texture
objects, shaders) as well as restore the GL state.
"""
def on_context_state_lost(self):
"""The state of the window's GL context was lost.
pyglet may sometimes need to recreate the window's GL context if
the window is moved to another video device, or between fullscreen
or windowed mode. In this case it will try to share the objects
(display lists, texture objects, shaders) between the old and new
contexts. If this is possible, only the current state of the GL
context is lost, and the application should simply restore state.
"""
def on_file_drop(self, x: int, y: int, paths: List[str]):
"""File(s) were dropped into the window, will return the position of the cursor and
a list of paths to the files that were dropped.
"""
def on_draw(self):
"""The window contents must be redrawn.
The `EventLoop` will dispatch this event when the window
should be redrawn. This will happen during idle time after
any window events and after any scheduled functions were called.
The window will already have the GL context, so there is no
need to call `switch_to`. The window's `flip` method will
be called after this event, so your event handler should not.
You should make no assumptions about the window contents when
this event is triggered; a resize or expose event may have
invalidated the framebuffer since the last time it was drawn.
"""
def on_refresh(self):
"""The window contents must be redrawn.
The `EventLoop` will dispatch this event when the window
should be redrawn.
The window will already have the GL context, so there is no
need to call `switch_to`. The window's `flip` method will
be called after this event, so your event handler should not.
You should make no assumptions about the window contents when
this event is triggered; a resize or expose event may have
invalidated the framebuffer since the last time it was drawn.
"""
def on_command(self, command):
"""
:param command:
:return:
"""
def on_message(self, message):
"""
:param message:
:return:
"""
BaseScreen.register_event_type('on_key_press')
BaseScreen.register_event_type('on_key_release')
BaseScreen.register_event_type('on_text')
BaseScreen.register_event_type('on_text_motion')
BaseScreen.register_event_type('on_text_motion_select')
BaseScreen.register_event_type('on_mouse_motion')
BaseScreen.register_event_type('on_mouse_drag')
BaseScreen.register_event_type('on_mouse_press')
BaseScreen.register_event_type('on_mouse_release')
BaseScreen.register_event_type('on_mouse_scroll')
BaseScreen.register_event_type('on_mouse_enter')
BaseScreen.register_event_type('on_mouse_leave')
BaseScreen.register_event_type('on_close')
BaseScreen.register_event_type('on_expose')
BaseScreen.register_event_type('on_resize')
BaseScreen.register_event_type('on_move')
BaseScreen.register_event_type('on_activate')
BaseScreen.register_event_type('on_deactivate')
BaseScreen.register_event_type('on_show')
BaseScreen.register_event_type('on_hide')
BaseScreen.register_event_type('on_context_lost')
BaseScreen.register_event_type('on_context_state_lost')
BaseScreen.register_event_type('on_file_drop')
BaseScreen.register_event_type('on_draw')
BaseScreen.register_event_type('on_refresh')

View File

@ -10,14 +10,15 @@ mail: 3695888@qq.com
github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
import inspect
# system function
import os
import time
import logging
import functools
import traceback
from typing import List, Union
from typing import List, Callable, Union
from decimal import Decimal
# third function
@ -30,11 +31,10 @@ from pyglet.window import Window
from pyglet.window import key, mouse
# Difficult_Rocket function
from Difficult_Rocket import Options, DR_runtime
from Difficult_Rocket import DR_runtime
from Difficult_Rocket.command import line, tree
from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.client.screen import DRScreen
from Difficult_Rocket.client.screen import DRDEBUGScreen
from Difficult_Rocket.client.screen import BaseScreen, DRScreen, DRDEBUGScreen
from Difficult_Rocket.utils import tools, translate
from Difficult_Rocket.utils.new_thread import new_thread
from Difficult_Rocket.client.fps.fps_log import FpsLogger
@ -54,7 +54,8 @@ class Client:
self.process_name = 'Client process'
self.process_pid = os.getpid()
self.net_mode = net_mode
self.caption = tools.name_handler(self.config['window']['caption'], {'version': self.config['runtime']['version']})
self.caption = tools.name_handler(self.config['window']['caption'],
{'version': self.config['runtime']['version']})
self.window = ClientWindow(net_mode=self.net_mode,
width=int(self.config['window']['width']),
height=int(self.config['window']['height']),
@ -83,8 +84,30 @@ def pyglet_load_fonts_folder(folder) -> None:
pyglet_load_fonts_folder(os.path.join(folder, obj))
# class _DR_Client_option(Options):
# ...
def _call_screen_after(func: Callable) -> Callable:
@functools.wraps(func)
def warped(self, *args, **kwargs):
result = func(self, *args, **kwargs)
for a_screen in self.screen_list:
if hasattr(a_screen, func.__name__):
getattr(a_screen, func.__name__)(*args, **kwargs)
return result
warped.__signature__ = inspect.signature(func)
return warped
def _call_screen_before(func: Callable) -> Callable:
@functools.wraps(func)
def warped(self, *args, **kwargs):
for a_screen in self.screen_list:
if hasattr(a_screen, func.__name__):
getattr(a_screen, func.__name__)(*args, **kwargs)
result = func(self, *args, **kwargs)
return result
warped.__signature__ = inspect.signature(func)
return warped
class ClientWindow(Window):
@ -117,7 +140,6 @@ class ClientWindow(Window):
# frame
self.frame = pyglet.gui.Frame(self, order=20)
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
# self.DRscreen = DRScreen(self)
self.screen_list = []
# setup
self.setup()
@ -128,13 +150,6 @@ class ClientWindow(Window):
batch=self.label_batch) # 实例化
self.push_handlers(self.input_box)
self.input_box.enabled = True
# fps显示
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
width=self.width - 20, height=20,
anchor_x='left', anchor_y='top',
font_name=translate.微软等宽无线, font_size=20,
multiline=True,
batch=self.label_batch, group=self.command_group)
# 设置刷新率
pyglet.clock.schedule_interval(self.draw_update, float(self.SPF))
# 完成设置后的信息输出
@ -149,7 +164,6 @@ class ClientWindow(Window):
def setup(self):
self.load_fonts()
from Difficult_Rocket.client.screen import DRDEBUGScreen, DRScreen, BaseScreen
self.screen_list: List[BaseScreen]
self.screen_list.append(DRDEBUGScreen(self))
self.screen_list.append(DRScreen(self))
@ -197,38 +211,39 @@ class ClientWindow(Window):
draws and some event
"""
@_call_screen_after
def draw_update(self, tick: float):
decimal_tick = Decimal(str(tick)[:10])
self.FPS_update(decimal_tick)
def FPS_update(self, tick: Decimal):
now_FPS = pyglet.clock.get_frequency()
self.fps_log.update_tick(now_FPS, tick)
self.fps_label.text = f'FPS: {self.fps_log.fps: >5.1f}({self.fps_log.middle_fps: >5.1f})[{now_FPS: >.7f}]\n {self.fps_log.max_fps: >7.1f} {self.fps_log.min_fps:>5.1f}'
self.fps_log.update_tick(now_FPS, decimal_tick)
@_call_screen_after
def on_draw(self, *dt):
# self.logger.debug('on_draw call dt: {}'.format(dt))
pyglet.gl.glClearColor(0.1, 0, 0, 0.0)
self.clear()
self.draw_batch()
@_call_screen_after
def on_resize(self, width: int, height: int):
super().on_resize(width, height)
self.fps_label.y = height - 10
@_call_screen_after
def on_refresh(self, dt):
...
@_call_screen_after
def on_show(self):
# HWND_TOPMOST = -1
# _user32.SetWindowPos(self._hwnd, HWND_TOPMOST, 0, 0, self.width, self.height, 0)
...
@_call_screen_after
def on_hide(self):
# self.set_location(*self.get_location())
print('on hide!')
@_call_screen_after
def draw_batch(self):
self.part_batch.draw()
self.label_batch.draw()
@ -237,11 +252,12 @@ class ClientWindow(Window):
command line event
"""
@_call_screen_after
def on_command(self, command: line.CommandText):
self.logger.info(tr.lang('window', 'command.text').format(command))
if command.match('stop'):
self.dispatch_event('on_exit')
# platform_event_loop.stop()
# self.dispatch_event('on_exit')
pyglet.app.platform_event_loop.stop()
self.dispatch_event('on_close', 'command') # source = command
elif command.match('fps'):
if command.match('log'):
@ -253,9 +269,11 @@ class ClientWindow(Window):
self.logger.info(self.fps_log.min_fps)
self.command.push_line(self.fps_log.min_fps, block_line=True)
elif command.match('default'):
self.set_size(int(self.main_config['window_default']['width']), int(self.main_config['window_default']['height']))
self.set_size(int(self.main_config['window_default']['width']),
int(self.main_config['window_default']['height']))
self.command_tree.parse(command.plain_command)
@_call_screen_after
def on_message(self, message: line.CommandLine.text):
self.logger.info(tr.lang('window', 'message.text').format(message))
@ -263,31 +281,51 @@ class ClientWindow(Window):
keyboard and mouse input
"""
def activate(self):
@_call_screen_after
def on_activate(self):
super().activate()
@_call_screen_after
def on_deactivate(self):
...
@_call_screen_after
def on_mouse_motion(self, x, y, dx, dy) -> None:
pass
@_call_screen_after
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers) -> None:
pass
@_call_screen_after
def on_mouse_press(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.press').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
self.logger.debug(tr.lang('window', 'mouse.press').format([x, y], tr.lang('window', 'mouse.{}'.format(
mouse.buttons_string(button)))))
@_call_screen_after
def on_mouse_release(self, x, y, button, modifiers) -> None:
self.logger.debug(tr.lang('window', 'mouse.release').format([x, y], tr.lang('window', 'mouse.{}'.format(mouse.buttons_string(button)))))
self.logger.debug(tr.lang('window', 'mouse.release').format([x, y], tr.lang('window', 'mouse.{}'.format(
mouse.buttons_string(button)))))
@_call_screen_after
def on_key_press(self, symbol, modifiers) -> None:
if symbol == key.ESCAPE and not (modifiers & ~(key.MOD_NUMLOCK |
key.MOD_CAPSLOCK |
key.MOD_SCROLLLOCK)):
self.dispatch_event('on_close')
self.logger.debug(tr.lang('window', 'key.press').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
self.logger.debug(
tr.lang('window', 'key.press').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
@_call_screen_after
def on_key_release(self, symbol, modifiers) -> None:
self.logger.debug(tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
self.logger.debug(
tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers)))
@_call_screen_after
def on_file_drop(self, x, y, paths):
...
@_call_screen_after
def on_text(self, text):
if text == '\r':
self.logger.debug(tr.lang('window', 'text.new_line'))
@ -296,18 +334,22 @@ class ClientWindow(Window):
if text == 't':
self.input_box.enabled = True
@_call_screen_after
def on_text_motion(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion').format(motion_string))
@_call_screen_after
def on_text_motion_select(self, motion):
motion_string = key.motion_string(motion)
self.logger.debug(tr.lang('window', 'text.motion_select').format(motion_string))
@_call_screen_before
def on_close(self, source: str = 'window') -> None:
self.logger.info(tr.lang('window', 'game.stop_get').format(tr.lang('window', f'game.{source}_stop')))
self.logger.info(tr.lang('window', 'game.stop'))
self.fps_log.check_list = False
DR_runtime.running = False
if self.run_input:
self.run_input = False
self.save_info()

View File

@ -5,8 +5,32 @@
# -------------------------------
# third party package
from defusedxml.ElementTree import parse
from defusedxml.ElementTree import DefusedXMLParser
# pyglet
from pyglet.graphics import Batch
from pyglet.resource import texture
# Difficult Rocket
from Difficult_Rocket.client.screen import BaseScreen
from client.screen import BaseScreen
from Difficult_Rocket.client import ClientWindow
class SR1ShipRender(BaseScreen):
"""用于渲染 sr1 船的类"""
def __init__(self, x: float, y: float,
scale: float,
xml_doc: DefusedXMLParser,
main_window: "ClientWindow"):
super().__init__(main_window)
self.x, self.y = x, y
self.scale = scale
self.xml_doc = xml_doc
self.part_batch = Batch()
def on_draw(self):
...
def on_command(self, command):
...

View File

@ -6,412 +6,19 @@
import typing
from pyglet.window import Window
from pyglet.event import EventDispatcher
from pyglet.text import Label
from pyglet.graphics import Batch, Group
from pyglet.clock import get_frequency
# Difficult Rocket function
from Difficult_Rocket.utils import translate
from Difficult_Rocket.api.screen import BaseScreen
from Difficult_Rocket.command.tree import CommandTree
if typing.TYPE_CHECKING:
from Difficult_Rocket.client import ClientWindow
class BaseScreen(EventDispatcher):
"""
DR 页面API
"""
def __init__(self, main_window: "ClientWindow"):
super().__init__()
self.window_pointer = main_window
def on_key_press(self, symbol, modifiers):
"""一个键盘按键被按下
:param:
`symbol` : int
按下按键的标识符
`modifiers` : int
每一位(二进制)表示一个修饰键的启用情况
"""
def on_key_release(self, symbol, modifiers):
"""一个键盘按键被松开
:param:
`symbol` : int
放下按键的标识符
`modifiers` : int
每一位(二进制)表示一个修饰键的启用情况
"""
def on_text(self, text):
"""用户输入了一个字符
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is held down (key repeating); or called without key presses if
another input method was used (e.g., a pen input).
You should always use this method for interpreting text, as the
key symbols often have complex mappings to their unicode
representation which this event takes care of.
:param:
`text` : unicode
用户输入的 unicode 编码的内容
"""
def on_text_motion(self, motion):
"""The user moved the text input cursor.
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is help down (key repeating).
You should always use this method for moving the text input cursor
(caret), as different platforms have different default keyboard
mappings, and key repeats are handled correctly.
The values that `motion` can take are defined in
:py:mod:`pyglet.window.key`:
* MOTION_UP
* MOTION_RIGHT
* MOTION_DOWN
* MOTION_LEFT
* MOTION_NEXT_WORD
* MOTION_PREVIOUS_WORD
* MOTION_BEGINNING_OF_LINE
* MOTION_END_OF_LINE
* MOTION_NEXT_PAGE
* MOTION_PREVIOUS_PAGE
* MOTION_BEGINNING_OF_FILE
* MOTION_END_OF_FILE
* MOTION_BACKSPACE
* MOTION_DELETE
:param:
`motion` : int
The direction of motion; see remarks.
"""
def on_text_motion_select(self, motion):
"""The user moved the text input cursor while extending the
selection.
Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before
:py:meth:`~pyglet.window.Window.on_key_release`, but may also be called multiple times if the key
is help down (key repeating).
You should always use this method for responding to text selection
events rather than the raw :py:meth:`~pyglet.window.Window.on_key_press`, as different platforms
have different default keyboard mappings, and key repeats are
handled correctly.
The values that `motion` can take are defined in :py:mod:`pyglet.window.key`:
* MOTION_UP
* MOTION_RIGHT
* MOTION_DOWN
* MOTION_LEFT
* MOTION_NEXT_WORD
* MOTION_PREVIOUS_WORD
* MOTION_BEGINNING_OF_LINE
* MOTION_END_OF_LINE
* MOTION_NEXT_PAGE
* MOTION_PREVIOUS_PAGE
* MOTION_BEGINNING_OF_FILE
* MOTION_END_OF_FILE
:param:
`motion` : int
The direction of selection motion; see remarks.
"""
def on_mouse_motion(self, x, y, dx, dy):
"""The mouse was moved with no buttons held down.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`dx` : int
Relative X position from the previous mouse position.
`dy` : int
Relative Y position from the previous mouse position.
"""
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
"""The mouse was moved with one or more mouse buttons pressed.
This event will continue to be fired even if the mouse leaves
the window, so long as the drag buttons are continuously held down.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`dx` : int
Relative X position from the previous mouse position.
`dy` : int
Relative Y position from the previous mouse position.
`buttons` : int
Bitwise combination of the mouse buttons currently pressed.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_press(self, x, y, button, modifiers):
"""A mouse button was pressed (and held down).
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`button` : int
The mouse button that was pressed.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_release(self, x, y, button, modifiers):
"""A mouse button was released.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`button` : int
The mouse button that was released.
`modifiers` : int
Bitwise combination of any keyboard modifiers currently
active.
"""
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
"""The mouse wheel was scrolled.
Note that most mice have only a vertical scroll wheel, so
`scroll_x` is usually 0. An exception to this is the Apple Mighty
Mouse, which has a mouse ball in place of the wheel which allows
both `scroll_x` and `scroll_y` movement.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
`scroll_x` : float
Amount of movement on the horizontal axis.
`scroll_y` : float
Amount of movement on the vertical axis.
"""
def on_close(self):
"""The user attempted to close the window.
This event can be triggered by clicking on the "X" control box in
the window title bar, or by some other platform-dependent manner.
The default handler sets `has_exit` to ``True``. In pyglet 1.1, if
`pyglet.app.event_loop` is being used, `close` is also called,
closing the window immediately.
"""
def on_mouse_enter(self, x, y):
"""The mouse was moved into the window.
This event will not be triggered if the mouse is currently being
dragged.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
"""
def on_mouse_leave(self, x, y):
"""The mouse was moved outside of the window.
This event will not be triggered if the mouse is currently being
dragged. Note that the coordinates of the mouse pointer will be
outside of the window rectangle.
:param:
`x` : int
Distance in pixels from the left edge of the window.
`y` : int
Distance in pixels from the bottom edge of the window.
"""
def on_expose(self):
"""A portion of the window needs to be redrawn.
This event is triggered when the window first appears, and any time
the contents of the window is invalidated due to another window
obscuring it.
There is no way to determine which portion of the window needs
redrawing. Note that the use of this method is becoming
increasingly uncommon, as newer window managers composite windows
automatically and keep a backing store of the window contents.
"""
def on_resize(self, width, height):
"""The window was resized.
The window will have the GL context when this event is dispatched;
there is no need to call `switch_to` in this handler.
:param:
`width` : int
The new width of the window, in pixels.
`height` : int
The new height of the window, in pixels.
"""
def on_move(self, x, y):
"""The window was moved.
:param:
`x` : int
Distance from the left edge of the screen to the left edge
of the window.
`y` : int
Distance from the top edge of the screen to the top edge of
the window. Note that this is one of few methods in pyglet
which use a Y-down coordinate system.
"""
def on_activate(self):
"""The window was activated.
This event can be triggered by clicking on the title bar, bringing
it to the foreground; or by some platform-specific method.
When a window is "active" it has the keyboard focus.
"""
def on_deactivate(self):
"""The window was deactivated.
This event can be triggered by clicking on another application
window. When a window is deactivated it no longer has the
keyboard focus.
"""
def on_show(self):
"""The window was shown.
This event is triggered when a window is restored after being
minimised, hidden, or after being displayed for the first time.
"""
def on_hide(self):
"""The window was hidden.
This event is triggered when a window is minimised
or hidden by the user.
"""
def on_context_lost(self):
"""The window's GL context was lost.
When the context is lost no more GL methods can be called until it
is recreated. This is a rare event, triggered perhaps by the user
switching to an incompatible video mode. When it occurs, an
application will need to reload all objects (display lists, texture
objects, shaders) as well as restore the GL state.
"""
def on_context_state_lost(self):
"""The state of the window's GL context was lost.
pyglet may sometimes need to recreate the window's GL context if
the window is moved to another video device, or between fullscreen
or windowed mode. In this case it will try to share the objects
(display lists, texture objects, shaders) between the old and new
contexts. If this is possible, only the current state of the GL
context is lost, and the application should simply restore state.
"""
def on_file_drop(self, x, y, paths):
"""File(s) were dropped into the window, will return the position of the cursor and
a list of paths to the files that were dropped.
"""
def on_draw(self, dt):
"""The window contents must be redrawn.
The `EventLoop` will dispatch this event when the window
should be redrawn. This will happen during idle time after
any window events and after any scheduled functions were called.
The window will already have the GL context, so there is no
need to call `switch_to`. The window's `flip` method will
be called after this event, so your event handler should not.
You should make no assumptions about the window contents when
this event is triggered; a resize or expose event may have
invalidated the framebuffer since the last time it was drawn.
"""
def on_refresh(self, dt):
"""The window contents must be redrawn.
The `EventLoop` will dispatch this event when the window
should be redrawn.
The window will already have the GL context, so there is no
need to call `switch_to`. The window's `flip` method will
be called after this event, so your event handler should not.
You should make no assumptions about the window contents when
this event is triggered; a resize or expose event may have
invalidated the framebuffer since the last time it was drawn.
"""
BaseScreen.register_event_type('on_key_press')
BaseScreen.register_event_type('on_key_release')
BaseScreen.register_event_type('on_text')
BaseScreen.register_event_type('on_text_motion')
BaseScreen.register_event_type('on_text_motion_select')
BaseScreen.register_event_type('on_mouse_motion')
BaseScreen.register_event_type('on_mouse_drag')
BaseScreen.register_event_type('on_mouse_press')
BaseScreen.register_event_type('on_mouse_release')
BaseScreen.register_event_type('on_mouse_scroll')
BaseScreen.register_event_type('on_mouse_enter')
BaseScreen.register_event_type('on_mouse_leave')
BaseScreen.register_event_type('on_close')
BaseScreen.register_event_type('on_expose')
BaseScreen.register_event_type('on_resize')
BaseScreen.register_event_type('on_move')
BaseScreen.register_event_type('on_activate')
BaseScreen.register_event_type('on_deactivate')
BaseScreen.register_event_type('on_show')
BaseScreen.register_event_type('on_hide')
BaseScreen.register_event_type('on_context_lost')
BaseScreen.register_event_type('on_context_state_lost')
BaseScreen.register_event_type('on_file_drop')
BaseScreen.register_event_type('on_draw')
BaseScreen.register_event_type('on_refresh')
class DRScreen(BaseScreen):
def __init__(self, main_window: "ClientWindow"):
super().__init__(main_window)
@ -420,3 +27,29 @@ class DRScreen(BaseScreen):
class DRDEBUGScreen(BaseScreen):
def __init__(self, main_window: "ClientWindow"):
super().__init__(main_window)
self.main_batch = Batch()
self.main_group = Group(order=1)
self.fps_label = Label(x=10, y=main_window.height - 10,
width=main_window.width - 20, height=20,
anchor_x='left', anchor_y='top',
font_name=translate.微软等宽无线, font_size=20,
multiline=True,
batch=self.main_batch, group=self.main_group)
self.fps_label.text = "11111114514"
def draw_update(self, tick: float):
self.update_label()
def update_label(self):
now_FPS = get_frequency()
self.fps_label.text = f'FPS: {self.window_pointer.fps_log.fps: >5.1f}(' \
f'{self.window_pointer.fps_log.middle_fps: >5.1f})[{now_FPS: >.7f}]\n ' \
f'{self.window_pointer.fps_log.max_fps: >7.1f} ' \
f'{self.window_pointer.fps_log.min_fps:>5.1f}'
def on_resize(self, width, height):
self.fps_label.y = height - 10
def on_draw(self, *dt):
self.main_batch.draw()
# print(self.window_pointer.try_if_runs)

View File

@ -22,7 +22,7 @@ if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs')
sys.path.append('/bin')
from Difficult_Rocket import client, DR_option
from Difficult_Rocket import client, server, DR_option
from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr
@ -56,6 +56,7 @@ class Game:
def setup(self) -> None:
self.client = client.Client(net_mode='local')
self.server = server.Server(net_mode='local')
def python_version_check(self) -> None: # best 3.8+ and write at 3.8.10
self.logger.info('{} {}'.format(tr['main']['version.now_on'], self.on_python_v))
@ -68,8 +69,8 @@ class Game:
# @new_thread('main')
def _start(self):
threaded = False
if threaded:
self.server.run()
if DR_option.use_muitprocess:
try:
game_process = multiprocessing.Process(target=self.client.start(), name='pyglet app')
game_process.start()

View File

@ -25,10 +25,11 @@ class Translates:
def __init__(self,
value: Union[Dict[str, Any], list, tuple, str],
raise_error: bool = False,
get_list: list = None,
get_list: List[str] = None,
error_get_list: List[str] = None,
final: bool = False):
"""
一个用于
一个用于翻译的东西
:param value: 翻译键节点
:param raise_error: 是否抛出错误
:param get_list: 尝试获取的列表
@ -37,19 +38,23 @@ class Translates:
self.value: Union[Dict[str, Any], list, tuple] = value
self.raise_error = raise_error
self.get_list = get_list or []
self.error_get_list = error_get_list or []
self.final = final
def __getitem__(self, item: Union[str, int, Hashable]) -> Union["Translates", str]:
def __getitem__(self, item: Union[str, int, Hashable]) -> Union["Translates", str, int]:
"""
一坨答辩
:param item: 取用的内容/小天才
:return:
"""
cache_get_list = self.get_list.copy()
cache_error_get_list = self.error_get_list.copy()
cache_get_list.append(item)
try:
cache = self.value[item]
cache_get_list.append(item)
except (KeyError, TypeError):
# 出现问题
if DR_option.report_translate_no_found:
frame = inspect.currentframe()
last_frame = frame.f_back
@ -58,15 +63,17 @@ class Translates:
call_info = f'Translate Not Found at {last_frame.f_code.co_name} by {".".join(cache_get_list)} at:' \
f'{last_frame.f_code.co_filename}:{last_frame.f_lineno}'
print(call_info)
if not self.raise_error:
return Translates(value='.'.join(cache_get_list), raise_error=False, final=True)
else:
# 如果不抛出错误
if self.raise_error:
raise TranslateKeyNotFound(item_names=cache_get_list) from None
if self.final:
return self
cache_error_get_list.append(item)
if self.final: # 如果已经是翻译结果
return Translates(value='.'.join(cache_get_list), raise_error=False, final=True, error_get_list=cache_error_get_list)
else:
return Translates(value=cache, raise_error=self.raise_error, get_list=cache_get_list)
if self.final:
return self
else:
return Translates(value=cache, raise_error=self.raise_error, get_list=cache_get_list)
def __getattr__(self, item: Union[str, Hashable]) -> Union["Translates"]:
if hasattr(object, item):
@ -74,7 +81,7 @@ class Translates:
return self.__getitem__(item)
def __str__(self):
if self.final:
if self.final: # 如果是字符串
return f'{self.value}.{".".join(self.get_list)}'
return str(self.value)

View File

@ -42,7 +42,7 @@ logger_version = '1.0.0'
[Formatter]
main_format = '[{long_time}] [{logger_name}] {level} | {file_name}:{code_line} | {message}'
main_format = '[{long_time}] [{logger_name}] {level} | {file_name}:{code_line} | {marker} | {message}'
file_name = 'no frame'
code_line = 'no frame'
short_time = '%Y-%m-%d %H-%M-%S'

View File

@ -8,8 +8,8 @@ fonts_folder = "libs/fonts"
[window]
style = "None"
width = 907
height = 570
width = 1219
height = 835
visible = true
gui_scale = 1
caption = "Difficult Rocket {version}"