找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 43|回复: 0

[教程] 能力雷达图

[复制链接]
发表于 昨天 17:51 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 leech 于 2025-7-18 18:48 编辑

写的一个小东西,一个能力雷达图
已经把大部分调整数值的都留了接口,直接用完事,注释都写好了
其实最开始没打算发,因为B站魔理沙大佬已经出过视频讲过思路了
不过她似乎并没有给出源码,然后论坛也没有看到过

                               
登录/注册后可看大图

所以我发一下
可能细节和魔理沙佬的不太一样,但思路应该都一样
我是直接没有做特别的美化什么的,学CDD的时候瞎琢磨的
[RenPy] 纯文本查看 复制代码
init python:
    import math
    class RadarChart(renpy.Displayable):
        def __init__(self,points,values,levels=1,max_value=10,size=400,colors=None,**kwargs):
            super(RadarChart, self).__init__(**kwargs)
            self.points = points
            self.texts = list(values.keys())
            self.nums = list(values.values())
            self.levels = levels
            self.max_value = max_value
            self.size = size
            self.colors = colors or ["#a646ffd0", "#6085ffd0", "#ffffff"]
            
        def render(self,width,height,st,at):
            render = renpy.Render(self.size,self.size)
            canvas = render.canvas()
            
            center = (self.size // 2, self.size // 2)
            # 绘制背景,动态计算顶点位置 (N边形)
            radius = self.size // 2 - 20
            points = []
            for i in range(self.points):
                angle = 2 * math.pi * i / self.points - math.pi / 2  # 保持顶部为起点
                x = center[0] + radius * math.cos(angle)
                y = center[1] + radius * math.sin(angle)
                points.append((x, y))
            canvas.polygon(self.colors[0],points)

            # 轴
            for point in points:
                canvas.line(self.colors[1],center,point,width=2)
            # 绘制蜘蛛网状网格
            for n in range(1, self.levels + 1):
                scale = n / self.levels  # 缩放比例
                grid_points = []
                for i in range(self.points):
                    angle = 2 * math.pi * i / self.points - math.pi / 2
                    x = center[0] + (radius * scale) * math.cos(angle)
                    y = center[1] + (radius * scale) * math.sin(angle)
                    grid_points.append((x, y))
                canvas.polygon(self.colors[1],grid_points,width=2)
            
            # 绘制数据区域
            data_points = []
            for i, value in enumerate(self.nums):
                scaled_radius = radius * (value / self.max_value)
                angle = 2 * math.pi * i /len(self.nums) - math.pi / 2
                x = center[0] + scaled_radius * math.cos(angle)
                y = center[1] + scaled_radius * math.sin(angle)
                data_points.append((x, y))
            canvas.polygon(self.colors[1],data_points)
            # 描个边
            canvas.polygon(self.colors[1],data_points,width=2)

            # 顶点上垂直排列的文本组
            group_radius = radius + self.size*0.05
            for i, (label, value) in enumerate(zip(self.texts, self.nums)):
                angle = 2 * math.pi * i / len(self.texts) - math.pi / 2
                x = center[0] + group_radius * math.cos(angle)
                y = center[1] + group_radius * math.sin(angle)
                
                # 预计算文本尺寸
                label_text = Text(label, color=self.colors[2], size=self.size*0.05,align=(0.5,0.5))
                value_text = Text(str(value), color=self.colors[2], size=self.size*0.05,align=(0.5,0.5))
                label_width, label_height = label_text.size()
                value_width, value_height = value_text.size()
                
                # 确定VBox总尺寸
                group_width = max(label_width, value_width)
                group_height = label_height + value_height
                
                # 创建固定尺寸的VBox
                text_group = VBox(
                    label_text,
                    value_text,
                    xysize=(group_width, group_height),
                    align=(0.5,0.5)
                )
                
                # 渲染
                render.blit(
                    renpy.render(text_group, width, height, st, at),
                    (x - group_width/2, y - group_height/2)
                )
            
            return render

# 示例数据,只有points和values是必要入参,其他的有默认
image character_stats = RadarChart(
    points=6,                                                            #正N边形
    values={"攻击": 12,"防御": 6, "速度": 9,"技巧": 7,"耐力": 5,"智力": 1},#数值字典,以正N边形顺时针排列,如果数值的数量不对应#正N边形,会出现有意思的错位效果
    levels=6,                                                            #雷达图中的蛛网纹路层级,是美化用的,这里是6层蛛网纹路
    max_value=10,                                                        #最大的数值,如果提供的数值超过最大数值,会出现有意思的错位效果
    size=400,                                                            #整个图的尺寸
    colors=["#a646ffd0", "#6085ffd0", "#ffffff"]                   #颜色列表,背景色,纹路色,文字色
)

label show_stats:
    show character_stats:
        anchor(0.5,0.5)
        pos(0.5,0.5)
    "这是角色的能力雷达图。"
    hide character_stats








评分

参与人数 1活力 +300 干货 +3 收起 理由
烈林凤 + 300 + 3 感谢分享!

查看全部评分

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

本版积分规则

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

GMT+8, 2025-7-19 14:14 , Processed in 0.048555 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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