离谱玩意.gif

This commit is contained in:
shenjackyuanjie 2021-12-15 23:28:08 +08:00
parent 10a097290b
commit 2ed77e7c3c
9 changed files with 115 additions and 83 deletions

View File

@ -44,6 +44,8 @@ if __name__ == '__main__':
try:
from Difficult_Rocket import main
game = main.Game()
from libs.pyglet.gl import glClearColor
glClearColor(0, 0, 0, 0)
cprofile = False
if cprofile:
cProfile.run('game.start()', sort='calls')

View File

@ -105,8 +105,7 @@ class ClientWindow(Window):
# FPS
self.FPS = Decimal(int(self.main_config['runtime']['fps']))
self.SPF = Decimal('1') / self.FPS
self.fps_log = FpsLogger(stable_fps=int(self.FPS),
wait_time=5)
self.fps_log = FpsLogger(stable_fps=int(self.FPS))
# batch
self.part_batch = pyglet.graphics.Batch()
self.label_batch = pyglet.graphics.Batch()
@ -117,17 +116,19 @@ class ClientWindow(Window):
self.setup()
# 命令显示
self.command_group = pyglet.graphics.Group(0)
self.command = line.CommandLine(x=50, y=30, # 实例化
width=self.width - 100, height=40,
length=int(self.game_config['command']['show']),
batch=self.label_batch, group=self.command_group)
self.push_handlers(self.command)
self.command.set_handler('on_command', self.on_command)
self.command.set_handler('on_message', self.on_message)
# self.command = line.CommandLine(x=50, y=30, # 实例化
# width=self.width - 100, height=40,
# length=int(self.game_config['command']['show']),
# batch=self.label_batch, group=self.command_group)
# self.push_handlers(self.command)
# self.command.set_handler('on_command', self.on_command)
# self.command.set_handler('on_message', self.on_message)
self.input_box = InputBox(x=50, y=30, width=300, height=20,
batch=self.label_batch) # 实例化
self.push_handlers(self.input_box)
self.input_box.enabled = True
self.label = pyglet.text.HTMLLabel(text=f'<font color=red real_size=20 face="{translate.HOS_S}">abc</font>',
x=self.width // 2, y=self.height // 2)
# fps显示
self.fps_label = pyglet.text.Label(x=10, y=self.height - 10,
width=self.width - 20, height=20,
@ -206,11 +207,12 @@ class ClientWindow(Window):
def FPS_update(self, tick: Decimal):
now_FPS = pyglet.clock.get_fps()
self.fps_log.update_tick(tick)
self.fps_label.text = f'FPS: {now_FPS: >10.1f} \n{1/tick} \n{self.fps_log.max_fps: >10.1f} {self.fps_log.min_fps:>5.1f}'
self.fps_label.text = f'FPS: {self.fps_log.fps: >5.1f}({self.fps_log.middle_fps: >5.1f})[{now_FPS}] \n{self.fps_log.max_fps: >7.1f} {self.fps_log.min_fps:>5.1f}'
def on_draw(self, *dt):
self.clear()
self.draw_batch()
self.label.draw()
def on_resize(self, width: int, height: int):
super().on_resize(width, height)

View File

@ -12,92 +12,58 @@ gitee: @shenjackyuanjie
"""
import time
import decimal
import statistics
from typing import Union
from decimal import Decimal
from ..api import new_thread
from libs import pyglet
"""
fps_list ->
[
[fps, time_ns, tick time_ns, pyglet tick]
]
"""
from libs.pyglet import clock
class FpsLogger:
def __init__(self,
stable_fps: int = 60,
wait_time: int = 5):
count: int = 400):
self.stable_fps = stable_fps
self.wait_time = wait_time
self.time = time.time_ns()
self.fps_list = [[stable_fps, time.time_ns()]]
self.count = count
self._fps = stable_fps
self.middle_fps = stable_fps
self.fps_list = [stable_fps] # type: list[Union[int, float]]
self.get_fps_list = [stable_fps] # type: list[Union[int, float]]
self._max_fps = stable_fps
self._max_fps_tick = time.time_ns()
self._min_fps = stable_fps
self._min_fps_tick = time.time_ns()
self.check_list = True
self.update_list()
# @new_thread('fps_logger update', daemon=False, log_thread=False)
def update_tick(self,
tick: Decimal):
self.time = time.time_ns()
now_fps = pyglet.clock.get_fps()
# 获取当前信息
if now_fps > self.max_fps and not self.time - self._max_fps_tick >= self.wait_time:
self.max_fps = now_fps
# self.max_fps = max(self.max_fps, now_fps)
tick_time = self.time - self.fps_list[-1][1]
# 获取渲染用时
self.fps_list.append([now_fps, self.time, tick_time, tick])
if self.time - self.fps_list[0][1] >= self.wait_time * (10 ** 9):
self.fps_list.pop(0)
now_fps = clock.get_fps()
if now_fps != 0:
self.fps_list.append(now_fps)
else:
self.fps_list.append(1)
if len(self.fps_list) > self.count:
self.fps_list = self.fps_list[-self.count + 1:]
if len(self.get_fps_list) > self.count:
self.get_fps_list = self.get_fps_list[-self.count + 1:]
try:
self._fps = statistics.geometric_mean(self.fps_list[-200:])
self.middle_fps = statistics.median(self.fps_list)
except Exception:
print(self.fps_list)
raise
self._max_fps = max(self.fps_list)
self._min_fps = min(self.fps_list)
# 获取新fps
del now_fps
del tick_time
@new_thread('fps_logger check_list', daemon=True)
def update_list(self):
while self.check_list:
now_time = time.time_ns()
for fps_time in self.fps_list:
if now_time - fps_time[1] >= self.wait_time * (10 ** 9):
del self.fps_list[self.fps_list.index(fps_time)]
time.sleep(1)
@property
def max_fps(self):
return self._max_fps
@max_fps.setter
def max_fps(self, value):
# if self.time - self._max_fps_tick <= self.wait_time:
# self._max_fps = value
# self._max_fps_tick = time.time_ns()
# else:
# max_fps = self.list_max_fps
# self._max_fps = max_fps[0]
# self._max_fps_tick = max_fps[1]
self._max_fps = value
self._max_fps_tick = self.time
@property
def min_fps(self):
return self._min_fps
@min_fps.setter
def min_fps(self, value):
self._min_fps = value
self._min_fps_tick = time.time_ns()
@property
def list_max_fps(self):
return max(self.fps_list)
@property
def list_min_fps(self):
return min(self.fps_list)
def fps(self):
return self._fps

View File

@ -23,6 +23,8 @@ from libs.pyglet.sprite import Sprite
from libs.pyglet.shapes import Rectangle
from libs.pyglet.image import AbstractImage
from libs.pyglet.graphics import Batch, Group
from libs.pyglet.text.document import FormattedDocument
from libs.pyglet.text.layout import IncrementalTextLayout
# from libs import pyperclip
from libs.pyperclip import paste, copy
@ -55,7 +57,7 @@ class InputBox(widgets.WidgetBase):
def __init__(self,
x: int, y: int, width: int, height: int,
message: str = '',
font_name: str = translate.鸿蒙简体,
font_name: str = translate.微软等宽,
font_size: int = 15,
font_bold: bool = False,
font_italic: bool = False,
@ -77,8 +79,14 @@ class InputBox(widgets.WidgetBase):
dpi=font_dpi)
self.font_height = self.font.ascent - self.font.descent
self.out_bound = out_line
# 基于IncrementalTextLayout的处理系统
self._doc = FormattedDocument(message)
# self._doc.set_style()
self._layout = IncrementalTextLayout(self._doc, self.font, width, height,
batch=batch, group=group)
# 基于Label的处理系统
self._input_box = Label(x=x + out_line, y=y + out_line,
width=width, height=height,
width=width, height=self.font_height + self.out_bound * 2,
color=text_color,
font_name=font_name, font_size=font_size,
batch=batch, group=group,
@ -122,10 +130,7 @@ class InputBox(widgets.WidgetBase):
def cursor_poi(self, value) -> None:
assert type(value) is int, 'Input Box\'s cursor poi must be int!'
self._cursor_poi = value
add_x = self.x + self.out_bound
for glyph in self.font.get_glyphs(self.text[:value]):
add_x += glyph.width
self._光标.x = add_x
self._光标.x = self.x + self.out_bound + self._input_box.content_width
# 渲染时属性
@property

View File

@ -8,8 +8,8 @@ fonts_folder = libs/fonts
[window]
style = None
width = 1024
height = 768
width = 646
height = 463
visible = true
caption = Difficult Rocket {version}
resizable = true

View File

@ -21,6 +21,11 @@
### Change
- 重命名 `Difficult_Rocket.py` -> `DR.py`
- 用于修复 `Pycharm` 检测模块时总是会把主文件检测成主程序,导致一些模块总是检测不到的问题
- Rename `Difficult_Rocket.py` -> `DR.py`
- Use it to fix `Pycharm` module detection problem
- When the main file is detected as the main program, some modules will always be detected as the main program
- 把`api/translate`移动到根目录下
- move `api/translate` to root directory
- 现在命令会慢慢消失,而不是立即消失

View File

@ -340,7 +340,11 @@ def _enum_font_names(logfont, textmetricex, fonttype, param):
global FONTDB
lf = logfont.contents
name = lf.lfFaceName.decode('utf-8')
try:
name = lf.lfFaceName.decode('utf-8')
except UnicodeDecodeError:
name = lf.lfFaceName.decode('ANSI')
# detect font type (vector|raster) and format (ttf)
# [ ] use Windows constant TRUETYPE_FONTTYPE

View File

@ -189,6 +189,7 @@ class HTMLDecoder(HTMLParser, structured.StructuredTextDecoder):
attrs = {}
for key, value in case_attrs:
attrs[key.lower()] = value
print(attrs)
if element in _metadata_elements:
self.in_metadata = True
@ -231,6 +232,10 @@ class HTMLDecoder(HTMLParser, structured.StructuredTextDecoder):
self._font_size_stack.append(size)
if size in self.font_sizes:
style['font_size'] = self.font_sizes.get(size, 3)
elif 'real_size' in attrs:
size = int(attrs['real_size'])
self._font_size_stack.append(size)
style['font_size'] = size
else:
self._font_size_stack.append(self._font_size_stack[-1])
if 'color' in attrs:

View File

@ -0,0 +1,43 @@
"""A simple demonstration of the HTMLLabel class, as it might be used on a
help or introductory screen.
"""
import os
import pyglet
html = '''
<h1>HTML labels in pyglet</h1>
<p>HTML labels are a simple way to add formatted text to your application.
Different <font face="Cascadia Code" size=+2>fonts</font>, <em>styles</em>
and <font color=red>colours</font> are supported.
<p>This window has been made resizable; text will reflow to fit the new size.
'''
window = pyglet.window.Window(resizable=True)
location = pyglet.resource.FileLocation(os.path.dirname(__file__))
label = pyglet.text.HTMLLabel(html, location=location,
width=window.width,
multiline=True, anchor_y='center')
@window.event
def on_resize(width, height):
# Wrap text to the width of the window
label.width = window.width
# Keep text vertically centered in the window
label.y = window.height // 2
@window.event
def on_draw():
window.clear()
label.draw()
pyglet.gl.glClearColor(1, 1, 1, 1)
pyglet.app.run()