using System.Collections.Generic;
using UnityEngine;
///
/// 运行时美术生成(普通类):
/// 不读取任何预制体/资源文件,用代码生成棋子圆底图、空心圆环等 Sprite
///
public static class ChessArtFactory
{
private static readonly Dictionary cache = new Dictionary();
///
/// 实心圆(棋子底图:米色主体 + 深棕外圈,边缘抗锯齿)
///
public static Sprite GetCircleSprite(int size = 128)
{
return GetCached("circle_" + size, size, (x, y, c, r) =>
{
float d = Vector2.Distance(new Vector2(x, y), new Vector2(c, c));
float alpha = Mathf.Clamp01(r + 0.5f - d);
if (alpha <= 0) return Color.clear;
Color fill = new Color32(0xF7, 0xEB, 0xD3, 0xFF);
Color rim = new Color32(0x4E, 0x34, 0x2E, 0xFF);
float rimWidth = r * 0.08f;
Color col = d > r - rimWidth ? rim : fill;
col.a = alpha;
return col;
});
}
///
/// 空心圆环(选中圈 / 吃子提示,白色,由 Image.color 上色)
///
public static Sprite GetRingSprite(int size = 128)
{
return GetCached("ring_" + size, size, (x, y, c, r) =>
{
float d = Vector2.Distance(new Vector2(x, y), new Vector2(c, c));
float inner = r * 0.78f;
float outer = r * 0.98f;
float alpha = Mathf.Clamp01(d - inner + 1.5f) * Mathf.Clamp01(outer - d + 1.5f);
return alpha <= 0 ? Color.clear : new Color(1f, 1f, 1f, alpha);
});
}
///
/// 实心小圆点(白色,由 Image.color 上色)
///
public static Sprite GetDotSprite(int size = 64)
{
return GetCached("dot_" + size, size, (x, y, c, r) =>
{
float d = Vector2.Distance(new Vector2(x, y), new Vector2(c, c));
float alpha = Mathf.Clamp01(r + 0.5f - d);
return alpha <= 0 ? Color.clear : new Color(1f, 1f, 1f, alpha);
});
}
///
/// 走子提示点(绿色实心圆,颜色已烘焙进图里,使用时不再染色)
///
public static Sprite GetHintDotSprite(int size = 64)
{
return GetCached("hintdot_" + size, size, (x, y, c, r) =>
{
float d = Vector2.Distance(new Vector2(x, y), new Vector2(c, c));
float alpha = Mathf.Clamp01(r + 0.5f - d) * 0.90f;
return alpha <= 0 ? Color.clear : new Color(0.26f, 0.66f, 0.31f, alpha);
});
}
///
/// 吃子提示圈(红色空心圆环,颜色已烘焙进图里,使用时不再染色)
///
public static Sprite GetCaptureRingSprite(int size = 128)
{
return GetCached("capturering_" + size, size, (x, y, c, r) =>
{
float d = Vector2.Distance(new Vector2(x, y), new Vector2(c, c));
float inner = r * 0.78f;
float outer = r * 0.98f;
float alpha = Mathf.Clamp01(d - inner + 1.5f) * Mathf.Clamp01(outer - d + 1.5f) * 0.95f;
return alpha <= 0 ? Color.clear : new Color(0.91f, 0.25f, 0.20f, alpha);
});
}
private delegate Color PixelFunc(int x, int y, float center, float radius);
private static Sprite GetCached(string key, int size, PixelFunc func)
{
Sprite sp;
if (cache.TryGetValue(key, out sp) && sp != null) return sp;
var tex = new Texture2D(size, size, TextureFormat.RGBA32, false)
{
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Bilinear
};
float c = (size - 1) * 0.5f;
float r = size * 0.5f - 1f;
var pixels = new Color[size * size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
pixels[y * size + x] = func(x, y, c, r);
tex.SetPixels(pixels);
tex.Apply();
sp = Sprite.Create(tex, new Rect(0, 0, size, size), new Vector2(0.5f, 0.5f), 100f);
cache[key] = sp;
return sp;
}
}