Files
Chef-s-Solitaire_Unity_IOS/Assets/Resources/Card/CreatCard.cs
T
2026-06-18 14:04:23 +08:00

428 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}