using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace DuckHunter
{
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
[SerializeField] GameObject dogObject;
[SerializeField] GameObject dogSideObject;
[SerializeField] GameObject duckPrefab;
[SerializeField] RectTransform duckBox;
[System.NonSerialized] public bool isGameStarted;
[System.NonSerialized] public bool isGameOver;
public bool isGamePlaying { get => isGameStarted && !isGameOver; }
public System.Action onGameStart;
public UserGameAnalyse1 userGameAnalyse1;
void Awake()
{
Instance = this;
dogObject.SetActive(true);
if (!AutoNextLevel)
{
//如果调试页面存在,使用duckHunterLevel
DefaultLevel = InfraredDemo._ins ? (int)InfraredDemo._ins.duckHunterLevel.Get(): 1;
_CumulativeScore = 0;
}
level = DefaultLevel;
uploadScore = 0;
}
void OnDestroy()
{
if (Instance == this) Instance = null;
}
void Start()
{
TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_START);
if (AutoNextLevel)
{
AutoNextLevel = false;
StartGame(true);
}
userGameAnalyse1 = UserGameAnalyse1.CreateWhenGameStartAndReturn(13);
}
void Update()
{
UpdateCheckMouseHit();
UpdateForAutoCreateDucks();
SettleGame();
#if UNITY_EDITOR
if (Input.GetKeyDown(KeyCode.A))
{
Time.timeScale = 10;
}
if (Input.GetKeyUp(KeyCode.A))
{
Time.timeScale = 1;
}
#endif
}
void UpdateCheckMouseHit()
{
if (Input.GetMouseButtonDown(0) && BowCamera.isTouchMode)
{
if (EventSystem.current.currentSelectedGameObject == null)
{
CrossHair.Instance.transform.position = Input.mousePosition;
OnModuleShooting(10);
}
}
}
///
/// 基础初速度
///
public static float BaseFlySpeed = 50;
///
/// 下次从多少分开始
///
public static int DefaultLevel = 1;
private static bool AutoNextLevel = false;
[System.NonSerialized] public int hitScore; //得分
private int uploadScore;//上传服务器的分数
private bool bAddCountScore = false;
[System.NonSerialized] public int level = 1;
///
/// 通关需要击落的鸭子数量
///
int passNeedHitCount;
int needCreateDuckCount;
bool canCreateDuck;
[System.NonSerialized] public int theDuckCountWaitingForDogHandle;
float _createDuckInterval;
void UpdateForAutoCreateDucks()
{
if (isGameOver) return;
if (!canCreateDuck) return;
_createDuckInterval = 0;
if (level <= 9)//60
{
if (theDuckCountWaitingForDogHandle > 0) return;
}
else if (level <= 13)//80
{
if (theDuckCountWaitingForDogHandle > 0) _createDuckInterval = 5;
if (theDuckCountWaitingForDogHandle > 1) return;
}
else //<=100
{
if (theDuckCountWaitingForDogHandle > 0) _createDuckInterval = 5;
if (theDuckCountWaitingForDogHandle > 2) return;
}
if (!Dog.Instance || Dog.Instance.isShowing) return;
if (Time.time - _lastCreateDuckTime < _createDuckInterval) return;
CreateDuck();
}
List _ductTypeList = null;
///
/// 生成野鸭,并且打乱数组
///
/// 绿色数量
/// 蓝色数量
/// 红色数量
void InitDuckTypeList(int greenCount, int blueCount, int redCount)
{
if (_ductTypeList != null) return;
_ductTypeList = new List();
for (int i = 0; i < greenCount; i++) _ductTypeList.Add(1);
for (int i = 0; i < blueCount; i++) _ductTypeList.Add(4);//2
for (int i = 0; i < redCount; i++) _ductTypeList.Add(3);
_ductTypeList.Sort((a, b) => Random.value < 0.5 ? -1 : 1);
needCreateDuckCount = _ductTypeList.Count;
}
static float[] _FlyAngles1 = { 75, 180 - 75 };
static float[] _FlyAngles2 = { 75, 60, 180 - 75, 180 - 60 };
static float[] _FlyAngles3 = { 45, 60, 180 - 45, 180 - 60 };
static float[] _FlyAngles4 = { 30, 45, 60, 180 - 30, 180 - 45, 180 - 60 };
static float RangeFlyAngle(float[] angles)
{
return angles[Random.Range(0, angles.Length)];
}
DuckConfig GetDuckConfig()
{
DuckConfig duckConfig = new DuckConfig();
if (level <= 20) duckConfig.positionX = Random.Range(duckBox.rect.width / 2 - 200, duckBox.rect.width / 2 + 50);
else duckConfig.positionX = Random.Range(250, duckBox.rect.width - 350);
// ● 三关,每关至少击中6只野鸭,同屏1只
// ● 遇到4次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 绿色野鸭
if (level <= 3)//10
{
InitDuckTypeList(10, 0, 0);
passNeedHitCount = 6;
duckConfig.touchBoundCount = 4;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
}
// ● 三关,每关至少击中7只野鸭,同屏1只
// ● 遇到5次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 蓝色野鸭
else if (level <= 6)//15
{
InitDuckTypeList(0, 10, 0);// InitDuckTypeList(5, 5, 0);
passNeedHitCount = 7;
duckConfig.touchBoundCount = 5;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
}
// ● 三关,每关至少击中8只野鸭,同屏1只
// ● 遇到6次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 红色野鸭
else if (level <= 9)//18
{
InitDuckTypeList(0, 0, 10);//InitDuckTypeList(5, 3, 2);
passNeedHitCount = 8;
duckConfig.touchBoundCount = 6;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
}
// ● 两关,每关至少击中9只野鸭,同屏2只,第二只5秒
// ● 遇到7次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 绿 ,蓝野鸭
else if (level <= 11)
{
InitDuckTypeList(5, 5, 0);
passNeedHitCount = 9;
duckConfig.touchBoundCount = 7;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
}
// ● 两关,每关至少击中9只野鸭,同屏2只,第二只5秒
// ● 遇到7次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 蓝,红野鸭
else if (level <= 13)
{
InitDuckTypeList(0, 5, 5);
passNeedHitCount = 9;
duckConfig.touchBoundCount = 7;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles1);
}
// ● 14-20关,每关至少击中10只野鸭,同屏3只,第二只5秒,第三只10秒。
// ● 遇到8次边框未被击中
// ● 三箭(枪)用尽未被击中
// ● 绿、蓝、红野鸭
else
{
InitDuckTypeList(3, 4, 3);
passNeedHitCount = 10;
duckConfig.touchBoundCount = 8;
duckConfig.flyAngle = RangeFlyAngle(_FlyAngles2);
}
//else if (level <= 60)
//{
// InitDuckTypeList(3, 3, 4);
// passNeedHitCount = 10;
// duckConfig.touchBoundCount = 6;
// duckConfig.flyAngle = RangeFlyAngle(_FlyAngles3);
//}
//else if (level <= 80)
//{
// InitDuckTypeList(2, 4, 4);
// passNeedHitCount = 10;
// duckConfig.touchBoundCount = 7;
// duckConfig.flyAngle = RangeFlyAngle(_FlyAngles4);
//}
//else if (level <= 100)
//{
// InitDuckTypeList(2, 3, 5);
// passNeedHitCount = 10;
// duckConfig.touchBoundCount = 8;
// duckConfig.flyAngle = RangeFlyAngle(_FlyAngles4);
//}
duckConfig.type = _ductTypeList[0]; _ductTypeList.RemoveAt(0);
//duckConfig.flySpeed = BaseFlySpeed * (1 + (level - 1) * 0.05f);
//2023-7-25修改:速度还是以80关的做为初始速度,后面的关卡再按原来的公式增加
duckConfig.flySpeed = BaseFlySpeed * (1 + (level + 79 - 1) * 0.05f);
if (duckConfig.type == 1) duckConfig.flySpeed *= 1f;
else if (duckConfig.type == 4) duckConfig.flySpeed *= 1.2f; //duckConfig.type == 2
else if (duckConfig.type == 3) duckConfig.flySpeed *= 1.5f;
return duckConfig;
}
float _lastCreateDuckTime = -1000;
void CreateDuck()
{
if (_ductTypeList != null && _ductTypeList.Count == 0) return;
theDuckCountWaitingForDogHandle++;
_lastCreateDuckTime = Time.time;
DuckConfig duckConfig = GetDuckConfig();
Duck duck = Instantiate(duckPrefab, duckBox).GetComponent();
duck.config = duckConfig;
duck.onExit += HandleOnDuckExit;
duck.onFallDonwEnd += HandleOnDuckFallDown;
duck.onHitDead += HandleOnHitDead;
duck.onStartFlyAway += () => TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.FLY_AWAY);
//恢复箭
ResumeArrows(duck);
}
int exitDuckCount = 0;
void HandleOnDuckExit(Duck duck)
{
if (duck.dead) Dog.Instance?.OnEvent(Dog.SensitiveEventType.DuckHit, duck);
else
{
RemoveArrows(duck);
GameUI.Instance.RenderHitDuckCount(0);
Dog.Instance?.OnEvent(Dog.SensitiveEventType.DuckGetAway);
}
exitDuckCount++;
}
float _lastFallDownTime = 0;
void HandleOnDuckFallDown(Duck duck)
{
_lastFallDownTime = Time.time;
}
[System.NonSerialized] public int hitCount = 0;
private int bowHitCount = 0;
void HandleOnHitDead(Duck duck)
{
hitCount++;
int scoreToPlus = duck.config.type * 500;
hitScore += scoreToPlus;
GameUI.Instance.RenderHitDuckCount(duck.config.type);
//射击状态下,刷新添加分数
if (bAddCountScore) {
bowHitCount++;
_CumulativeScore += scoreToPlus;
uploadScore += scoreToPlus; //击杀野鸭分数
GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
GameUI.Instance.ShowTextHitScore(scoreToPlus, duck.transform.position);
}
RemoveArrows(duck);
}
public void OnModuleRotationUpdate(Quaternion rotation)
{
CrossHair.Instance?.UpdatePositionByModuleRotation(rotation);
}
public void OnModuleShooting(float speed, bool bAddCount = false)
{
if (CrossHair.Instance)
{
if (isGamePlaying)
{
if (UseOneArrow(bAddCount))
{
CrossHair.Instance.Shoot();
CheckShootPointHitDuck();
CheckNotifyFlyAway();
}
}
else if (!isGameStarted)
{
//CrossHair.Instance.Shoot();
if (GameUI.Instance.CheckHitDuckForGameStart(CrossHair.Instance.transform.position))
{
OnClick_GameStart();
}
}
}
}
void CheckShootPointHitDuck()
{
bool hitDuck = false;
Vector2 aimPos = CrossHair.Instance.transform.position;
for (int i = Duck.DuckList.Count - 1; i >= 0; i--)
{
Duck duck = Duck.DuckList[i];
RectTransform duckRTF = duck.transform as RectTransform;
bool intersect = RectTransformUtility.RectangleContainsScreenPoint(duckRTF, aimPos);
bool hitFrontBG = false;
Collider2D[] hitColliders = Physics2D.OverlapPointAll(aimPos);
foreach (var item in hitColliders)
{
if (item.name.StartsWith("BGFront"))
{
hitFrontBG = true;
break;
}
}
if (intersect && !hitFrontBG && duck.Hit())
{
hitDuck = true;
break;
}
}
if (!hitDuck)
{
GameUI.Instance.AddArrowOnScreen(aimPos);
}
else {
//枪械模式下,射中也加个效果
if(GlobalData.MyDeviceMode == DeviceMode.Gun)
{
GameUI.Instance.AddArrowOnScreen(aimPos);
}
}
}
void OnClick_GameStart()
{
AudioManager.Instance.PlayGameStart();
StartGame(false);
}
void StartGame(bool startImmediate)
{
if (isGameStarted) return;
isGameStarted = true;
onGameStart?.Invoke();
GameUI.Instance.HandleGameStart(() =>
{
dogSideObject.SetActive(true);
dogSideObject.GetComponent().onExit = () => canCreateDuck = true;
TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.ROUND_X, new object[] { level });
}, startImmediate);
NoArrows();
GameUI.Instance.RenderLevel(level);
// GameUI.Instance.RenderHitScore(hitScore, GetBestScore());
GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
}
void SettleGame()
{
if (isGameOver) return;
if (_ductTypeList == null) return;
if (Dog.Instance != null && Dog.Instance.isShowing) return;
if (needCreateDuckCount != exitDuckCount) return;
isGameOver = true;
Debug.Log("Game Over");
GameUI.Instance.RenderHitDuckCount(-1);
if (hitCount < passNeedHitCount)
{
//通关失败
TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_OVER, null, () =>
{
UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
});
AudioManager.Instance.PlayGameOver();
Debug.Log("通关失败");
}
else
{
//完美通关
if (needCreateDuckCount == hitCount && needCreateDuckCount == bowHitCount)
{
//奖励额外积分
int plusScore = 10000;
hitScore += plusScore;
_CumulativeScore += plusScore;
uploadScore += plusScore;
GameUI.Instance.RenderHitScore(_CumulativeScore, GetBestScore());
TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.SUPER_ARCHER, new object[] { plusScore }, ShowGamePass);
AudioManager.Instance.PlayFullScore();
}
else
{
ShowGamePass();
}
}
//通过关卡时候,上传一次分数
onUploadScore();
SaveBestScore();
GameOverInterface.OnGameOver(GameMgr.gameType);
}
//野鸭退出时候保存分数到服务器
public void onUploadScore()
{
if (uploadScore > 0)
{
Debug.Log("野鸭上传的积分为:" + uploadScore);
RankComp.Instance.uploadSinglePlayerGameRes(uploadScore);
uploadScore = 0;
}
}
void ShowGamePass()
{
//通关成功
TextGameScreenCenter.Instance.ShowText(TextGameScreenCenter.TextName.GAME_COMPLETED, null, () =>
{
//自动进入下一关
if (level < 20)
{
DefaultLevel = level + 1;
AutoNextLevel = true;
}
UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
});
AudioManager.Instance.PlayGamePass();
Debug.Log("通关成功");
}
int _arrowCount;
int arrowCount
{
get
{
// int count = 0;
// _duckCanShootCountList.ForEach(e => count += e.shootCount);
// return count;
return _arrowCount;
}
}
List _duckCanShootCountList = new List();
class DuckCanShootCount
{
public Duck duck;
public int shootCount;
public DuckCanShootCount(Duck duck, int shootCount)
{
this.duck = duck;
this.shootCount = shootCount;
}
}
void ResumeArrows(Duck duck)
{
// _duckCanShootCountList.Add(new DuckCanShootCount(duck, 3));
_arrowCount = 3;
GameUI.Instance.RenderArrowCount(arrowCount);
}
void RemoveArrows(Duck duck)
{
// _duckCanShootCountList.RemoveAll(e => e.duck == duck);
// GameUI.Instance.RenderArrowCount(arrowCount);
}
bool UseOneArrow(bool bAddCount = false)
{
//根据射箭状态赋值
bAddCountScore = bAddCount;
if (arrowCount > 0)
{
// foreach (var e in _duckCanShootCountList)
// {
// if (e.shootCount > 0)
// {
// e.shootCount--;
// break;
// }
// }
if (bAddCount) userGameAnalyse1.changeShootingCount(1);
_arrowCount--;
GameUI.Instance.RenderArrowCount(arrowCount);
return true;
}
return false;
}
void NoArrows()
{
// _duckCanShootCountList = new List();
_arrowCount = 0;
GameUI.Instance.RenderArrowCount(arrowCount);
}
void CheckNotifyFlyAway()
{
// foreach (var e in _duckCanShootCountList)
// if (e.shootCount == 0)
// e.duck.NotifyFlyAway();
if (arrowCount <= 0)
foreach (var duck in Duck.DuckList)
duck.NotifyFlyAway();
}
//累计得分
private static int _CumulativeScore = 0;
private static int _BestScoreVersion = 1;
string GetBestScoreKey()
{
// return "BestScore_Level" + level + "_V" + _BestScoreVersion;
return "DuckHunter_" + LoginMgr.myUserInfo.id + "_" + _BestScoreVersion;
}
void SaveBestScore()
{
string k = GetBestScoreKey();
int s = PlayerPrefs.GetInt(k, 0);
// if (hitScore > s) PlayerPrefs.SetInt(k, hitScore);
if (_CumulativeScore > s) PlayerPrefs.SetInt(k, _CumulativeScore);
}
int GetBestScore()
{
string k = GetBestScoreKey();
int s = PlayerPrefs.GetInt(k, 0);
return s;
}
}
}