| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- 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;
- #if UNITY_EDITOR
- bool isAdd = true;
- #else
- bool isAdd = false;
- #endif
- OnModuleShooting(10, isAdd);
- }
- }
- }
- /// <summary>
- /// 基础初速度
- /// </summary>
- public static float BaseFlySpeed = 50;
- /// <summary>
- /// 下次从多少分开始
- /// </summary>
- 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;
- /// <summary>
- /// 通关需要击落的鸭子数量
- /// </summary>
- 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<int> _ductTypeList = null;
- /// <summary>
- /// 生成野鸭,并且打乱数组
- /// </summary>
- /// <param name="greenCount">绿色数量</param>
- /// <param name="blueCount">蓝色数量</param>
- /// <param name="redCount">红色数量</param>
- void InitDuckTypeList(int greenCount, int blueCount, int redCount)
- {
- if (_ductTypeList != null) return;
- _ductTypeList = new List<int>();
- 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>();
- 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<DogSide>().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");
- //失败时候也时候弹出排行榜
- UploadBestScoreToLocalRank(() => {
- 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()
- {
- //uploadScore = 500;
- 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;
- //小于20,就是未完全通关
- UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
- }
- else {
- //完全通过时候弹出排行榜
- UploadBestScoreToLocalRank(() => {
- UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
- });
- }
- Debug.Log("野鸭跳转关卡:"+ DefaultLevel);
-
- //UnityEngine.SceneManagement.SceneManager.LoadScene("DuckHunter");
- });
- AudioManager.Instance.PlayGamePass();
- Debug.Log("通关成功");
- }
- /// <summary>
- /// 把累计得分记录到本地数据库
- /// </summary>
- public void UploadBestScoreToLocalRank(System.Action callback) {
- if (CommonConfig.StandaloneModeOrPlatformB)
- {
- //获取当前记录的最高分数
- LocalRank.RankManager.SetCurrentScore(_CumulativeScore);
- LocalRank.RankManager.CreateRankView(GlobalData.singlePlayerGameType, callback);
- }
- else
- {
- callback?.Invoke();
- }
- }
- int _arrowCount;
- int arrowCount
- {
- get
- {
- // int count = 0;
- // _duckCanShootCountList.ForEach(e => count += e.shootCount);
- // return count;
- return _arrowCount;
- }
- }
- List<DuckCanShootCount> _duckCanShootCountList = new List<DuckCanShootCount>();
- 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<DuckCanShootCount>();
- _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;
- }
- }
- }
|