Files
Chef-s-Solitaire_Unity_IOS/Assets/Resources/Card/CreatCard.cs
T

428 lines
17 KiB
C#
Raw Normal View History

2026-06-18 14:04:23 +08:00
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using MYp0ZVTT2QSDK;
using NPOI.SS.Formula.Functions;
using UnityEngine;
public class CreatCard : MonoBehaviour
{
private Dictionary<string, Material> materialDict;
public Camera main_camera;
// private List<GameObject> Card_gameobject_list = new List<GameObject>();
// Start is called before the first frame update
private int _sortingOrder = 0;
private int hand_card_num = -1;
Vector3 hand_card_pos = new Vector3(2.3f, -6, 0);
Vector3 dark_hand_card_pos = new Vector3(0.3f, -6, 0);
void Awake()
{
float size = (float)System.Math.Round(4.5f / ((float)Screen.width / Screen.height), 4);
string type = SystemInfo.deviceModel.ToLower().Trim();
// Debug.Log($"type==========={type}");
if (type.Substring(0, 3) == "ipa")
{//iPad机型
size = 49.9f;
}
main_camera.orthographicSize = size;
}
void Start()
{
card_item = Resources.Load<GameObject>("card/card_item");
Material[] materials = Resources.LoadAll<Material>("Card/poker_material");
// 初始化字典
materialDict = new Dictionary<string, Material>();
foreach (Material mat in materials)
{
if (!materialDict.ContainsKey(mat.name))
{
materialDict.Add(mat.name, mat);
// Debug.Log("Loaded material: " + mat.name);
}
}
// 使用示例:通过名字获取材质球
// if (materialDict.TryGetValue("poker_back", out Material backMat))
// {
// // 给某个 MeshRenderer 应用材质
// GetComponent<MeshRenderer>().material = backMat;
// }
CreatCardFunction();
CheckCanClick();
}
void CreatCardFunction()
{
for (int i = 0; i < cards.Count; i++)
{
GameObject temp = Instantiate(card_item, cards[i].initial_position, Quaternion.Euler(cards[i].initial_rotation), gameObject.transform);
temp.name = i.ToString();
Debug.Log(cards[i].suit);
Debug.Log(cards[i].number);
string color_ = null;
if (cards[i].suit == 0 || cards[i].suit == 1)
{
color_ = "black";
}
else
{
color_ = "red";
}
if (materialDict.TryGetValue("num_" + color_ + "_small_" + cards[i].number, out Material backMat))
{
// 给某个 MeshRenderer 应用材质
temp.transform.Find("small").GetComponent<MeshRenderer>().material = backMat;
}
if (materialDict.TryGetValue("num_" + color_ + "_big_" + cards[i].number, out Material backMat1))
{
// 给某个 MeshRenderer 应用材质
temp.transform.Find("big").GetComponent<MeshRenderer>().material = backMat1;
}
if (materialDict.TryGetValue("suit_" + cards[i].suit, out Material backMat2))
{
// 给某个 MeshRenderer 应用材质
temp.transform.Find("suit").GetComponent<MeshRenderer>().material = backMat2;
}
cards[i]._gameObject = temp;
if (cards[i].is_dark_hand)
{
dark_hand_cards_list.Add(cards[i]);
}
if (cards[i].is_hand)
{
cards[i]._gameObject.transform.eulerAngles = new Vector3(0, 180, 0);
cards[i]._gameObject.transform.position = hand_card_pos;
hand_card_num = cards[i].number;
}
}
// 就地排序(从大到小)
dark_hand_cards_list.Sort((a, b) => b.initial_position.z.CompareTo(a.initial_position.z));
int index = 0;
for (int i = dark_hand_cards_list.Count - 1; i >= 0; i--)
{
dark_hand_cards_list[i]._gameObject.transform.eulerAngles = Vector3.zero;
dark_hand_cards_list[i]._gameObject.transform.position = new Vector3(dark_hand_card_pos.x + index * (-0.1f), dark_hand_card_pos.y, dark_hand_cards_list[i]._gameObject.transform.position.z);
index++;
}
}
void CheckCanClick(bool showAnima = false)
{
// List<Renderer> allRenderers = new List<Renderer>();
// for (int i = 0; i < Card_gameobject_list.Count; i++)
// {
// Renderer render = Card_gameobject_list[i].GetComponentInChildren<Renderer>();
// allRenderers.Add(render);
// }
// for (int i = 0; i < Card_gameobject_list.Count; i++)
// {
// if (IsCovered(allRenderers[i], allRenderers, main_camera))
// {
// Debug.Log(Card_gameobject_list[i].name);
// Card_gameobject_list[i].transform.rotation = Quaternion.Euler(new Vector3(0, 0, Card_gameobject_list[i].transform.rotation.z));
// }
// }
for (int i = 0; i < cards.Count; i++)
{
bool is_cover = false;
if (cards[i].is_hand || cards[i].is_dark_hand) continue;
for (int j = 0; j < cards.Count; j++)
{
if (cards[j].is_hand || cards[j].is_dark_hand) continue;
if (cards[i] == cards[j]) continue;
if (cards[j]._gameObject.transform.position.z > cards[i]._gameObject.transform.position.z)
{
continue;
}
if (IsIntersect(cards[j], cards[i]))//被盖住了
{
is_cover = true;
break;
}
}
if (!is_cover)//正面
{
if (cards[i].isBack)
{
if (!showAnima) cards[i]._gameObject.transform.Rotate(0f, 180f, 0f, Space.Self);
else
{
cards[i]._gameObject.transform
.DOLocalRotate(new Vector3(0, 180, 0), 0.5f, RotateMode.LocalAxisAdd);
}
cards[i].isBack = false;
}
}
else//背面
{
}
}
}
void HitCard(string card_name)
{
int index = int.Parse(card_name);
// cards[index]._gameObject
if (dark_hand_cards_list.Count > 0 && cards[index] == dark_hand_cards_list[dark_hand_cards_list.Count - 1])
{
Debug.Log("????????????????????????????????");
Transform t = cards[index]._gameObject.transform;
t.DOLocalMove(hand_card_pos, 0.3f);
t.DOLocalRotate(new Vector3(0, -180, 0), 0.3f, RotateMode.LocalAxisAdd);
t.DOScale(1.1f, 0.15f).SetEase(Ease.OutBack).OnComplete(() =>
{
t.DOScale(1f, 0.15f).SetEase(Ease.InQuad);
});
// .DOLocalRotate(new Vector3(0, 180, 0), 0.5f, RotateMode.LocalAxisAdd);
cards[index].is_hand = true;
hand_card_num = cards[index].number;
Renderer[] _render_ = cards[index]._gameObject.transform.GetComponentsInChildren<Renderer>();
for (int i = 0; i < _render_.Length; i++)
{
// _render_[i].material.renderQueue = renderQueue;
_render_[i].sortingOrder = _sortingOrder;
_sortingOrder++;
}
dark_hand_cards_list.RemoveAt(dark_hand_cards_list.Count - 1);
}
else
{
if (cards[index].isBack)
{
return;
}
if (!numberCanClick(cards[index].number))
{
return;
}
cards[index]._gameObject.transform.DOLocalMove(hand_card_pos, 0.3f);
cards[index]._gameObject.transform.DOLocalRotate(new Vector3(0, 180, 0), 0.3f);
cards[index].is_hand = true;
Renderer[] _render_ = cards[index]._gameObject.transform.GetComponentsInChildren<Renderer>();
for (int i = 0; i < _render_.Length; i++)
{
// _render_[i].material.renderQueue = renderQueue;
_render_[i].sortingOrder = _sortingOrder;
_sortingOrder++;
}
DOVirtual.DelayedCall(0.5f, () =>
{
CheckCanClick(true);
});
}
}
bool numberCanClick(int _number)
{
Debug.Log("dianjide" + _number);
Debug.Log("xianzaide" + hand_card_num);
if (hand_card_num < 0)
{
hand_card_num = _number;
return true;
}
if (hand_card_num == 13 && (_number == 1 || _number == 12))
{
hand_card_num = _number;
return true;
}
if (hand_card_num == 1 && (_number == 13 || _number == 2))
{
hand_card_num = _number;
return true;
}
if ((hand_card_num == (_number - 1)) || (hand_card_num == (_number + 1)))
{
hand_card_num = _number;
return true;
}
return false;
}
public static bool IsIntersect(CardInfo a, CardInfo b)
{
float w = 1.12f, h = 1.64f;
Vector2[] rectA = GetCorners(a.initial_position, w, h, a.initial_rotation.z);
Vector2[] rectB = GetCorners(b.initial_position, w, h, b.initial_rotation.z);
// 在 Scene 里画出来
DrawRect(rectA, Color.red);
DrawRect(rectB, Color.green);
List<Vector2> axes = new List<Vector2>();
for (int i = 0; i < 4; i++)
{
Vector2 edgeA = rectA[(i + 1) % 4] - rectA[i];
axes.Add(edgeA.normalized);
}
for (int i = 0; i < 4; i++)
{
Vector2 edgeB = rectB[(i + 1) % 4] - rectB[i];
axes.Add(edgeB.normalized);
}
foreach (var axis in axes)
{
(float minA, float maxA) = Project(rectA, axis);
(float minB, float maxB) = Project(rectB, axis);
// Debug.Log($"Axis {axis}: A[{minA},{maxA}] B[{minB},{maxB}]");
// 加容差避免边界误判
if (maxA < minB - 1e-6 || maxB < minA - 1e-6)
return false;
}
return true;
}
private static Vector2[] GetCorners(Vector2 center, float w, float h, float angleDeg)
{
float angle = angleDeg * Mathf.Deg2Rad; // 度转弧度
Vector2[] corners = new Vector2[4];
Vector2[] offsets = {
new Vector2(-w/2, -h/2), new Vector2(w/2, -h/2),
new Vector2(w/2, h/2), new Vector2(-w/2, h/2)
};
for (int i = 0; i < 4; i++)
{
float x = Mathf.Cos(angle) * offsets[i].x - Mathf.Sin(angle) * offsets[i].y;
float y = Mathf.Sin(angle) * offsets[i].x + Mathf.Cos(angle) * offsets[i].y;
corners[i] = center + new Vector2(x, y);
}
return corners;
}
private static (float min, float max) Project(Vector2[] corners, Vector2 axis)
{
float min = float.MaxValue, max = float.MinValue;
foreach (var p in corners)
{
float proj = Vector2.Dot(p, axis);
min = Mathf.Min(min, proj);
max = Mathf.Max(max, proj);
}
return (min, max);
}
private static void DrawRect(Vector2[] corners, Color color)
{
for (int i = 0; i < 4; i++)
{
Vector2 p1 = corners[i];
Vector2 p2 = corners[(i + 1) % 4]; // 下一个点,最后一个点连回第一个
Debug.DrawLine(p1, p2, color, 100f, false);
}
}
private GameObject card_item;
private GameObject Popup;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// if (Popup == null) Popup = GameObject.Find("Popup");
// if (Popup.transform.childCount != 0) return;
Ray ray = main_camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
int layerMask = 1 << 6; // 只与第6层的碰撞器碰撞
// 如果射线与layerMask指定层的碰撞器发生碰撞
if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask))
{
Debug.Log("Hit " + hit.collider.transform.parent.gameObject.name);
HitCard(hit.collider.transform.parent.gameObject.name);
// GameDispatcher.Instance.Dispatch(GameMsg.card_click, hit.collider.gameObject.name);
}
}
if (Input.GetMouseButtonDown(1))
{
Debug.Log("chehui");
}
}
List<CardInfo> dark_hand_cards_list = new List<CardInfo>();
List<CardInfo> cards = new List<CardInfo>
{
// 上层半圆
new CardInfo { number = 7, suit = 0, initial_position = new Vector3(-4.2f, 2.5f, -0.10f), initial_rotation = new Vector3(0,0,-25f), isBack = true, is_dark_hand = false },
new CardInfo { number = 11, suit = 3, initial_position = new Vector3(-2.95f, 2.22f, -1.10f), initial_rotation = new Vector3(0,0,-18f), isBack = true, is_dark_hand = false },
new CardInfo { number = 12, suit = 2, initial_position = new Vector3(-1.5f, 3.0f, -2.10f), initial_rotation = new Vector3(0,0,-8f), isBack = true, is_dark_hand = false },
new CardInfo { number = 8, suit = 1, initial_position = new Vector3(0.0f, 3.1f, -3.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = false },
new CardInfo { number = 10, suit = 0, initial_position = new Vector3(1.5f, 3.0f, -4.10f), initial_rotation = new Vector3(0,0,8f), isBack = true, is_dark_hand = false },
new CardInfo { number = 9, suit = 2, initial_position = new Vector3(3.0f, 2.7f, -5.10f), initial_rotation = new Vector3(0,0,18f), isBack = true, is_dark_hand = false },
new CardInfo { number = 13, suit = 1, initial_position = new Vector3(4.2f, 2.5f, -6.10f), initial_rotation = new Vector3(0,0,25f), isBack = true, is_dark_hand = false },
// 下层覆盖
new CardInfo { number = 5, suit = 0, initial_position = new Vector3(-4.4f, 0.9f, -7.10f), initial_rotation = new Vector3(0,0,-20f), isBack = true, is_dark_hand = false },
new CardInfo { number = 6, suit = 1, initial_position = new Vector3(-2.2f, 2.5f, -8.10f), initial_rotation = new Vector3(0,0,-10f), isBack = true, is_dark_hand = false },
new CardInfo { number = 3, suit = 2, initial_position = new Vector3(-0.5f, 2.7f, -9.10f), initial_rotation = new Vector3(0,0,-3f), isBack = true, is_dark_hand = false },
new CardInfo { number = 4, suit = 3, initial_position = new Vector3(1.0f, 2.7f, -10.10f), initial_rotation = new Vector3(0,0,3f), isBack = true, is_dark_hand = false },
new CardInfo { number = 2, suit = 0, initial_position = new Vector3(2.5f, 2.5f, -11.10f), initial_rotation = new Vector3(0,0,10f), isBack = true, is_dark_hand = false },
new CardInfo { number = 1, suit = 3, initial_position = new Vector3(3.9f, 2.2f, -12.10f), initial_rotation = new Vector3(0,0,20f), isBack = true, is_dark_hand = false,is_hand=true },
// 底部单张
new CardInfo { number = 9, suit = 2, initial_position = new Vector3(0f, 0.5f, -13.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = false },
// 新增十张(is_dark_hand = true
new CardInfo { number = 1, suit = 0, initial_position = new Vector3(-5f, 1f, -14.10f), initial_rotation = new Vector3(0,0,-30f), isBack = true, is_dark_hand = true },
new CardInfo { number = 2, suit = 1, initial_position = new Vector3(-3.5f, 1.2f, -15.10f), initial_rotation = new Vector3(0,0,-20f), isBack = true, is_dark_hand = true },
new CardInfo { number = 3, suit = 2, initial_position = new Vector3(-2f, 1.5f, -16.10f), initial_rotation = new Vector3(0,0,-10f), isBack = true, is_dark_hand = true },
new CardInfo { number = 4, suit = 3, initial_position = new Vector3(-0.5f, 1.8f, -17.10f), initial_rotation = new Vector3(0,0,0f), isBack = true, is_dark_hand = true },
new CardInfo { number = 5, suit = 0, initial_position = new Vector3(1f, 2.0f, -18.10f), initial_rotation = new Vector3(0,0,10f), isBack = true, is_dark_hand = true },
new CardInfo { number = 6, suit = 1, initial_position = new Vector3(2.5f, 2.2f, -19.10f), initial_rotation = new Vector3(0,0,20f), isBack = true, is_dark_hand = true },
new CardInfo { number = 7, suit = 2, initial_position = new Vector3(4f, 2.4f, -20.10f), initial_rotation = new Vector3(0,0,30f), isBack = true, is_dark_hand = true },
new CardInfo { number = 8, suit = 3, initial_position = new Vector3(-4f, 0.5f, -21.10f), initial_rotation = new Vector3(0,0,-15f), isBack = true, is_dark_hand = true },
new CardInfo { number = 9, suit = 0, initial_position = new Vector3(-2f, 0.7f, -22.10f), initial_rotation = new Vector3(0,0,-5f), isBack = true, is_dark_hand = true },
new CardInfo { number = 10, suit = 1, initial_position = new Vector3(0f, 0.9f, -23.10f), initial_rotation = new Vector3(0,0,5f), isBack = true, is_dark_hand = true },
};
}
[System.Serializable]
public class CardInfo
{
public int number; // 1-13 (A-K)
public int suit; // 0-3 (♣♠♦♥)
public Vector3 initial_position; // 卡牌位置 (x, y, z)
public Vector3 initial_rotation; // 卡牌旋转 (Euler角)
public bool isBack; // 是否显示背面,默认 true
public GameObject _gameObject;
public bool is_hand;
public bool is_dark_hand;
}