196 lines
6.5 KiB
C#
196 lines
6.5 KiB
C#
using UnityEngine;
|
|
using TMPro;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace AibisDream.MiniGame.HuoShan
|
|
{
|
|
/// <summary>
|
|
/// 背景文字层 - 生成和管理大量随机变化的文字,文字间寻找关联形成词语连线
|
|
/// </summary>
|
|
public class BackgroundTextLayer
|
|
{
|
|
private List<TextNode> _allNodes;
|
|
private List<string> _chineseChars;
|
|
private float _fieldWidth;
|
|
private float _fieldHeight;
|
|
private int _nodeCount;
|
|
private Transform _parentTransform;
|
|
private GameObject _textPrefab;
|
|
|
|
// 文字变化参数
|
|
private float _changeInterval = 0.5f;
|
|
private float _lastChangeTime;
|
|
|
|
// 连线参数
|
|
private float _connectionRadius = 2f;
|
|
private float _connectionProbability = 0.3f;
|
|
|
|
public BackgroundTextLayer(float fieldWidth, float fieldHeight, int nodeCount, Transform parentTransform)
|
|
{
|
|
_fieldWidth = fieldWidth;
|
|
_fieldHeight = fieldHeight;
|
|
_nodeCount = nodeCount;
|
|
_parentTransform = parentTransform;
|
|
_allNodes = new List<TextNode>();
|
|
|
|
// 初始化中文字符集
|
|
InitializeChineseChars();
|
|
|
|
// 创建文字预制体
|
|
CreateTextPrefab();
|
|
|
|
// 生成初始节点
|
|
GenerateNodes();
|
|
}
|
|
|
|
private void InitializeChineseChars()
|
|
{
|
|
_chineseChars = new List<string>();
|
|
// 常用中文字符(可以扩展)
|
|
for (int i = 0x4e00; i <= 0x9fff; i++)
|
|
{
|
|
_chineseChars.Add(char.ConvertFromUtf32(i));
|
|
}
|
|
// 添加一些常用字
|
|
_chineseChars.AddRange(new[] { "的", "是", "在", "了", "和", "有", "就", "不", "人", "都", "一", "一个", "上", "也", "很", "到", "说", "要", "去", "你", "会", "着", "没有", "看", "好", "自己", "这" });
|
|
}
|
|
|
|
private void CreateTextPrefab()
|
|
{
|
|
_textPrefab = new GameObject("TextNodePrefab");
|
|
_textPrefab.hideFlags = HideFlags.HideAndDontSave;
|
|
|
|
var textMesh = _textPrefab.AddComponent<TextMeshPro>();
|
|
textMesh.fontSize = 24;
|
|
textMesh.alignment = TextAlignmentOptions.Center;
|
|
textMesh.color = Color.white;
|
|
textMesh.enableWordWrapping = false;
|
|
textMesh.overflowMode = TextOverflowModes.Overflow;
|
|
|
|
_textPrefab.SetActive(false);
|
|
}
|
|
|
|
private void GenerateNodes()
|
|
{
|
|
for (int i = 0; i < _nodeCount; i++)
|
|
{
|
|
Vector2 randomPos = new Vector2(
|
|
Random.Range(-_fieldWidth * 0.5f, _fieldWidth * 0.5f),
|
|
Random.Range(-_fieldHeight * 0.5f, _fieldHeight * 0.5f)
|
|
);
|
|
|
|
string randomChar = _chineseChars[Random.Range(0, _chineseChars.Count)];
|
|
TextNode node = new TextNode(randomPos, randomChar);
|
|
|
|
// 创建GameObject
|
|
GameObject nodeObj = Object.Instantiate(_textPrefab, _parentTransform);
|
|
nodeObj.SetActive(true);
|
|
nodeObj.name = $"TextNode_{i}";
|
|
node.GameObject = nodeObj;
|
|
node.TextComponent = nodeObj.GetComponent<TextMeshPro>();
|
|
|
|
node.UpdateVisual();
|
|
_allNodes.Add(node);
|
|
}
|
|
|
|
// 建立初始连接关系
|
|
UpdateConnections();
|
|
}
|
|
|
|
public void Update(float deltaTime)
|
|
{
|
|
_lastChangeTime += deltaTime;
|
|
|
|
if (_lastChangeTime >= _changeInterval)
|
|
{
|
|
_lastChangeTime = 0f;
|
|
|
|
// 随机改变一些文字(排除已选定的和候选的)
|
|
foreach (var node in _allNodes)
|
|
{
|
|
if (node.State == TextNodeState.Random)
|
|
{
|
|
// 随机改变文字
|
|
if (Random.value < 0.1f) // 10%概率改变
|
|
{
|
|
node.Text = _chineseChars[Random.Range(0, _chineseChars.Count)];
|
|
node.UpdateVisual();
|
|
}
|
|
|
|
// 随机改变亮度
|
|
node.Brightness = Random.Range(0.3f, 1f);
|
|
node.UpdateVisual();
|
|
}
|
|
}
|
|
|
|
// 更新连接关系
|
|
UpdateConnections();
|
|
}
|
|
}
|
|
|
|
private void UpdateConnections()
|
|
{
|
|
// 清除所有连接
|
|
foreach (var node in _allNodes)
|
|
{
|
|
node.ConnectedNodes.Clear();
|
|
}
|
|
|
|
// 重新建立连接(基于距离和概率)
|
|
for (int i = 0; i < _allNodes.Count; i++)
|
|
{
|
|
for (int j = i + 1; j < _allNodes.Count; j++)
|
|
{
|
|
var nodeA = _allNodes[i];
|
|
var nodeB = _allNodes[j];
|
|
|
|
float distance = Vector2.Distance(nodeA.Position, nodeB.Position);
|
|
|
|
if (distance < _connectionRadius && Random.value < _connectionProbability)
|
|
{
|
|
nodeA.AddConnection(nodeB);
|
|
nodeB.AddConnection(nodeA);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<TextNode> GetAllNodes()
|
|
{
|
|
return _allNodes;
|
|
}
|
|
|
|
public List<TextNode> GetNodesInRange(Vector2 center, float radius)
|
|
{
|
|
return _allNodes.Where(node =>
|
|
Vector2.Distance(node.Position, center) <= radius
|
|
).ToList();
|
|
}
|
|
|
|
public void SetNodeState(TextNode node, TextNodeState state)
|
|
{
|
|
node.State = state;
|
|
node.UpdateVisual();
|
|
}
|
|
|
|
public void Cleanup()
|
|
{
|
|
foreach (var node in _allNodes)
|
|
{
|
|
if (node.GameObject != null)
|
|
{
|
|
Object.Destroy(node.GameObject);
|
|
}
|
|
}
|
|
_allNodes.Clear();
|
|
|
|
if (_textPrefab != null)
|
|
{
|
|
Object.Destroy(_textPrefab);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|