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; } }