using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using Random = UnityEngine.Random;
public class LotteryDemo : MonoBehaviour
{
public static LotteryDemo instance;
public static int[] textArray;
public static Dictionary<int, Texture2D> textMap = new Dictionary<int, Texture2D>();
public static int[] DebristextArray;
public static Dictionary<int, Texture2D> DebristextMap = new Dictionary<int, Texture2D>();
public Camera worldCamera;
public float forceFactor = 1;
public Action del = null;
public bool slideMode = false; //默认是点击模式(单抽),滑动模式请打开(十连抽)
public float defaultVelocity = 50;
public float slideVelocity = 10;
public float minSlideDistance = 100;
bool isForbiden = true;
public float inAreaRadius = 100; //最小影响半径
public int outAreaRadius = 1500; //滑动时,最大影响半径,在这个半径内线性衰减到0
public int minDragSpeed = 100;
public int maxDragSpeed = 1000;
public int dragSpeedFactor = 100;
public List<int> heroIds; //抽卡结果,如果只有一个值,则表示为单抽
public List<int> qualitys;//抽卡的品质
public List<bool> existing;//已经拥有的卡片
private int waitingCount; //还需要等待几个才能完成
public Action startCb;
public Action overCb;
public Action<int> selectSummonHero;
Vector3 startTouchPos;//开始拖动的屏幕位置
float startTouchTime; //开始拖动的时间
private bool IsSummoned = false;
CardCtr[] cards;
public float changeDebrisDelay = 0.5f;
private GameObject clickEff;
private GameObject clickEff2;
private static Queue<GameObject> usedBall = new Queue<GameObject>();//使用过的质量球
private static Dictionary<int, Queue<GameObject>> qualityBallPool = new Dictionary<int, Queue<GameObject>>();//质量球对象池
private static Dictionary<int, GameObject> qualityBallGO = new Dictionary<int, GameObject>();//质量球类型
private static Queue<GameObject> changeDebrisPool = new Queue<GameObject>(); //转换碎片对象池
private static GameObject changeDebriEff;// = new GameObject();//转换碎片特效
private static Queue<GameObject> usedDebrisPool = new Queue<GameObject>();//使用过的碎片特效
private void InitEffect()
{
qualityBallPool.Add(1, new Queue<GameObject>());//green
qualityBallPool.Add(2, new Queue<GameObject>());//blue
qualityBallPool.Add(3, new Queue<GameObject>());//purple
qualityBallPool.Add(4, new Queue<GameObject>());//yellow
qualityBallGO.Add(1, Resources.Load("UIEffects/Eff_GJUI_chouka_GreenLoop") as GameObject);//green
qualityBallGO.Add(2, Resources.Load("UIEffects/Eff_GJUI_chouka_BlueLoop") as GameObject);//blue
qualityBallGO.Add(3, Resources.Load("UIEffects/Eff_GJUI_chouka_PurpleLoop") as GameObject);//purple
qualityBallGO.Add(4, Resources.Load("UIEffects/Eff_GJUI_chouka_YellowLoop") as GameObject);//yellow
}
void Start(){
instance = this;
isForbiden = true;
cards = GetComponentsInChildren<CardCtr>();
LoadHeadImage();
InitEffect();
var cameraData = worldCamera.GetUniversalAdditionalCameraData();
cameraData.renderType = CameraRenderType.Overlay;
clickEff = Instantiate(Resources.Load("UIEffects/Eff_GJUI_chouka_YellowBOOM")) as GameObject;//Eff_GJUI_chouka_YellowBOOM
clickEff.transform.parent = this.transform;
clickEff.SetActive(false);
clickEff2 = Instantiate(Resources.Load("UIEffects/Eff_GJUI_chouka_huadong")) as GameObject;
clickEff2.name = "zheshiyigedianji";
clickEff2.transform.parent = this.transform;
clickEff2.SetActive(false);
changeDebriEff = Resources.Load("UIEffects/Eff_GJUI_suipianzhuanhua") as GameObject;
changeDebriEff.SetActive(false);
}
public void SetBoolFalse()
{
this.IsSummoned = false;
}
#region 质量球对象池
/// <summary>
/// 根据type得到一个球
/// </summary>
public static void GetOneQualityBallByType(int qualityType, Transform t)
{
//因为代码会遗留上次抽卡的质量值,所以抽卡结束后质量值设置成99,如果质量值是99 则不得到球,
if (qualityType == 99 || qualityType == 0)
{
return;
}
if (qualityBallPool[qualityType].Count <= 0)
{
GameObject go = Instantiate(qualityBallGO[qualityType], t);
go.name = qualityType.ToString();
go.transform.position = t.position - new Vector3(0, 0, 0.05f);
go.transform.localScale = new Vector3(1.22f, 1.22f, 1.22f);
usedBall.Enqueue(go);
}
else
{
GameObject go = qualityBallPool[qualityType].Dequeue();
go.transform.position = t.position - new Vector3(0, 0, 0.05f);
go.transform.localScale = new Vector3(1.22f, 1.22f, 1.22f);
usedBall.Enqueue(go);
}
}
/// <summary>
/// 移除一个球到对象池
/// </summary>
public static void RemoveOneQualityBall(GameObject go)
{
go.transform.position = new Vector3(9999, 0, 0);
qualityBallPool[Int32.Parse(go.name)].Enqueue(go);
}
/// <summary>
/// 移除所有的球到对象池
/// </summary>
public void ReMoveAllQualityBalls()
{
int count = usedBall.Count;
if (count > 0)
{
for (int i = 0; i < count; i++)
{
GameObject go = usedBall.Dequeue();
RemoveOneQualityBall(go);
}
}
}
/// <summary>
/// 得到一个特效
/// </summary>
public void GetOneDebriEff(Transform t)
{
if (changeDebrisPool.Count <= 0)
{
GameObject go = Instantiate(changeDebriEff, t);
go.SetActive(true);
//go.name = qualityType.ToString();
go.transform.position = t.position- new Vector3(0, 0, 0.05f);
go.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
usedDebrisPool.Enqueue(go);
}
else
{
GameObject go = changeDebrisPool.Dequeue();
go.SetActive(true);
go.transform.position = t.position- new Vector3(0, 0, 0.05f);
go.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
usedDebrisPool.Enqueue(go);
}
}
/// <summary>
/// 移除一个球到对象池
/// </summary>
public void RemoveOneDebri(GameObject go)
{
go.SetActive(false);
go.transform.position = new Vector3(9999, 0, 0);
changeDebrisPool.Enqueue(go);
}
/// <summary>
/// 移除所有的球到对象池
/// </summary>
public void ReMoveAllDebris()
{
int count = usedDebrisPool.Count;
if (count > 0)
{
for (int i = 0; i < count; i++)
{
GameObject go = usedDebrisPool.Dequeue();
RemoveOneDebri(go);
}
}
}
#endregion
public void LoadHeadImage()
{
Texture2D[] images = Resources.LoadAll<Texture2D>("UIImage/Summon/card");
textArray = new int[images.Length];
for (int i = 0; i < images.Length; i++)
{
int id = int.Parse(images[i].name);
textArray[i] = id;
textMap[id] = images[i];
}
Texture2D[] Debrisimages = Resources.LoadAll<Texture2D>("UIImage/Summon/cardDebris");
DebristextArray = new int[Debrisimages.Length];
for (int i = 0; i < Debrisimages.Length; i++)
{
int id = int.Parse(Debrisimages[i].name);
DebristextArray[i] = id;
DebristextMap[id] = Debrisimages[i];
}
}
public void initCardAction(Action one,Action ten){
}
void ApplyHitForce(ref RaycastHit hitInfo, Vector3 forcePoint)
{
clickEff.SetActive(true);
clickEff.transform.position = forcePoint;
GameObject go = hitInfo.collider.gameObject;
//Vector3 screenPos = worldCamera.WorldToScreenPoint(go.transform.position);
float deltaX = forcePoint.x - go.transform.position.x;
float deltaY = forcePoint.y - go.transform.position.y;
Vector3 rotation = new Vector3(deltaX ,deltaY,0);
float weight = Mathf.Pow(1 + rotation.magnitude,2);
float N = weight * forceFactor * 10;
CardCtr card = go.GetComponentInChildren<CardCtr>();
Debug.LogError(N);
waitingCount = 1;
card.setTarget(N, rotation, heroIds[0],qualitys[0], existing[0]);
heroIds = null;
}
public void setCards(List<int> list, List<int> Qualitys,List<bool> existing, Action startFun,Action overFunc,Action<int> SelectSummonHero){
this.startCb = startFun;
this.overCb = overFunc;
this.selectSummonHero = SelectSummonHero;
this.isForbiden = false;
this.slideMode = list.Count >= 10 ;
this.heroIds = list;
this.qualitys = Qualitys;
this.existing = existing;
ResetAll();
this.IsSummoned = false;
}
float GetAreaForce(float distance)
{
if (distance > outAreaRadius)
{
distance = outAreaRadius;
}
if (distance < inAreaRadius)
return 1;
float ret = (outAreaRadius - distance) / (outAreaRadius - inAreaRadius);
return Mathf.Max(0.1f, ret * ret);
}
float GetSpeedFactor(float speed)
{
if (speed > maxDragSpeed)
{
return dragSpeedFactor;
}
if (speed < minDragSpeed)
{
speed = minDragSpeed;
}
float result = (outAreaRadius - speed) / (outAreaRadius - inAreaRadius);
return Mathf.Max(0.1f,result*result)* dragSpeedFactor;
}
public void ResetAll()
{
CardCtr[] arr = gameObject.GetComponentsInChildren<CardCtr>();
for (int i = 0; i < arr.Length; i++)
{
arr[i].ResetRotation();
arr[i].HeroId = 0;
}
ReMoveAllQualityBalls();
ReMoveAllDebris();
SetDebriFalse();
}
/// <summary>
/// 设置成false防止下次全亮
/// </summary>
public void SetDebriFalse()
{
foreach (CardCtr item in cards)
{
item.isDebris = false;
}
}
public void OneCardOver()
{
waitingCount--;
if (waitingCount == 0)
{
this.overCb();
clickEff.SetActive(false);
clickEff2.SetActive(false);
this.IsSummoned = true;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0)&&IsSummoned)
{
Vector3 hitPos = Input.mousePosition;
var ray = worldCamera.ScreenPointToRay(hitPos);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 100, 1 << LayerMask.NameToLayer("Default")))
{
CardCtr cc = hitInfo.transform.GetComponent<CardCtr>();
selectSummonHero(cc.HeroId);
//print(hitInfo.collider.gameObject.name);
}
}
if (this.isForbiden){
return;
}
bool leftDown = Input.GetMouseButtonDown(0);
bool leftUp = Input.GetMouseButtonUp(0);
bool leftHold = Input.GetMouseButton(0);
Vector3 pos = Input.mousePosition;
if (Input.touchSupported)
{
if (Input.touchCount > 0){
leftDown = (Input.GetTouch(0).phase == TouchPhase.Began);
leftUp = (Input.GetTouch(0).phase == TouchPhase.Ended);
leftHold = (Input.GetTouch(0).phase == TouchPhase.Moved);
}
}
if (leftDown)
{
clickEff2.SetActive(true);
startTouchPos = pos;
startTouchTime = Time.time;
return;
}
if (!slideMode) {
if (leftUp && heroIds!=null)
{
Vector3 hitPos = pos;
var ray = worldCamera.ScreenPointToRay(hitPos);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 100, 1 << LayerMask.NameToLayer("Default")))
{
ApplyHitForce(ref hitInfo, hitInfo.point);
}
}
}
else
{
Vector3 curPos = pos;
if (leftHold) //拖动中
{
Vector3 point = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 2f);
clickEff2.transform.position = worldCamera.ScreenToWorldPoint(point);
Vector3 deltaPos = curPos - startTouchPos;
if (deltaPos.x == 0 && deltaPos.y == 0)
{
return;
}
Vector3 rotation = new Vector2(deltaPos.y, -deltaPos.x);
for (int i = 0; i < cards.Length; i++)
{
CardCtr card = cards[i];
GameObject go = cards[i].gameObject;
Vector3 screen_go = worldCamera.WorldToScreenPoint(go.transform.position);
float dist = (screen_go - curPos).magnitude;
float areaForce = GetAreaForce(dist);
float factor = areaForce * 90 * Mathf.Min(1,(rotation.magnitude/outAreaRadius*2));
card.Drag(factor, rotation);
}
}
else if (leftUp) // 释放
{
Vector3 deltaPos = curPos - startTouchPos;
float timeDelta = Time.time - startTouchTime;
float speed = GetSpeedFactor(deltaPos.magnitude / timeDelta);
if(Math.Sqrt(deltaPos.sqrMagnitude) < minSlideDistance){
ResetAll();
}else{
this.isForbiden = true;
if(this.startCb != null){
this.startCb();
}
Vector3 rotation =new Vector2(deltaPos.y,-deltaPos.x);
for(int i=0;i<cards.Length;i++){
CardCtr card = cards[i];
GameObject go = cards[i].gameObject;
Vector3 screen_go = worldCamera.WorldToScreenPoint(go.transform.position);
float dist = GetAreaForce((screen_go - curPos).magnitude) ;
dist += GetAreaForce((screen_go - startTouchPos).magnitude);
//float factor = dist * forceFactor * rotation.magnitude;
float factor = dist * forceFactor * speed;
//Debug.LogError(factor);
card.setTarget(factor, rotation,heroIds.Count >i? heroIds[i]:0,qualitys[i], existing[i]);
waitingCount = 10;
}
}
}
}
}
public void Dispose()
{
usedBall.Clear();
qualityBallPool.Clear();
qualityBallGO.Clear();
}
public void ChangeDebris()
{
StartCoroutine(changeDebris());
}
IEnumerator changeDebris()
{
yield return new WaitForSeconds(changeDebrisDelay);
foreach (CardCtr item in cards)
{
bool bl = item.ChangeDebris();
if (bl)
{
//创建一个特效
GetOneDebriEff(item.gameObject.transform);
}
}
}
}
内含一些对象池的代码类
最新推荐文章于 2024-11-03 19:28:13 发布