577 lines
20 KiB
C#
577 lines
20 KiB
C#
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
|
||
}
|
||
}
|