使用Javascript创建类Cryptopunk NFT时rarity稀有度函数不生效求助
HashLips generative-art-node 稀有度不生效解决方案
- 补充稀有度权重配置
你当前src/config.js里只定义了稀有度后缀和名称的映射,没有配置对应的出现概率权重,这是最常见的失效原因。
修改config.js新增权重配置,示例如下:
// 原有rarity配置保留 const rarity = [ { key: "", val: "original" }, { key: "_r", val: "rare" }, { key: "_sr", val: "super rare" }, ]; // 新增稀有度权重,数值越大出现概率越高,总和不需要为100,按比例计算 const rarityWeights = { "original": 70, "rare": 25, "super rare": 5 } // 导出的时候把rarityWeights加进去 module.exports = { layersOrder, format, rarity, rarityWeights, defaultEdition };
- 修正main.js中的属性选择逻辑
项目默认的属性选择如果是普通随机取样,不会用到权重,需要替换为带权重的随机选择函数,找到main.js中选择层元素的代码段,替换为如下逻辑:
// 先导入新增的rarityWeights const { layersOrder, format, rarity, rarityWeights, defaultEdition } = require("./config.js"); // 新增带权重的随机选择函数 const getWeightedRandom = (items, weights) => { const totalWeight = weights.reduce((acc, w) => acc + w, 0); let random = Math.random() * totalWeight; for (let i = 0; i < items.length; i++) { random -= weights[i]; if (random <= 0) return items[i]; } return items[items.length - 1]; } // 处理单个层的元素选择时,先给每个元素计算对应权重 const getLayerElement = (layer) => { const elements = layer.elements; // 给每个元素匹配对应稀有度的权重 const elementWeights = elements.map(el => { const rarityLevel = rarity.find(r => el.name.endsWith(r.key))?.val || "original"; return rarityWeights[rarityLevel]; }); return getWeightedRandom(elements, elementWeights); }
验证文件命名规则
确保所有图层资源的命名严格匹配config中定义的后缀:- 普通属性直接命名为
属性名.png,不要加任何后缀 - 稀有属性命名为
属性名_r.png - 超稀有属性命名为
属性名_sr.png
注意后缀大小写要和config里的key完全一致,不要出现大写的_R、_SR这类命名,会导致匹配失败默认按original权重处理。
- 普通属性直接命名为
结果验证
生成完成后可以写简单脚本统计所有元数据里的属性出现频率,确认稀有属性的出现概率符合你设置的权重。
内容的提问来源于stack exchange,提问作者bondadde
相关产品推荐
相关产品推荐

