Files
back_cantanBuilding/Assets/Scripts/UI/ScratchTicket/ScratchCard/ScratchCard.cs
2026-05-26 16:15:54 +08:00

577 lines
20 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 asap.core;
using cfg;
using DG.Tweening;
using GameCore;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace game
{
public class ScratchCard : MonoBehaviour, IBeginDragHandler, IDragHandler
{
[Header("Mask")]
public List<ScratchCardMaskUGUI> m_MaskList = new List<ScratchCardMaskUGUI>();
[SerializeField] private int m_CDFrame = 5;
[SerializeField] private string m_Ticket_Mask_Texture_Name = "sp_scratchticket_ticket_mask";
[Header("Brush")]
[SerializeField] private EditablePolygon m_OperatingArea;
[SerializeField] private GameObject m_BrushRoot;
[SerializeField] private Image m_Brush;
[SerializeField] private float m_BrushDurationTime = 1.0f;
[SerializeField] private float m_BrushSpeed = 1000.0f;
[SerializeField] private Material m_BrushMaterial;
[SerializeField] private Vector2 m_BrushSize = new Vector2(50f, 50f);
[SerializeField] private int m_InterpolationMaxCount = 4;
[SerializeField] private int m_InterpolationMinDistance = 8;
[SerializeField] private EventScratchTicketScratchType m_ScratchType = EventScratchTicketScratchType.TypeInvalid;
[Header("Animation")]
[SerializeField] private Animation m_Animation;
[SerializeField] private string m_Anim_Ticket_Out = "ticket_out";
[SerializeField] private float m_Anim_Ticket_Out_DurationTime = 1.1f;
[SerializeField] private CanvasGroup m_ShadowCanvasGroup;
[SerializeField] private CanvasGroup m_TicketCanvasGroup;
[Header("音效")]
[SerializeField] private List<OutPlaySound> m_ScratchOutPlaySoundList = new List<OutPlaySound>();
[SerializeField] private List<float> m_ScratchOutPlaySoundTimeList = new List<float>();
[Header("Toast相关")]
[SerializeField] private float m_ToastIntervalTime = 1.0f;
private int m_CumulativeFrame = 0;
private int m_MaskIndex = 0;
private float m_BrushCumulativeTime = 0f;
#region
private bool m_IsPlayingSound = false;
private float m_PlayingSoundTime = 0;
private float m_PlayingSoundCumulativeTime = 0f;
private void PlayScratchSound()
{
int count = m_ScratchOutPlaySoundList.Count;
if (count < 1) return;
foreach (var item in m_ScratchOutPlaySoundList)
{
if (item.gameObject.activeSelf)
{
item.gameObject.SetActive(false);
}
}
int index = UnityEngine.Random.Range(0, count);
m_IsPlayingSound = true;
m_PlayingSoundTime = m_ScratchOutPlaySoundTimeList[index];
m_PlayingSoundCumulativeTime = 0f;
m_ScratchOutPlaySoundList[index].gameObject.SetActive(true);
}
private void StopScratchSound()
{
foreach (var item in m_ScratchOutPlaySoundList)
{
item.gameObject.SetActive(false);
}
m_IsPlayingSound = false;
m_PlayingSoundTime = float.MaxValue;
m_PlayingSoundCumulativeTime = float.MinValue;
}
#endregion
#region ScratchCardMask
public void InitMaskList()
{
foreach (var item in m_MaskList)
{
item.InitMaskUGUI(m_BrushMaterial, m_BrushSize, m_InterpolationMaxCount, m_InterpolationMinDistance);
//item.RevealProgressChanged = OnRevealProgressChangedCallback;
}
}
private void OnRevealProgressChangedCallback(ScratchCardMask mask, float progress, bool isRevealed)
{
//Debug.LogError("--- ScratchCard OnRevealProgressChangedCallback mask:" + mask + ", progress:" + progress + ", isRevealed:" + isRevealed);
bool flag = true;
foreach (var item in m_MaskList)
{
if (!item.IsRevealed())
{
flag = false;
break;
}
}
//if (flag)
//{
// Debug.LogError("--- they have all revealed");
//}
//else
//{
// Debug.LogError("--- they have not all revealed");
//}
}
#endregion
#region Brush
private bool m_IsBrushPainting = false;
public void SetBrushPosition(Vector2 screenPosition)
{
if (!m_OperatingArea.ContainsPoint(screenPosition))
{
return;
}
RectTransformUtility.ScreenPointToLocalPointInRectangle(
transform as RectTransform,
screenPosition,
UIManager.Instance.UICanvas.worldCamera,
out Vector2 localPoint);
if (!m_Brush.gameObject.activeSelf)
{
m_Brush.gameObject.SetActive(true);
m_Brush.rectTransform.localPosition = localPoint;
}
float distance = Vector2.Distance(m_Brush.rectTransform.localPosition, localPoint);
float time = distance / m_BrushSpeed;
m_Brush.rectTransform.DOKill();
m_Brush.rectTransform.DOLocalMove(localPoint, time).SetEase(Ease.Linear);
//m_BrushCumulativeTime = 0f;
}
private void OnMaskBeginDrag()
{
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(UIManager.Instance.UICanvas.worldCamera, m_Brush.transform.position);
foreach (var item in m_MaskList)
{
item.OnMaskBeginDrag(screenPoint);
}
}
private void OnMaskDrag()
{
bool flag = false;
Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(UIManager.Instance.UICanvas.worldCamera, m_Brush.transform.position);
foreach (var item in m_MaskList)
{
if (item.OnMaskDrag(screenPoint))
{
flag = true;
}
}
//if (flag)
//{
// bool isAllRevealed = true;
// foreach (var item in m_MaskList)
// {
// if (!item.IsRevealed())
// {
// isAllRevealed = false;
// break;
// }
// }
// if (isAllRevealed)
// {
// Debug.LogError("=== ok");
// }
//}
}
#endregion
#region IBeginDragHandler + IDragHandler
public void OnBeginDrag(PointerEventData eventData)
{
if (m_ScratchType != EventScratchTicketScratchType.TypeScratch1) return;
//Debug.LogWarning("---- ScratchCard OnBeginDrag");
SetBrushPosition(eventData.position);
m_BrushCumulativeTime = 0f;
//foreach (var item in m_MaskList)
//{
// item.OnMaskBeginDrag(eventData.position);
//}
}
public void OnDrag(PointerEventData eventData)
{
if (m_ScratchType != EventScratchTicketScratchType.TypeScratch1) return;
//Debug.LogWarning("---- ScratchCard OnDrag");
SetBrushPosition(eventData.position);
m_BrushCumulativeTime = 0f;
//bool flag = false;
//foreach (var item in m_MaskList)
//{
// if (item.OnMaskDrag(eventData.position))
// {
// flag = true;
// }
//}
//if (flag)
//{
// bool isAllRevealed = true;
// foreach (var item in m_MaskList)
// {
// if (!item.IsRevealed())
// {
// isAllRevealed = false;
// break;
// }
// }
// if (isAllRevealed)
// {
// Debug.LogError("=== ok");
// }
//}
}
#endregion
#region TypeScratch1
private IEnumerator PlayTicketOutAnim(EventScratchTicketScratchType scratchType)
{
// 播放 m_Anim_Ticket_Out
m_Animation.Play(m_Anim_Ticket_Out);
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
// 重置 ScratchCard 图片资源并将ticket和shadow的alpha设置为1显示
foreach (var item in m_MaskList)
{
item.Restore();
//item.Reload();
}
m_ShadowCanvasGroup.alpha = 1.0f;
m_TicketCanvasGroup.alpha = 1.0f;
if (scratchType == EventScratchTicketScratchType.TypeScratch1)
{
FishingScratchTicketAct.Publish(new EventScratchTicketPanelPlayEndAnimData()
{
ScratchType = scratchType
});
}
else if (scratchType == EventScratchTicketScratchType.TypeScratch5)
{
FishingScratchTicketAct.Publish(new EventScratchTicketPlayScratchType5());
}
}
private IEnumerator PlayCardRevealedAnimInScratch1(EventScratchTicketScratchType scratchType)
{
// 隐藏笔刷
m_Brush.gameObject.SetActive(false);
// 确认奖励
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
if (scratchCard.DropReward == 0)
{
// 空奖
FishingScratchTicketAct.Publish(new EventScratchTicketRewardEmptyData()
{
ScratchType = EventScratchTicketScratchType.TypeScratch1
});
}
else
{
// 播放 m_Anim_Ticket_Out
m_Animation.Play(m_Anim_Ticket_Out);
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
// 重置 ScratchCard 图片资源并将ticket和shadow的alpha设置为1显示
foreach (var item in m_MaskList)
{
item.Restore();
//item.Reload();
}
m_ShadowCanvasGroup.alpha = 1.0f;
m_TicketCanvasGroup.alpha = 1.0f;
// RewardFly
FishingScratchTicketAct.Publish(new EventScratchTicketStampRewardFlyData()
{
ScratchType = scratchType,
SrcPosition = ticket_reward.transform.position,
LocalScale = ticket_reward.transform.localScale,
IconSize = ticket_reward.rectTransform.sizeDelta.x
});
}
}
#endregion
#region TypeScratch5
private IEnumerator PlayCardRevealedAnimInScratch5(EventScratchTicketScratchType scratchType)
{
// 隐藏笔刷
m_Brush.gameObject.SetActive(false);
// 确认奖励
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
if (scratchCard.DropReward == 0)
{
// 空奖
FishingScratchTicketAct.Publish(new EventScratchTicketRewardEmptyData()
{
ScratchType = scratchType
});
}
else
{
// 播放 m_Anim_Ticket_Out
m_Animation.Play(m_Anim_Ticket_Out);
yield return new WaitForSeconds(m_Anim_Ticket_Out_DurationTime);
// 重置 ScratchCard 图片资源并将ticket和shadow的alpha设置为1显示
foreach (var item in m_MaskList)
{
item.Restore();
//item.Reload();
}
m_ShadowCanvasGroup.alpha = 1.0f;
m_TicketCanvasGroup.alpha = 1.0f;
FishingScratchTicketAct.Publish(new EventScratchTicketPlayScratchType5());
}
}
#endregion
#region
private void InitEvent()
{
FishingScratchTicketAct.Subscribe<EventScratchTicketChangeScratchTypeData>(ChangeScratchType);
FishingScratchTicketAct.Subscribe<EventScratchTicketRevealedAllData>(OnScratchCardRevealedAll);
FishingScratchTicketAct.Subscribe<EventScratchTicketUpdateEventScratchCardData>(UpdateEventScratchCardData);
FishingScratchTicketAct.Subscribe<EventScratchTicketOutData>(OnEventScratchTicketOutDataListener);
}
private void OnEventScratchTicketOutDataListener(EventScratchTicketOutData data)
{
StartCoroutine(PlayTicketOutAnim(data.ScratchType));
}
private void UpdateEventScratchCardData(EventScratchTicketUpdateEventScratchCardData data)
{
var scratchCard = m_DataManager.GetCurrentEventScratchCard();
if (scratchCard == null) return;
var sprite = m_DataManager.GetSprite(scratchCard.Card);
ticket_reward.sprite = sprite;
ticket_maskCore.UpdateScratchCardMask(sprite.texture);
ticket_maskCore.Restore();
ticket_maskCore.SetThreshold(scratchCard.CorePercent);
ticket_mask.Restore();
}
private void OnScratchCardRevealedAll(EventScratchTicketRevealedAllData data)
{
StopScratchSound();
EventScratchCard scratchCard = m_DataManager.GetCurrentEventScratchCard();
if (scratchCard.DropReward > 0)
{
m_DataManager.AddScratchStamp(scratchCard.ID);
}
if (data.ScratchType == EventScratchTicketScratchType.TypeScratch1)
{
StartCoroutine(PlayCardRevealedAnimInScratch1(EventScratchTicketScratchType.TypeScratch1));
}
else if (data.ScratchType == EventScratchTicketScratchType.TypeScratch5)
{
StartCoroutine(PlayCardRevealedAnimInScratch5(EventScratchTicketScratchType.TypeScratch5));
}
}
private void ChangeScratchType(EventScratchTicketChangeScratchTypeData data)
{
m_ScratchType = data.ScratchType;
if (m_ScratchType != EventScratchTicketScratchType.TypeInvalid)
{
m_BrushRoot.SetActive(true);
m_Brush.gameObject.SetActive(false);
}
}
#endregion
#region UI
private Image ticket_reward;
private ScratchCardMaskUGUI ticket_maskCore;
private ScratchCardMaskUGUI ticket_mask;
private void InitUI()
{
ticket_reward = transform.Find("ticket_reward").GetComponent<Image>();
ticket_maskCore = transform.Find("ticket_maskCore").GetComponent<ScratchCardMaskUGUI>();
ticket_mask = transform.Find("ticket_mask").GetComponent<ScratchCardMaskUGUI>();
}
public void RefreshData()
{
UpdateEventScratchCardData(null);
}
#endregion
#region
private EventScratchTicketDataManager m_DataManager;
// Start is called before the first frame update
void Start()
{
m_DataManager = GContext.container.Resolve<EventScratchTicketDataManager>();
InitUI();
InitMaskList();
InitEvent();
RefreshData();
}
private bool m_IsToasting = false;
private float m_CumulativeToastIntervalTime = 0f;
private void Update()
{
if (m_ScratchType == EventScratchTicketScratchType.TypeInvalid)
{
if (Input.GetMouseButtonDown(0) || Input.GetMouseButton(0))
{
if (!m_IsToasting && m_OperatingArea.ContainsPoint(Input.mousePosition))
{
ToastPanel.Show(LocalizationMgr.GetText("UI_EventScratchTicketPanel_9"));
m_IsToasting = true;
m_CumulativeToastIntervalTime = 0f;
}
}
if (m_IsToasting)
{
if (m_CumulativeToastIntervalTime >= m_ToastIntervalTime)
{
m_CumulativeToastIntervalTime = 0f;
m_IsToasting = false;
}
else
{
m_CumulativeToastIntervalTime += Time.deltaTime;
}
}
}
if (m_ScratchType == EventScratchTicketScratchType.TypeScratch1)
{
bool flag = false;
if (!Input.GetMouseButtonDown(0) && !Input.GetMouseButton(0))
{
flag = true;
}
else if (!m_OperatingArea.ContainsPoint(Input.mousePosition))
{
flag = true;
}
if (flag)
{
if (m_BrushCumulativeTime >= m_BrushDurationTime)
{
if (m_Brush.gameObject.activeSelf)
{
m_Brush.gameObject.SetActive(false);
m_IsBrushPainting = false;
StopScratchSound();
}
}
else
{
m_BrushCumulativeTime += Time.deltaTime;
}
}
}
if (m_ScratchType != EventScratchTicketScratchType.TypeInvalid)
{
if (m_Brush.gameObject.activeSelf)
{
if (m_IsPlayingSound)
{
m_PlayingSoundCumulativeTime += Time.deltaTime;
if (m_PlayingSoundCumulativeTime >= m_PlayingSoundTime)
{
PlayScratchSound();
}
}
else
{
PlayScratchSound();
}
if (m_IsBrushPainting == false)
{
m_IsBrushPainting = true;
OnMaskBeginDrag();
}
else
{
OnMaskDrag();
}
}
}
}
private void LateUpdate()
{
if (m_ScratchType == EventScratchTicketScratchType.TypeInvalid || m_ScratchType == EventScratchTicketScratchType.TypeTemporary) return;
if (m_BrushRoot.activeInHierarchy == false || m_Brush.gameObject.activeSelf == false) return;
if (m_CumulativeFrame > m_CDFrame)
{
m_CumulativeFrame = 1;
m_MaskIndex = 0;
}
else
{
++m_CumulativeFrame;
}
int count = m_MaskList.Count;
int step = Mathf.CeilToInt((float)count / m_CDFrame);
int endIndex = m_MaskIndex + step;
while (m_MaskIndex < count && m_MaskIndex < endIndex)
{
m_MaskList[m_MaskIndex].UpdateTempTexture();
++m_MaskIndex;
}
bool flag = true;
foreach (var mask in m_MaskList)
{
if (!mask.IsRevealed())
{
flag = false;
break;
}
}
if (flag)
{
//Debug.LogError("--- all ok");
FishingScratchTicketAct.Publish(new EventScratchTicketRevealedAllData
{
ScratchType = m_ScratchType
});
m_ScratchType = EventScratchTicketScratchType.TypeTemporary;
}
}
#endregion
}
}