diff --git a/Difficult_Rocket/client.py b/Difficult_Rocket/client.py index 9e4e8a7..25df0e7 100644 --- a/Difficult_Rocket/client.py +++ b/Difficult_Rocket/client.py @@ -15,26 +15,18 @@ gitee: @shenjackyuanjie import os import sys import time -import random import logging -import threading import configparser -import multiprocessing from decimal import Decimal -from multiprocessing import Pipe -from multiprocessing.connection import Connection if __name__ == '__main__': # been start will not run this sys.path.append('/bin/libs') sys.path.append('/bin') # Difficult_Rocket function -from Difficult_Rocket import crash -from Difficult_Rocket.api.Exp import * from Difficult_Rocket.api.translate import tr -from Difficult_Rocket.graphics import widgets -from Difficult_Rocket.api import tools, load_file, new_thread, thread +from Difficult_Rocket.api import tools, new_thread, translate # libs function local_lib = True @@ -97,6 +89,7 @@ class ClientWindow(pyglet.window.Window): pyglet.resource.path = ['textures'] pyglet.resource.reindex() self.config_file = tools.load_file('configs/main.config') + self.game_config = tools.load_file('configs/game.config') self.FPS = Decimal(int(self.config_file['runtime']['fps'])) self.SPF = Decimal('1') / self.FPS # dic @@ -115,21 +108,32 @@ class ClientWindow(pyglet.window.Window): self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL) # setup self.setup() - self.info_label = pyglet.text.Label(x=10, y=self.height - 10, - anchor_x='left', anchor_y='top', - batch=self.label_batch) + # 命令显示 + self.command_label = [pyglet.text.Label(x=10, y=10 + 20 * line, + anchor_x='left', anchor_y='center', + font_name=translate.鸿蒙简体, font_size=12, + batch=self.label_batch) + for line in range(int(self.game_config['command']['show']) + 1)] + # fps显示 + self.fps_label = pyglet.text.Label(x=10, y=self.height - 10, + anchor_x='left', anchor_y='top', + font_name=translate.鸿蒙简体, font_size=20, + batch=self.label_batch) + # 设置刷新率 pyglet.clock.schedule_interval(self.update, float(self.SPF)) + # 完成设置后的信息输出 self.logger.info(tr.lang('window', 'setup.done')) + self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid())) end_time = time.time_ns() self.use_time = end_time - start_time self.logger.info(tr.lang('window', 'setup.use_time').format(Decimal(self.use_time) / 1000000000)) self.logger.debug(tr.lang('window', 'setup.use_time_ns').format(self.use_time)) def setup(self): - self.logger.info(tr.lang('window', 'os.pid_is').format(os.getpid(), os.getppid())) self.load_fonts() + # print(pyglet.font.have_font('HarmonyOS_Sans_Black')) - @new_thread('client load_fonts') + # @new_thread('client load_fonts') def load_fonts(self): file_path = './libs/fonts/HarmonyOS Sans/' ttf_files = os.listdir(file_path) @@ -176,7 +180,7 @@ class ClientWindow(pyglet.window.Window): self.max_fps = [self.FPS, time.time()] elif (time.time() - self.min_fps[1]) > self.fps_wait: self.min_fps = [self.FPS, time.time()] - self.info_label.text = 'FPS: {:.1f} {:.1f} ({:.1f}/{:.1f}) | MSPF: {:.5f} '.format(now_FPS, 1 / tick, self.max_fps[0], self.min_fps[0], tick) + self.fps_label.text = 'FPS: {:.1f} {:.1f} ({:.1f}/{:.1f}) | MSPF: {:.5f} '.format(now_FPS, 1 / tick, self.max_fps[0], self.min_fps[0], tick) def on_draw(self): self.clear() @@ -184,7 +188,7 @@ class ClientWindow(pyglet.window.Window): def on_resize(self, width: int, height: int): super().on_resize(width, height) - self.info_label.y = height - 10 + self.fps_label.y = height - 10 def draw_batch(self): self.part_batch.draw() @@ -213,9 +217,16 @@ class ClientWindow(pyglet.window.Window): 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))) def on_key_release(self, symbol, modifiers) -> None: - pass + self.logger.debug(tr.lang('window', 'key.release').format(key.symbol_string(symbol), key.modifiers_string(modifiers))) + + def on_text(self, text): + if text == '': + self.logger.debug(tr.lang('window', 'text.new_line')) + else: + self.logger.debug(tr.lang('window', 'text.input').format(text)) def on_close(self) -> None: self.run_input = False @@ -225,4 +236,4 @@ class ClientWindow(pyglet.window.Window): config_file['window']['width'] = str(self.width) config_file['window']['height'] = str(self.height) config_file.write(open('configs/main.config', 'w', encoding='utf-8')) - super(ClientWindow, self).on_close() + super().on_close() diff --git a/configs/game.config b/configs/game.config new file mode 100644 index 0000000..509b2d1 --- /dev/null +++ b/configs/game.config @@ -0,0 +1,4 @@ +[command] +log = 1000 +show = 20 +size = 12 diff --git a/configs/lang/en-us.json5 b/configs/lang/en-us.json5 index d57b92d..914d0e7 100644 --- a/configs/lang/en-us.json5 +++ b/configs/lang/en-us.json5 @@ -6,6 +6,7 @@ 'lang.language': 'English (EN-US)', 'logger.language': 'Logging language is: ', 'logger.created': 'Log handler created', + 'logger.mkdir': 'logs/ folder not found, now created', 'logger.main_done': 'Main log handler created ', 'logger.logfile_name': 'Log file name :', 'logger.logfile_level': 'Log file record level :', @@ -14,17 +15,29 @@ 'game_start.at': 'The main thread of the game starts with:' }, 'client': { - 'setup.done': 'Client load complete ', - 'os.pid_is': 'Client is using PID', + 'setup.done': 'Client load complete', + 'setup.use_time': 'Client load use: {} second', + 'setup.use_time_ns': 'Client load use: {} nano second' + }, + 'window': { + 'setup.done': 'Window load complete ', + 'setup.use_time': 'Window load use: {} second', + 'setup.use_time_ns': 'Window load use: {} nano second', + 'os.pid_is': 'Window\'s PID: {} PPID: {}', 'button.been_press': 'The button is pressed, the current state of the button is:', 'mouse.press_at': 'mouse was click at {} button is: {}', 'mouse.release': 'mouse release at {} button is: {}', - 'mouse.right': 'right button', - 'mouse.left': 'left button' + 'mouse.RIGHT': 'right button', + 'mouse.LEFT': 'left button', + 'mouse.MIDDLE': 'middle button', + 'key.press': 'key {} {} been press', + 'key.release': 'key {} {} been release', + 'text.input': 'input text {}', + 'text.new_line': '换行' }, 'server': { - 'setup.done': 'server load complete ', - 'os.pid_is': 'Client is using PID: {} PPID: {}' + 'setup.done': 'Server load complete ', + 'os.pid_is': 'Server is using PID: {} PPID: {}' }, 'language': 'English' } diff --git a/configs/lang/zh-CN.json5 b/configs/lang/zh-CN.json5 index dc76258..4ab98ae 100644 --- a/configs/lang/zh-CN.json5 +++ b/configs/lang/zh-CN.json5 @@ -29,6 +29,11 @@ 'mouse.release': '鼠标在 {} 释放,按键为:{}', 'mouse.RIGHT': '右键', 'mouse.LEFT': '左键', + 'mouse.MIDDLE': '中键', + 'key.press': '按键 {} {} 被按下', + 'key.release': '按键 {} {} 被释放', + 'text.input': '输入字符 {}', + 'text.new_line': '换行', 'libs.local': '正在使用本地 pyglet 库 版本为: {}', 'libs.outer': '正在使用全局 pyglet 库 版本为: {}\n(可能会造成bug,因为本地库版本为2.0dev9)', 'fonts.found': '在字体列表中找到以下字体库: {}' diff --git a/configs/logger.json5 b/configs/logger.json5 index 6fd3f07..1562af7 100644 --- a/configs/logger.json5 +++ b/configs/logger.json5 @@ -35,15 +35,15 @@ }, 'loggers': { 'client': { - 'level': 'DEBUG', +// 'level': 'DEBUG', 'handlers': [] }, 'server': { - 'level': 'DEBUG', +// 'level': 'DEBUG', 'handlers': [] }, 'main': { - 'level': 'DEBUG', +// 'level': 'DEBUG', 'handlers': [] } }, diff --git a/docs/update_logs.md b/docs/update_logs.md index 733d07a..8e21cc4 100644 --- a/docs/update_logs.md +++ b/docs/update_logs.md @@ -23,6 +23,9 @@ - `Difficult_Rocket.graphics.widgets.Parts` - have many costume value - `libs/fonts` now have `HarmonyOS_Sans` +- handler of `on_key_press` and `on_key_release` and `on_text` +- `game.config` config file +- `lang/en-us.json5` now up to date with `lang/zh-CN.json5` ## 20210928 V 0.5.2 diff --git a/libs/pyglet/graphics/shader.py b/libs/pyglet/graphics/shader.py index 0f626f3..3a18fef 100644 --- a/libs/pyglet/graphics/shader.py +++ b/libs/pyglet/graphics/shader.py @@ -514,31 +514,34 @@ class UniformBufferObject: # Query the number of active Uniforms: num_active = GLint() - indices = (GLuint * num_active.value)() - indices_ptr = cast(addressof(indices), POINTER(GLint)) glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, num_active) - glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices_ptr) - # Create objects and pointers for query values, to be used in the next step: + # Query the uniform index order and each uniform's offset: + indices = (GLuint * num_active.value)() offsets = (GLint * num_active.value)() - gl_types = (GLuint * num_active.value)() - mat_stride = (GLuint * num_active.value)() + indices_ptr = cast(addressof(indices), POINTER(GLint)) offsets_ptr = cast(addressof(offsets), POINTER(GLint)) + glGetActiveUniformBlockiv(p_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices_ptr) + glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_OFFSET, offsets_ptr) + + # Offsets may be returned in non-ascending order, sort them with the corresponding index: + _oi = sorted(zip(offsets, indices), key=lambda x: x[0]) + offsets = [x[0] for x in _oi] + [self.block.size] + indices = (GLuint * num_active.value)(*(x[1] for x in _oi)) + + # Query other uniform information: + gl_types = (GLint * num_active.value)() + mat_stride = (GLint * num_active.value)() gl_types_ptr = cast(addressof(gl_types), POINTER(GLint)) stride_ptr = cast(addressof(mat_stride), POINTER(GLint)) - - # Query the indices, offsets, and types uniforms: - glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_OFFSET, offsets_ptr) glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_TYPE, gl_types_ptr) glGetActiveUniformsiv(p_id, num_active.value, indices, GL_UNIFORM_MATRIX_STRIDE, stride_ptr) - offsets = offsets[:] + [self.block.size] args = [] for i in range(num_active.value): - u_name, gl_type, length = self.block.uniforms[i] - start = offsets[i] - size = offsets[i+1] - start + u_name, gl_type, length = self.block.uniforms[indices[i]] + size = offsets[i+1] - offsets[i] c_type_size = sizeof(gl_type) actual_size = c_type_size * length padding = size - actual_size diff --git a/libs/pyglet/math.py b/libs/pyglet/math.py index 7d1c9c0..7da664e 100644 --- a/libs/pyglet/math.py +++ b/libs/pyglet/math.py @@ -472,6 +472,17 @@ class Mat4(tuple): 0.0, 0.0, 1.0, 0.0, vector[0], vector[1], vector[2], 1.0)) + @classmethod + def from_rotation(cls, angle: float, vector: Vec3) -> 'Mat4': + """Create a rotation matrix from an angle and Vec3. + + :Parameters: + `angle` : A `float` + `vector` : A `Vec3`, or 3 component tuple of float or int + Vec3 or tuple with x, y and z translaton values + """ + return cls().rotate(angle, vector) + @classmethod def look_at_direction(cls, direction: Vec3, up: Vec3) -> 'Mat4': vec_z = direction.normalize() @@ -498,21 +509,22 @@ class Mat4(tuple): """Get a specific column as a tuple.""" return self[index::4] - def scale(self, x=1, y=1, z=1) -> 'Mat4': + def scale(self, vector: Vec3) -> 'Mat4': """Get a scale Matrix on x, y, or z axis.""" temp = list(self) - temp[0] *= x - temp[5] *= y - temp[10] *= z + temp[0] *= vector[0] + temp[5] *= vector[1] + temp[10] *= vector[2] return Mat4(temp) - def translate(self, x=0, y=0, z=0) -> 'Mat4': + def translate(self, vector: Vec3) -> 'Mat4': """Get a translate Matrix along x, y, and z axis.""" - return Mat4(self) @ Mat4((1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1)) + return Mat4(self) @ Mat4((1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, *vector, 1)) - def rotate(self, angle=0, x=0, y=0, z=0) -> 'Mat4': + def rotate(self, angle: float, vector: Vec3) -> 'Mat4': """Get a rotation Matrix on x, y, or z axis.""" - assert all(abs(n) <= 1 for n in (x, y, z)), "x,y,z must be normalized (<=1)" + assert all(abs(n) <= 1 for n in vector), "vector must be normalized (<=1)" + x, y, z = vector c = _math.cos(angle) s = _math.sin(angle) t = 1 - c diff --git a/libs/pyglet/model/__init__.py b/libs/pyglet/model/__init__.py index 5d0b4b8..a0c86bb 100644 --- a/libs/pyglet/model/__init__.py +++ b/libs/pyglet/model/__init__.py @@ -89,7 +89,7 @@ import pyglet from pyglet import gl from pyglet import graphics from pyglet.gl import current_context -from pyglet.math import Mat4 +from pyglet.math import Mat4, Vec3 from pyglet.graphics import shader from .codecs import ModelDecodeException @@ -190,8 +190,8 @@ class Model: self.vertex_lists = vertex_lists self.groups = groups self._batch = batch - self._rotation = 0, 0, 0 - self._translation = 0, 0, 0 + self._rotation = Vec3() + self._translation = Vec3() @property def batch(self): @@ -279,16 +279,16 @@ class BaseMaterialGroup(graphics.ShaderGroup): super().__init__(program, order, parent) self.material = material - self.rotation = 0, 0, 0 - self.translation = 0, 0, 0 + self.rotation = Vec3() + self.translation = Vec3() def set_modelview_matrix(self): # NOTE: Matrix operations can be optimized later with transform feedback view = Mat4() - view = view.rotate(radians(self.rotation[2]), z=1) - view = view.rotate(radians(self.rotation[1]), y=1) - view = view.rotate(radians(self.rotation[0]), x=1) - view = view.translate(*self.translation) + view = view.rotate(radians(self.rotation[2]), Vec3(0, 0, 1)) + view = view.rotate(radians(self.rotation[1]), Vec3(0, 1, 0)) + view = view.rotate(radians(self.rotation[0]), Vec3(1, 0, 0)) + view = view.translate(self.translation) # TODO: separate the projection block, and remove this hack block = self.program.uniform_blocks['WindowBlock'] diff --git a/libs/pyglet/sprite.py b/libs/pyglet/sprite.py index 0cf1903..9182835 100644 --- a/libs/pyglet/sprite.py +++ b/libs/pyglet/sprite.py @@ -178,141 +178,6 @@ fragment_array_source = """#version 150 core """ -############################ - -vertex_src = """#version 150 - in vec2 position; - in vec4 size; - in vec4 color; - in vec4 tex_coords; - in float rotation; - - out vec4 geo_size; - out vec4 geo_color; - out vec4 geo_tex_coords; - out float geo_rotation; - - void main() { - gl_Position = vec4(position, 0, 1); - geo_size = size; - geo_color = color; - geo_tex_coords = tex_coords; - geo_rotation = rotation; - } -""" - - -geometry_src = """#version 150 - // We are taking single points form the vertex shader - // and emitting 4 new vertices creating a quad/sprites - layout (points) in; - layout (triangle_strip, max_vertices = 4) out; - - uniform WindowBlock - { - mat4 projection; - mat4 view; - } window; - - - // Since geometry shader can take multiple values from a vertex - // shader we need to define the inputs from it as arrays. - // In our instance we just take single values (points) - in vec4 geo_size[]; - in vec4 geo_color[]; - in vec4 geo_tex_coords[]; - in float geo_rotation[]; - - out vec2 uv; - out vec4 frag_color; - - void main() { - - // We grab the position value from the vertex shader - vec2 center = gl_in[0].gl_Position.xy; - - // Calculate the half size of the sprites for easier calculations - vec2 hsize = geo_size[0].xy / 2.0; - - // Convert the rotation to radians - float angle = radians(-geo_rotation[0]); - - // Create a scale vector - vec2 scale = vec2(geo_size[0][2], geo_size[0][3]); - - // Create a 2d rotation matrix - mat2 rot = mat2(cos(angle), sin(angle), - -sin(angle), cos(angle)); - - // Calculate the left, bottom, right, top: - float tl = geo_tex_coords[0].s; - float tb = geo_tex_coords[0].t; - float tr = geo_tex_coords[0].s + geo_tex_coords[0].p; - float tt = geo_tex_coords[0].t + geo_tex_coords[0].q; - - // Emit a triangle strip creating a quad (4 vertices). - // Here we need to make sure the rotation is applied before we position the sprite. - // We just use hardcoded texture coordinates here. If an atlas is used we - // can pass an additional vec4 for specific texture coordinates. - // Each EmitVertex() emits values down the shader pipeline just like a single - // run of a vertex shader, but in geomtry shaders we can do it multiple times! - - // Upper left - gl_Position = window.projection * window.view * vec4(rot * vec2(-hsize.x, hsize.y) * scale + center, 0.0, 1.0); - uv = vec2(tl, tt); - frag_color = geo_color[0]; - EmitVertex(); - - // lower left - gl_Position = window.projection * window.view * vec4(rot * vec2(-hsize.x, -hsize.y) * scale + center, 0.0, 1.0); - uv = vec2(tl, tb); - frag_color = geo_color[0]; - EmitVertex(); - - // upper right - gl_Position = window.projection * window.view * vec4(rot * vec2(hsize.x, hsize.y) * scale + center, 0.0, 1.0); - uv = vec2(tr, tt); - frag_color = geo_color[0]; - EmitVertex(); - - // lower right - gl_Position = window.projection * window.view * vec4(rot * vec2(hsize.x, -hsize.y) * scale + center, 0.0, 1.0); - uv = vec2(tr, tb); - frag_color = geo_color[0]; - EmitVertex(); - - // We are done with this triangle strip now - EndPrimitive(); - } -""" - -fragment_src = """#version 150 - in vec2 uv; - in vec4 frag_color; - - out vec4 final_color; - - uniform sampler2D sprite_texture; - - void main() { - final_color = texture(sprite_texture, uv) * frag_color; - } - -""" - - -def get_geo_shader(): - try: - return pyglet.gl.current_context.pyglet_sprite_geo_shader - except AttributeError: - new_vert_shader = graphics.shader.Shader(vertex_src, 'vertex') - new_geom_shader = graphics.shader.Shader(geometry_src, 'geometry') - new_frag_shader = graphics.shader.Shader(fragment_src, 'fragment') - new_program = graphics.shader.ShaderProgram(new_vert_shader, new_geom_shader, new_frag_shader) - pyglet.gl.current_context.pyglet_sprite_geo_shader = new_program - return pyglet.gl.current_context.pyglet_sprite_geo_shader - - def get_default_shader(): try: return pyglet.gl.current_context.pyglet_sprite_default_shader @@ -935,229 +800,3 @@ class Sprite(event.EventDispatcher): Sprite.register_event_type('on_animation_end') - - -class GeoSprite(Sprite): - """Instance of an on-screen image. - - See the module documentation for usage. - """ - - _batch = None - _animation = None - _frame_index = 0 - _paused = False - _rotation = 0 - _rgba = [255, 255, 255, 255] - _scale = 1.0 - _scale_x = 1.0 - _scale_y = 1.0 - _visible = True - - def __init__(self, - img, x=0, y=0, - blend_src=GL_SRC_ALPHA, - blend_dest=GL_ONE_MINUS_SRC_ALPHA, - batch=None, - group=None, - subpixel=False): - """Create a sprite. - - :Parameters: - `img` : `~pyglet.image.AbstractImage` or `~pyglet.image.Animation` - Image or animation to display. - `x` : int - X coordinate of the sprite. - `y` : int - Y coordinate of the sprite. - `blend_src` : int - OpenGL blend source mode. The default is suitable for - compositing sprites drawn from back-to-front. - `blend_dest` : int - OpenGL blend destination mode. The default is suitable for - compositing sprites drawn from back-to-front. - `batch` : `~pyglet.graphics.Batch` - Optional batch to add the sprite to. - `group` : `~pyglet.graphics.Group` - Optional parent group of the sprite. - `subpixel` : bool - Allow floating-point coordinates for the sprite. By default, - coordinates are restricted to integer values. - """ - self._x = x - self._y = y - - if isinstance(img, image.Animation): - self._animation = img - self._texture = img.frames[0].image.get_texture() - self._next_dt = img.frames[0].duration - if self._next_dt: - clock.schedule_once(self._animate, self._next_dt) - else: - self._texture = img.get_texture() - - program = get_geo_shader() - - self._batch = batch or graphics.get_default_batch() - self._group = SpriteGroup(self._texture, blend_src, blend_dest, program, 0, group) - self._subpixel = subpixel - - # TODO: add a property to the Texture class: - tex_coords = (self._texture.tex_coords[0], self._texture.tex_coords[1], - self._texture.tex_coords[3], self._texture.tex_coords[7]) - - self._vertex_list = self._batch.add( - 1, GL_POINTS, self._group, - ('position2f', (int(x) if subpixel else x, int(y) if subpixel else y)), - ('size4f', (self._texture.width, self._texture.height, 1, 1)), - ('rotation1f', (self._rotation,)), - ('color4Bn', self._rgba), - ('tex_coords4f', tex_coords) - ) - - @property - def position(self): - """The (x, y) coordinates of the sprite, as a tuple. - - :Parameters: - `x` : int - X coordinate of the sprite. - `y` : int - Y coordinate of the sprite. - """ - return self._x, self._y - - @position.setter - def position(self, position): - self._x, self._y = position - self._vertex_list.position[:] = position - - @property - def x(self): - """X coordinate of the sprite. - - :type: int - """ - return self._x - - @x.setter - def x(self, x): - self._x = x - self._vertex_list.position[:] = x, self._y - - @property - def y(self): - """Y coordinate of the sprite. - - :type: int - """ - return self._y - - @y.setter - def y(self, y): - self._y = y - self._vertex_list.position[:] = self._x, y - - @property - def rotation(self): - """Clockwise rotation of the sprite, in degrees. - - The sprite image will be rotated about its image's (anchor_x, anchor_y) - position. - - :type: float - """ - return self._rotation - - @rotation.setter - def rotation(self, rotation): - self._rotation = rotation - self._vertex_list.rotation[0] = rotation - - @property - def scale(self): - """Base Scaling factor. - - A scaling factor of 1 (the default) has no effect. A scale of 2 will - draw the sprite at twice the native size of its image. - - :type: float - """ - return self._scale - - @scale.setter - def scale(self, scale): - self._scale = scale - self._vertex_list.size[2:4] = (scale * self._scale_x, scale * self._scale_y) - - @property - def scale_x(self): - """Horizontal scaling factor. - - A scaling factor of 1 (the default) has no effect. A scale of 2 will - draw the sprite at twice the native width of its image. - - :type: float - """ - return self._scale_x - - @scale_x.setter - def scale_x(self, scale_x): - self._scale_x = scale_x - self._vertex_list.size[2:4] = (self._scale * scale_x, self._scale * self._scale_y) - - @property - def scale_y(self): - """Vertical scaling factor. - - A scaling factor of 1 (the default) has no effect. A scale of 2 will - draw the sprite at twice the native height of its image. - - :type: float - """ - return self._scale_y - - @scale_y.setter - def scale_y(self, scale_y): - self._scale_y = scale_y - self._vertex_list.size[2:4] = (self._scale * self._scale_x, self._scale * scale_y) - - @property - def opacity(self): - """Blend opacity. - - This property sets the alpha component of the colour of the sprite's - vertices. With the default blend mode (see the constructor), this - allows the sprite to be drawn with fractional opacity, blending with the - background. - - An opacity of 255 (the default) has no effect. An opacity of 128 will - make the sprite appear translucent. - - :type: int - """ - return self._rgba[3] - - @opacity.setter - def opacity(self, opacity): - self._rgba[3] = opacity - self._vertex_list.color[:] = self._rgba - - @property - def color(self): - """Blend color. - - This property sets the color of the sprite's vertices. This allows the - sprite to be drawn with a color tint. - - The color is specified as an RGB tuple of integers '(red, green, blue)'. - Each color component must be in the range 0 (dark) to 255 (saturated). - - :type: (int, int, int) - """ - return self._rgba[:3] - - @color.setter - def color(self, rgb): - self._rgba[:3] = list(map(int, rgb)) - self._vertex_list.color[:] = self._rgba diff --git a/libs/pyglet/text/layout.py b/libs/pyglet/text/layout.py index 5185a74..0073518 100644 --- a/libs/pyglet/text/layout.py +++ b/libs/pyglet/text/layout.py @@ -1011,18 +1011,8 @@ class TextLayout: return self._x, self._y @position.setter - def position(self, position): - self.update(*position) - - def update(self, x, y): - """Change both X and Y positions of the layout at once for faster performance. - - :Parameters: - `x` : int - X coordinate of the layout. - `y` : int - Y coordinate of the layout. - """ + def position(self, values): + x, y = values if self._boxes: self._x = x self._y = y @@ -1790,6 +1780,10 @@ class ScrollableTextLayout(TextLayout): for group in self.groups.values(): group.scissor_area = area + def _update(self): + super()._update() + self._update_scissor_area() + # Properties @property