refactor color system

This commit is contained in:
bridge
2025-11-17 23:24:37 +08:00
parent d5e8ad0ac9
commit 5ae2538d86
9 changed files with 140 additions and 27 deletions

View File

@@ -35,6 +35,11 @@ class Auxiliary:
def get_detailed_info(self) -> str:
"""获取详细信息"""
return f"{self.name}{self.grade}{self.desc}"
def get_colored_info(self) -> str:
"""获取带颜色标记的信息,供前端渲染使用"""
r, g, b = self.grade.color_rgb
return f"<color:{r},{g},{b}>{self.get_info()}</color>"
def _load_auxiliaries() -> tuple[Dict[int, Auxiliary], Dict[str, Auxiliary], Dict[int, Auxiliary]]:

View File

@@ -585,18 +585,11 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
from src.classes.root import format_root_cn
add_kv(lines, "灵根", format_root_cn(self.root))
if self.technique is not None:
tech_str = f"{self.technique.name}{self.technique.attribute}·{self.technique.grade.value}"
else:
tech_str = ""
tech_str = self.technique.get_colored_info() if self.technique is not None else ""
add_kv(lines, "功法", tech_str)
if self.personas:
# 使用颜色标记格式:<color:R,G,B>text</color>
persona_parts = []
for p in self.personas:
r, g, b = p.rarity.color_rgb
persona_parts.append(f"<color:{r},{g},{b}>{p.name}</color>")
persona_parts = [p.get_colored_info() for p in self.personas]
add_kv(lines, "特质", ", ".join(persona_parts))
add_kv(lines, "位置", f"({self.pos_x}, {self.pos_y})")
@@ -619,16 +612,14 @@ class Avatar(AvatarSaveMixin, AvatarLoadMixin):
# 兵器(必有,使用颜色标记等级)
if self.weapon is not None:
r, g, b = self.weapon.grade.color_rgb
weapon_text = f"<color:{r},{g},{b}>{self.weapon.get_info()}</color>"
weapon_text = self.weapon.get_colored_info()
if self.weapon.desc:
weapon_text += f"{self.weapon.desc}"
add_kv(lines, "兵器", weapon_text)
# 辅助装备(可选,使用颜色标记等级)
if self.auxiliary is not None:
r, g, b = self.auxiliary.grade.color_rgb
auxiliary_text = f"<color:{r},{g},{b}>{self.auxiliary.get_info()}</color>"
auxiliary_text = self.auxiliary.get_colored_info()
if self.auxiliary.desc:
auxiliary_text += f"{self.auxiliary.desc}"
add_kv(lines, "辅助装备", auxiliary_text)

92
src/classes/color.py Normal file
View File

@@ -0,0 +1,92 @@
"""
颜色系统
统一管理游戏中各种等级、稀有度的颜色方案
"""
from typing import Protocol
class ColorGradable(Protocol):
"""支持颜色分级的协议"""
@property
def color_rgb(self) -> tuple[int, int, int]:
"""返回RGB颜色值"""
...
# ==================== 通用颜色定义 ====================
class Color:
"""预定义的颜色常量"""
# 基础颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 品质颜色 - 从低到高
COMMON_WHITE = (255, 255, 255) # 普通/白色
UNCOMMON_GREEN = (50, 205, 50) # 不凡/绿色
RARE_BLUE = (74, 144, 226) # 稀有/蓝色
EPIC_PURPLE = (147, 112, 219) # 史诗/紫色
LEGENDARY_GOLD = (255, 215, 0) # 传说/金色
# ==================== 辅助函数 ====================
def get_color_from_mapping(
grade_value: object,
color_mapping: dict,
default_color: tuple[int, int, int] = Color.COMMON_WHITE
) -> tuple[int, int, int]:
"""
从映射字典中获取颜色
Args:
grade_value: 等级对象
color_mapping: 等级到颜色的映射字典
default_color: 默认颜色
Returns:
RGB颜色元组
"""
return color_mapping.get(grade_value, default_color)
def format_colored_text(text: str, color_rgb: tuple[int, int, int]) -> str:
"""
将文本格式化为带颜色标记的字符串,供前端渲染使用
格式:<color:R,G,B>text</color>
Args:
text: 要着色的文本
color_rgb: RGB颜色元组
Returns:
带颜色标记的文本字符串
"""
r, g, b = color_rgb
return f"<color:{r},{g},{b}>{text}</color>"
# ==================== 颜色方案映射 ====================
# 装备等级颜色方案(普通-宝物-法宝)
EQUIPMENT_GRADE_COLORS = {
"COMMON": Color.COMMON_WHITE,
"TREASURE": Color.EPIC_PURPLE,
"ARTIFACT": Color.LEGENDARY_GOLD,
}
# 稀有度颜色方案N-R-SR-SSR
RARITY_COLORS = {
"N": Color.COMMON_WHITE,
"R": Color.RARE_BLUE,
"SR": Color.EPIC_PURPLE,
"SSR": Color.LEGENDARY_GOLD,
}
# 功法品阶颜色方案(下品-中品-上品)
TECHNIQUE_GRADE_COLORS = {
"LOWER": Color.COMMON_WHITE,
"MIDDLE": Color.UNCOMMON_GREEN,
"UPPER": Color.EPIC_PURPLE,
}

View File

@@ -1,4 +1,5 @@
from enum import Enum
from src.classes.color import Color, EQUIPMENT_GRADE_COLORS
class EquipmentGrade(Enum):
@@ -15,13 +16,10 @@ class EquipmentGrade(Enum):
@property
def color_rgb(self) -> tuple[int, int, int]:
"""返回装备等级对应的RGB颜色值"""
return _grade_colors.get(self, (200, 200, 200))
# 装备等级颜色映射
_grade_colors = {
EquipmentGrade.COMMON: (255, 255, 255), # 白色
EquipmentGrade.TREASURE: (138, 43, 226), # 紫色
EquipmentGrade.ARTIFACT: (255, 215, 0), # 金色
}
color_map = {
EquipmentGrade.COMMON: EQUIPMENT_GRADE_COLORS["COMMON"],
EquipmentGrade.TREASURE: EQUIPMENT_GRADE_COLORS["TREASURE"],
EquipmentGrade.ARTIFACT: EQUIPMENT_GRADE_COLORS["ARTIFACT"],
}
return color_map.get(self, Color.COMMON_WHITE)

View File

@@ -37,6 +37,11 @@ class Persona:
def get_detailed_info(self) -> str:
return f"{self.name}{self.desc}"
def get_colored_info(self) -> str:
"""获取带颜色标记的信息,供前端渲染使用"""
r, g, b = self.rarity.color_rgb
return f"<color:{r},{g},{b}>{self.name}</color>"
def _load_personas() -> tuple[dict[int, Persona], dict[str, Persona]]:
"""从配表加载persona数据"""

View File

@@ -4,6 +4,7 @@
"""
from enum import Enum
from dataclasses import dataclass
from src.classes.color import Color, RARITY_COLORS
class RarityLevel(Enum):
@@ -35,28 +36,28 @@ RARITY_CONFIGS = {
RarityLevel.N: Rarity(
level=RarityLevel.N,
weight=10.0,
color_rgb=(255, 255, 255), # 白色
color_rgb=RARITY_COLORS["N"],
color_hex="#FFFFFF",
chinese_name="普通"
),
RarityLevel.R: Rarity(
level=RarityLevel.R,
weight=5.0,
color_rgb=(74, 144, 226), # 蓝色
color_rgb=RARITY_COLORS["R"],
color_hex="#4A90E2",
chinese_name="稀有"
),
RarityLevel.SR: Rarity(
level=RarityLevel.SR,
weight=3.0,
color_rgb=(147, 112, 219), # 紫色
color_rgb=RARITY_COLORS["SR"],
color_hex="#9370DB",
chinese_name="超稀有"
),
RarityLevel.SSR: Rarity(
level=RarityLevel.SSR,
weight=1.0,
color_rgb=(255, 215, 0), # 金色
color_rgb=RARITY_COLORS["SSR"],
color_hex="#FFD700",
chinese_name="传说"
),

View File

@@ -5,6 +5,7 @@ from enum import Enum
from typing import Optional, Dict, List
import json
from src.classes.effect import load_effect_from_str
from src.classes.color import Color, TECHNIQUE_GRADE_COLORS
from src.utils.df import game_configs
from src.classes.alignment import Alignment
@@ -40,6 +41,16 @@ class TechniqueGrade(Enum):
if s == "中品":
return TechniqueGrade.MIDDLE
return TechniqueGrade.LOWER
@property
def color_rgb(self) -> tuple[int, int, int]:
"""返回功法品阶对应的RGB颜色值"""
color_map = {
TechniqueGrade.LOWER: TECHNIQUE_GRADE_COLORS["LOWER"],
TechniqueGrade.MIDDLE: TECHNIQUE_GRADE_COLORS["MIDDLE"],
TechniqueGrade.UPPER: TECHNIQUE_GRADE_COLORS["UPPER"],
}
return color_map.get(self, Color.COMMON_WHITE)
@dataclass
@@ -66,6 +77,11 @@ class Technique:
def get_detailed_info(self) -> str:
return f"{self.name}{self.attribute}{self.grade.value} {self.desc}"
def get_colored_info(self) -> str:
"""获取带颜色标记的信息,供前端渲染使用"""
r, g, b = self.grade.color_rgb
return f"<color:{r},{g},{b}>{self.name}{self.attribute}·{self.grade.value}</color>"
# 五行与扩展属性的克制关系
# - 五行:金克木,木克土,土克水,水克火,火克金

View File

@@ -45,6 +45,11 @@ class Weapon:
if self.name == "万魂幡" and self.special_data.get("devoured_souls", 0) > 0:
souls = f" 吞噬魂魄:{self.special_data['devoured_souls']}"
return f"{self.name}{self.weapon_type}·{self.grade}{self.desc}{souls}"
def get_colored_info(self) -> str:
"""获取带颜色标记的信息,供前端渲染使用"""
r, g, b = self.grade.color_rgb
return f"<color:{r},{g},{b}>{self.get_info()}</color>"
def _load_weapons() -> tuple[Dict[int, Weapon], Dict[str, Weapon], Dict[int, Weapon]]: