找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 148|回复: 0

[软件/工具] Positioner:一个Ren'Py定位工具

[复制链接]
发表于 2024-8-27 18:16:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 ZYKsslm 于 2024-8-28 13:19 编辑

Positioner:一个Ren'Py定位工具



Positioner 是一个在 Ren'Py 中快速使用矩形定位的工具(别问为什么是矩形,问就是Ren'Py没实现弧线和圆的绘制)
通过不同的定位工具可以快速确定位置参数(目前只有绝对坐标),同时支持实时拖动调整和滚轮缩放




源码:

核心部分:
[RenPy] 纯文本查看 复制代码
#* Positioner - 一个开源的 Ren'Py 定位工具
#* 作者 ZYKsslm
#! 开源协议 MIT
#* 感谢 Feniks [url=home.php?mod=space&uid=1671]@[/url] feniksdev.com 提供的非常实用的开源工具 color_picker


python early:
    import pygame

    class Positioner(renpy.Displayable):
        def __init__(self, name="", size=(100, 100), color=Color("#00d9ff", alpha=0.7), **properties):
            super().__init__(**properties)
            self._name = name
            self._name_color = Color("#e5ff00")
            self.name_displayable = Text(str(name), color=self.name_color)
            self._size = size   # 大小
            self._color = color
            self._pos = (0, 0)  # 左上角顶点的坐标
            self._relative_size = (0, 0)
            self.rect = (*self.pos, *self.size)
            self.pressed = False
            self.lock = False
            self.follow_mouse = False
            self.show = True

        @property
        def pos(self):
            return self._pos

        @pos.setter
        def pos(self, value):
            self._pos = value
            self.rect = (*self.pos, *self.size)
            self._update_display()

        @property
        def size(self):
            return self._size

        @size.setter
        def size(self, value):
            self._size = value
            self.rect = (*self.pos, *self.size)
            self._update_display()

        @property
        def color(self):
            return self._color

        @color.setter
        def color(self, value):
            self._color = Color(color=value.hexcode, alpha=0.7)
            self._update_display()

        @property
        def name(self):
            return self._name

        @name.setter
        def name(self, value):
            self._name = value
            self.name_displayable = Text(str(value), color=self.name_color)
            self._update_display()

        @property
        def name_color(self):
            return self._name_color

        @name_color.setter
        def name_color(self, value):
            self._name_color = value
            self.name_displayable = Text(str(self.name), color=self.name_color)
            self._update_display()

        def _update_display(self):
            renpy.redraw(self, 0)
            renpy.restart_interaction()

        def toggle_lock(self):
            self.lock = not self.lock
            self._update_display()

        def toggle_show(self):
            self.show = not self.show
            self._update_display()

        def toggle_follow_mouse(self):
            self.follow_mouse = not self.follow_mouse
            self._update_display()

        def reset(self):
            self.size = (100, 100)
            self.pos = (0, 0)
            self._relative_size = (0, 0)
            self._update_display()

        def modify_size(self, factor, x=True, y=True):
            if x:
                self.size = (round(self.size[0] * factor), self.size[1])
            if y:
                self.size = (self.size[0], round(self.size[1] * factor))
            self._update_display()

        def plus(self, x=True, y=True):
            self.modify_size(1.1, x, y)

        def minus(self, x=True, y=True):
            self.modify_size(0.9, x, y)

        def render(self, width, height, st, at):
            render = renpy.Render(width, height)
            if self.show:
                canvas = render.canvas()
                canvas.rect(self.color, (*self.pos, *self.size))
                if self.name:
                    name_render = renpy.render(self.name_displayable, width, height, st, at)
                    render.blit(name_render, self.pos)
            return render

        def event(self, ev, x, y, st):
            if self.lock:
                return
            if ev.type == pygame.MOUSEBUTTONDOWN:
                if ev.button == 1:
                    if self.rect[0] <= x <= self.rect[0] + self.rect[2] and self.rect[1] <= y <= self.rect[1] + self.rect[3]:
                        self._relative_size = (x - self.pos[0], y - self.pos[1])
                    self.pressed = True
                elif ev.button == 4:
                    self.plus()
                elif ev.button == 5:
                    self.minus()

            elif ev.type == pygame.MOUSEBUTTONUP:
                self.pressed = False
                self._relative_size = (0, 0)

            if self.pressed or self.follow_mouse:
                if self.pressed:
                    self.follow_mouse = False
                self.pos = (x - self._relative_size[0], y - self._relative_size[1])
                renpy.restart_interaction()
                
            renpy.redraw(self, 0)

    class PositionerGroup(renpy.Displayable):
        def __init__(self, *positioners, **properties):
            super().__init__(**properties)
            self.positioners = list(positioners)
            if not self.positioners:
                self.create()
            else:
                self.selected_positioner = self.positioners[-1]

        def create(self, *args, **kwargs):
            positioner = Positioner(*args, **kwargs)
            self.positioners.append(positioner)
            self.selected_positioner = positioner
            renpy.redraw(self, 0)

        def remove(self, positioner):
            self.positioners.remove(positioner)
            if not self.positioners:
                self.create()
            self.selected_positioner = self.positioners[-1]
            renpy.redraw(self, 0)
        
        def render(self, width, height, st, at):
            render = renpy.Render(width, height)
            for positioner in self.positioners:
                render.blit(positioner.render(width, height, st, at), (0, 0))
            
            return render

        def event(self, ev, x, y, st):
            if ev.type == pygame.MOUSEBUTTONDOWN and ev.button == 1:
                for positioner in self.positioners:
                    area = (*positioner.pos, *positioner.size)
                    if area[0] <= x <= area[0] + area[2] and area[1] <= y <= area[1] + area[3]:
                        self.selected_positioner = positioner
                        renpy.restart_interaction()
            
            self.selected_positioner.event(ev, x, y, st)
            renpy.redraw(self, 0)
        
        def visit(self):
            return self.positioners

screen color_picker(obj, field, default_color):
    modal True
    style_prefix 'cpicker'

    default picker = ColorPicker(500, 500, default_color)
    default picker_swatch = DynamicDisplayable(picker_color, picker=picker, xsize=100, ysize=100)
    default picker_hex = DynamicDisplayable(picker_hexcode, picker=picker)
    
    label "{i}color_picker{/i} 工具由 {u}@ feniksdev.com{/u} 提供"
    hbox:
        vbar value FieldValue(picker, "hue_rotation", 1.0)
        vbox:
            add picker
            bar value FieldValue(picker, "hue_rotation", 1.0)
        vbox:
            xsize 200 spacing 10 align (0.0, 0.0)
            add picker_swatch
            add picker_hex
            textbutton "完成" action [SetField(obj, field, picker.color), Return()]

style cpicker_vbox:
    align (0.5, 0.5)
    spacing 25
style cpicker_hbox:
    align (0.5, 0.5)
    spacing 25
style cpicker_vbar:
    xysize (50, 500)
    base_bar At(Transform("#000", xysize=(50, 500)), spectrum(horizontal=False))
    thumb Transform("selector_bg", xysize=(50, 20))
    thumb_offset 10
style cpicker_bar:
    xysize (500, 50)
    base_bar At(Transform("#000", xysize=(500, 50)), spectrum())
    thumb Transform("selector_bg", xysize=(20, 50))
    thumb_offset 10
style cpicker_text:
    color "#fff"
style cpicker_button:
    padding (4, 4) insensitive_background "#fff"
style cpicker_button_text:
    color "#aaa"
    hover_color "#fff"
style cpicker_image_button:
    xysize (104, 104)
    padding (4, 4)
    hover_foreground "#fff2"

screen change_positioner_name(positioner):
    modal True
    default notice_value = FieldInputValue(positioner, "name")

    frame:
        xysize (500, 300)
        align (0.5, 0.5)

        label "请输入名称:" align (0.5, 0.15)
        input:
            align (0.5, 0.5)
            pixel_width 390
            multiline True
            copypaste True
            value notice_value

        hbox:
            spacing 100
            align (0.5, 0.75)
            textbutton "颜色" action ShowMenu("color_picker", obj=positioner, field="name_color", default_color=positioner.name_color)
            textbutton "完成" action Hide("change_positioner_name")

screen position_helper(*displayables):
    default positioner_group = PositionerGroup()
    $ positioner = positioner_group.selected_positioner
    
    for displayable in displayables:
        add displayable

    add positioner_group

    frame:
        background Color("#ffffff", alpha=0.3)
        align (0.02, 0.1)
        has vbox
        spacing 20
    
        label "当前参数"
        label "[positioner.rect]"
        label "x&y轴"
        textbutton "放大" action Function(positioner.plus)
        textbutton "缩小" action Function(positioner.minus)
        textbutton "重置" action Function(positioner.reset)
        label "x轴"
        textbutton "放大" action Function(positioner.plus, y=False)
        textbutton "缩小" action Function(positioner.minus, y=False)
        label "y轴"
        textbutton "放大" action Function(positioner.plus, x=False)
        textbutton "缩小" action Function(positioner.minus, x=False)
    
    frame:
        background Color("#ffffff", alpha=0.3)
        align (0.98, 0.1)
        has vbox
        spacing 20

        label "状态"
        hbox:
            spacing 5
            text "名称:"
            add positioner.name_displayable
        text "位置: [positioner.pos]"
        text "大小: [positioner.size]"
        text "锁定: [positioner.lock]"
        text "显示: [positioner.show]"
        text "跟随: [positioner.follow_mouse]"
        label "操作"
        textbutton "锁定/解锁" action Function(positioner.toggle_lock)
        textbutton "显示/隐藏" action Function(positioner.toggle_show)
        textbutton "跟随/取消" action Function(positioner.toggle_follow_mouse)
        textbutton "修改定位工具名称" action Show("change_positioner_name", positioner=positioner)
        textbutton "修改定位工具颜色" action ShowMenu("color_picker", obj=positioner, field="color", default_color=positioner.color)
        textbutton "创建定位工具" action Function(positioner_group.create)
        textbutton "删除定位工具" action Function(positioner_group.remove, positioner)




color_picker 工具部分(由 Feniks @ feniksdev.com 提供)
[RenPy] 纯文本查看 复制代码
################################################################################
##
## Color Picker for Ren'Py by Feniks (feniksdev.itch.io / feniksdev.com)
##
################################################################################
## This file contains code for a colour picker in Ren'Py.
## If you use this code in your projects, credit me as Feniks @ feniksdev.com
##
## If you'd like to see how to use this tool, check the other file,
## color_picker_examples.rpy!
## You can also see this tool in action in the image tint tool, also on itch:
## [url=https://feniksdev.itch.io/image-tint-tool]https://feniksdev.itch.io/image-tint-tool[/url]
##
## Leave a comment on the tool page on itch.io or an issue on the GitHub
## if you run into any issues.
## [url=https://feniksdev.itch.io/color-picker-for-renpy]https://feniksdev.itch.io/color-picker-for-renpy[/url]
## [url=https://github.com/shawna-p/renpy-color-picker]https://github.com/shawna-p/renpy-color-picker[/url]
################################################################################
################################################################################
## SHADERS & TRANSFORMS
################################################################################
init python:
    ## A shader which creates a gradient for a colour picker.
    renpy.register_shader("feniks.color_picker", variables="""
        uniform vec4 u_gradient_top_right;
        uniform vec4 u_gradient_top_left;
        uniform vec4 u_gradient_bottom_left;
        uniform vec4 u_gradient_bottom_right;
        uniform vec2 u_model_size;
        varying float v_gradient_x_done;
        varying float v_gradient_y_done;
        attribute vec4 a_position;
    """, vertex_300="""
        v_gradient_x_done = a_position.x / u_model_size.x;
        v_gradient_y_done = a_position.y / u_model_size.y;
    """, fragment_300="""
        // Mix the two top colours
        vec4 top = mix(u_gradient_top_left, u_gradient_top_right, v_gradient_x_done);
        // Mix the two bottom colours
        vec4 bottom = mix(u_gradient_bottom_left, u_gradient_bottom_right, v_gradient_x_done);
        // Mix the top and bottom
        gl_FragColor = mix(bottom, top, 1.0-v_gradient_y_done);
    """)

    ## A shader which creates a spectrum. Generally for colour pickers.
    renpy.register_shader("feniks.spectrum", variables="""
        uniform float u_lightness;
        uniform float u_saturation;
        uniform float u_horizontal;
        uniform vec2 u_model_size;
        varying float v_gradient_x_done;
        varying float v_gradient_y_done;
        attribute vec4 a_position;
    """, vertex_300="""
        v_gradient_x_done = a_position.x / u_model_size.x;
        v_gradient_y_done = a_position.y / u_model_size.y;
    """, fragment_functions="""
    // HSL to RGB conversion adapted from
    // [url=https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion]https://stackoverflow.com/questi ... gb-color-conversion[/url]
    float hue2rgb(float p, float q, float t){
        if(t < 0.0) t += 1.0;
        if(t > 1.0) t -= 1.0;
        if(t < 1.0/6.0) return p + (q - p) * 6.0 * t;
        if(t < 1.0/2.0) return q;
        if(t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0;
        return p;
    }
    vec3 hslToRgb(float h, float l, float s) {
        float q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
        float p = 2.0 * l - q;
        float r = hue2rgb(p, q, h + 1.0/3.0);
        float g = hue2rgb(p, q, h);
        float b = hue2rgb(p, q, h - 1.0/3.0);
        return vec3(r, g, b);
    }
    """, fragment_300="""
        float hue = u_horizontal > 0.5 ? v_gradient_x_done : 1.0-v_gradient_y_done;
        vec3 rgb = hslToRgb(hue, u_lightness, u_saturation);
        gl_FragColor = vec4(rgb.r, rgb.g, rgb.b, 1.0);
    """)

## A transform which creates a spectrum.
## If horizontal is True, the spectrum goes from left to right instead of
## top to bottom. You can also adjust the lightness and saturation
## (between 0 and 1).
transform spectrum(horizontal=True, light=0.5, sat=1.0):
    shader "feniks.spectrum"
    u_lightness light
    u_saturation sat
    u_horizontal float(horizontal)

## A transform which creates a square with a gradient. By default, only the
## top right colour is required (to make a colour picker gradient) but four
## corner colours may also be provided clockwise from the top-right.
transform color_picker(top_right, bottom_right="#000", bottom_left="#000",
        top_left="#fff"):
    shader "feniks.color_picker"
    u_gradient_top_right Color(top_right).rgba
    u_gradient_top_left Color(top_left).rgba
    u_gradient_bottom_left Color(bottom_left).rgba
    u_gradient_bottom_right Color(bottom_right).rgba

################################################################################
## CLASSES AND FUNCTIONS
################################################################################
init python:

    import pygame
    class ColorPicker(renpy.Displayable):
        """
        A CDD which allows the player to pick a colour between four
        corner colours, with the typical setup used for a colour picker.

        Attributes
        ----------
        xsize : int
            The width of the colour picker.
        ysize : int
            The height of the colour picker.
        top_left : Color
            The colour of the top-left corner.
        top_right : Color
            The colour of the top-right corner.
        bottom_left : Color
            The colour of the bottom-left corner.
        bottom_right : Color
            The colour of the bottom-right corner.
        color : Color
            The current colour the colour picker is focused over.
        selector_xpos : float
            The xpos of the colour selector.
        selector_ypos : float
            The ypos of the colour selector.
        picker : Displayable
            A square that is used to display the colour picker.
        hue_rotation : float
            The amount the current hue is rotated by.
        dragging : bool
            True if the indicator is currently being dragged around.
        saved_colors : dict
            A dictionary of key - Color pairs corresponding to colours the
            picker has selected in the past.
        last_saved_color : any
            The dictionary key of the last colour saved.
        mouseup_callback : callable
            An optional callback or list of callbacks which will be called when
            the player lifts their mouse after selecting a colour.
        """
        RED = Color("#f00")
        def __init__(self, xsize, ysize, start_color=None, four_corners=None,
                saved_colors=None, last_saved_color=None, mouseup_callback=None,
                **kwargs):
            """
            Create a ColorPicker object.

            Parameters:
            -----------
            xsize : int
                The width of the colour picker.
            ysize : int
                The height of the colour picker.
            start_color : str
                A hexadecimal colour code corresponding to the starting colour.
            four_corners : tuple(Color, Color, Color, Color)
                A tuple of four colours corresponding to the four corners of the
                colour picker. The order is top right, bottom right, bottom
                left, top left. If this is not None, it will override the
                start_color parameter.
            saved_colors : dict
                A dictionary of key - Color pairs corresponding to colours
                the picker has selected in the past.
            last_saved_color : any
                The dictionary key of the last colour saved.
            mouseup_callback : callable
                An optional callback or list of callbacks which will be called
                when the player lifts their mouse after selecting a colour.
            """
            super(ColorPicker, self).__init__(**kwargs)
            self.xsize = xsize
            self.ysize = ysize

            self.top_left = None
            self.top_right = None
            self.bottom_left = None
            self.bottom_right = None

            self.last_saved_color = last_saved_color
            self.saved_colors = saved_colors or dict()
            self.mouseup_callback = mouseup_callback

            if start_color is None and four_corners is None:
                ## Automatically start with red
                self.set_color("#f00")
            elif four_corners is None:
                self.set_color(start_color)
            else:
                all_corners = [Color(c) if not isinstance(c, Color) else c for c in four_corners]
                self.top_right, self.bottom_right, self.bottom_left, self.top_left = all_corners
                self.set_color(self.top_right)

            self.picker = Transform("#fff", xysize=(self.xsize, self.ysize))
            self.dragging = False

            self.save_color(self.last_saved_color)

        def set_color(self, color):
            """
            Set the current colour of the colour picker.

            Parameters
            ----------
            color : Color
                The new colour to set the colour picker to.
            """
            if not isinstance(color, Color):
                self.color = Color(color)
            else:
                self.color = color
            self.dragging = False

            ## Check if this has four custom corners
            if self.top_left is None:
                ## No; set to saturation/value
                self.selector_xpos = round(self.color.hsv[1]*255.0)/255.0
                self.selector_ypos = 1.0 - round(self.color.hsv[2]*255.0)/255.0
                self._hue_rotation = self.color.hsv[0]
            else:
                ## There isn't a good way to guess the position of a colour
                ## with custom corners, so just set it to the top right
                self.selector_xpos = 1.0
                self.selector_ypos = 0.0
                self._hue_rotation = 0.0

        @property
        def hue_rotation(self):
            """
            The hue rotation of the colour picker.
            """
            return self._hue_rotation

        @hue_rotation.setter
        def hue_rotation(self, value):
            """
            Set the hue rotation of the colour picker.
            """
            if value > 1.0:
                value = value % 1.0
            if round(self._hue_rotation*255.0) == round(value*255):
                return
            self._hue_rotation = value
            self.update_hue()

        def set_saved_color(self, key, new_color):
            """
            Set the colour saved with key as the key to new_color.

            Parameters
            ----------
            key : any
                The key of the colour to change. Must be a valid dictionary key.
            new_color : Color
                The new colour to set the saved colour to.
            """
            if not isinstance(new_color, Color):
                self.saved_colors[key] = Color(new_color)
            else:
                self.saved_colors[key] = new_color

        def save_color(self, key):
            """
            Save the current colour to the saved dictionary with key as the key.
            """
            self.saved_colors[key] = self.color

        def get_color(self, key):
            """
            Retrieve the colour saved in the dictionary with key as the key.
            """
            return self.saved_colors.get(key, Color("#000"))

        def swap_to_saved_color(self, key):
            """
            Swap to the saved colour with key as the key.
            """
            self.set_color(self.saved_colors.get(key, Color("#000")))
            self.last_saved_color = key
            renpy.redraw(self, 0)

        def render(self, width, height, st, at):
            """
            Render the displayable to the screen.
            """
            r = renpy.Render(self.xsize, self.ysize)

            if self.top_left is None:
                trc = self.RED.rotate_hue(self.hue_rotation)
                # Colorize the picker into a gradient
                picker = At(self.picker, color_picker(trc))
            else:
                # Custom four corners; no spectrum sliders
                picker = At(self.picker, color_picker(
                    self.top_right.rotate_hue(self.hue_rotation),
                    self.bottom_right.rotate_hue(self.hue_rotation),
                    self.bottom_left.rotate_hue(self.hue_rotation),
                    self.top_left.rotate_hue(self.hue_rotation)))
            # Position the selector
            selector = Transform("selector", anchor=(0.5, 0.5),
                xpos=self.selector_xpos, ypos=self.selector_ypos)
            final = Fixed(picker, selector, xysize=(self.xsize, self.ysize))
            # Render it to the screen
            ren = renpy.render(final, self.xsize, self.ysize, st, at)
            r.blit(ren, (0, 0))
            return r

        def update_hue(self):
            """
            Update the colour based on the hue in the top-right corner
            (or in all 4 corners).
            """
            # Figure out the colour under the selector
            if self.top_left is None:
                trc = self.RED.rotate_hue(self.hue_rotation)
                tlc = Color("#fff")
                brc = Color("#000")
                blc = Color("#000")
            else:
                tlc = self.top_left.rotate_hue(self.hue_rotation)
                trc = self.top_right.rotate_hue(self.hue_rotation)
                brc = self.bottom_right.rotate_hue(self.hue_rotation)
                blc = self.bottom_left.rotate_hue(self.hue_rotation)

            self.color = tlc.interpolate(trc, self.selector_xpos)
            bottom = blc.interpolate(brc, self.selector_xpos)
            self.color = self.color.interpolate(bottom, self.selector_ypos)
            self.save_color(self.last_saved_color)
            renpy.redraw(self, 0)

        def event(self, ev, x, y, st):
            """Allow the user to drag their mouse to select a colour."""
            relative_x = round(x/float(self.xsize)*255.0)/255.0
            relative_y = round(y/float(self.ysize)*255.0)/255.0

            in_range = (0.0 <= relative_x <= 1.0) and (0.0 <= relative_y <= 1.0)

            if renpy.map_event(ev, "mousedown_1") and in_range:
                self.dragging = True
                self.selector_xpos = relative_x
                self.selector_ypos = relative_y
            elif ev.type == pygame.MOUSEMOTION and self.dragging:
                self.selector_xpos = relative_x
                self.selector_ypos = relative_y
            elif renpy.map_event(ev, "mouseup_1") and self.dragging:
                self.dragging = False
                ## Update the screen
                renpy.restart_interaction()
                if self.mouseup_callback is not None:
                    renpy.run(self.mouseup_callback, self)
                return
            else:
                return

            # Limit x/ypos
            self.selector_xpos = min(max(self.selector_xpos, 0.0), 1.0)
            self.selector_ypos = min(max(self.selector_ypos, 0.0), 1.0)
            self.update_hue()
            return None

    def picker_color(st, at, picker, xsize=100, ysize=100):
        """
        A DynamicDisplayable function to update the colour picker swatch.

        Parameters:
        -----------
        picker : ColorPicker
            The picker this swatch is made from.
        xsize : int
            The width of the swatch.
        ysize : int
            The height of the swatch.
        """
        return Transform(picker.color, xysize=(xsize, ysize)), 0.01

    def picker_hexcode(st, at, picker):
        """
        A brief DynamicDisplayable demonstration of how to display color
        information in real-time.
        """
        return Text(picker.color.hexcode, style='picker_hexcode'), 0.01

################################################################################
## IMAGES
################################################################################
init offset = -1
init python:
    def construct_selector(w=2, sz=5):
        """
        Constructs a white box surrounded by a black box, to use as a
        selector for the colour picker.

        Parameters
        ----------
        w : int
            The width of the lines.
        sz : int
            The size of the inner box.
        """
        ## First, the sides of the box
        box_leftright = [
            Transform("#000", xysize=(w, sz+2*3*w), align=(0.5, 0.5)),
            Transform("#fff", xysize=(w, sz+2*2*w), align=(0.5, 0.5)),
            Transform("#000", xysize=(w, sz+2*1*w), align=(0.5, 0.5)),
        ]
        ## Then the top and bottom
        box_topbottom = [
            Transform("#000", xysize=(sz+2*2*w, w), align=(0.5, 0.5)),
            Transform("#fff", xysize=(sz+2*1*w, w), align=(0.5, 0.5)),
            Transform("#000", xysize=(sz, w), align=(0.5, 0.5)),
        ]
        final_vbox = box_topbottom + [Null(height=sz)] + box_topbottom[::-1]
        final_hbox = (box_leftright + [Null(width=-w*2)]
            + [VBox(*final_vbox, style='empty', spacing=0)]
            + [Null(width=-w*2)] + box_leftright[::-1])
        ## Now put it together
        return HBox(*final_hbox, spacing=0, style='empty')

## These can be changed; see color_picker_examples.rpy for more.
## Feel free to remove the constructor function above if you don't use these.
## Used for both the spectrum thumb and the colour indicator.
image selector_img = construct_selector(2, 3)
image selector_bg = Frame("selector_img", 7, 7)
## The image used for the indicator showing the current colour.
image selector = Transform("selector_bg", xysize=(15, 15))

style picker_hexcode:
    color "#fff"
    font "DejaVuSans.ttf"






使用方式:
  • 复制源码放到游戏目录中的 rpy 脚本文件中将附件解压至游戏目录
  • 调用 position_helper 屏幕




使用示范:
  • 在界面中调用
    [RenPy] 纯文本查看 复制代码
    screen test():
        add mao align (0.5, 1.0)
        use position_helper()
  • 在脚本标签中使用
    [RenPy] 纯文本查看 复制代码
    show mao mtn_01
    call screen position_helper()
  • 特殊用法:传参任意数量的可视组件于 position_helper 中,则将按传入顺序逐一绘制






2024827-181701.jpg

Positioner.zip

7.21 KB, 阅读权限: 10, 下载次数: 2, 下载积分: 活力 100

评分

参与人数 2活力 +300 干货 +6 收起 理由
烈林凤 + 3 感谢分享!
被诅咒的章鱼 + 300 + 3 感谢分享!

查看全部评分

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-9-17 03:33 , Processed in 0.127632 second(s), 29 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表