428 lines
17 KiB
C#
428 lines
17 KiB
C#
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;
|
||
} |