|
|
@@ -3,13 +3,355 @@ using System.Collections.Generic;
|
|
|
using UnityEngine;
|
|
|
using UnityEngine.UI;
|
|
|
using DG.Tweening;
|
|
|
+using Newtonsoft.Json;
|
|
|
|
|
|
/**双人PK模式 */
|
|
|
-public class PKGameMode_OnlinePK : PKGameMode {
|
|
|
+public class PKGameMode_OnlinePK : GameMode {
|
|
|
SocketPlayer socketPlayer;
|
|
|
+ public int myPlayerIndex = -111;
|
|
|
+ public bool IsMyPlayerInited() {
|
|
|
+ return myPlayerIndex >= 0;
|
|
|
+ }
|
|
|
+ public bool IsMyPlayerRunning() {
|
|
|
+ return myPlayerIndex == gameLogic.currentPlayerIndex;
|
|
|
+ }
|
|
|
|
|
|
public PKGameMode_OnlinePK(GameMgr gameMgr) : base(gameMgr) {
|
|
|
- socketPlayer = new GameObject().AddComponent<SocketPlayer>();
|
|
|
- socketPlayer.gameMode = this;
|
|
|
+ GlobalData.pkMatchType = PKMatchType.OnlinePK;
|
|
|
+ myPlayerIndex = GlobalData.playerIndexInRoom;
|
|
|
+
|
|
|
+ gameLogic.InitAppearPlayerIndexes();
|
|
|
+ gameLogic.SetCurrentPlayerIndexToNext();
|
|
|
+
|
|
|
+ //记录可射击的靶子
|
|
|
+ targetBody = GameObject.Find("GameArea/TargetObject/TargetBody").GetComponent<TargetBody>();
|
|
|
+ GameObject.FindObjectOfType<ArmBow>().validTargets.Add(targetBody);
|
|
|
+ //添加游戏界面
|
|
|
+ GameObject view = Resources.Load<GameObject>("Prefabs/Views/PKGameView");
|
|
|
+ GameObject.Instantiate(view);
|
|
|
+ //禁止动作-相机和手臂
|
|
|
+ BanBowReady();
|
|
|
+
|
|
|
+ AutoSwitchBanUserControlBow();
|
|
|
+
|
|
|
+ // socketPlayer = new GameObject("SocketPlayer").AddComponent<SocketPlayer>();
|
|
|
+ socketPlayer = GameObject.Find("SocketPlayer").GetComponent<SocketPlayer>();
|
|
|
+ socketPlayer.onReceivePKGameData = onReceivePKGameData;
|
|
|
+ }
|
|
|
+
|
|
|
+ Quaternion bowTargetQua;
|
|
|
+ bool hasBowTargBtQua;
|
|
|
+ void onReceivePKGameData(string key, string data) {
|
|
|
+ if (key == "logic") {
|
|
|
+ GameLogic gameLogic = JsonConvert.DeserializeObject<GameLogic>(data);
|
|
|
+ if (
|
|
|
+ (gameLogic.nextPlayerExcuteID == this.gameLogic.nextPlayerExcuteID && myPlayerIndex != gameLogic.currentPlayerIndex) ||
|
|
|
+ (gameLogic.nextPlayerExcuteID > this.gameLogic.nextPlayerExcuteID)
|
|
|
+ ) {
|
|
|
+ this.gameLogic = gameLogic;
|
|
|
+ AutoSwitchBanUserControlBow();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (key == "bow") {
|
|
|
+ if (!IsMyPlayerRunning()) {
|
|
|
+ string[] quaStr = data.Split(',');
|
|
|
+ if (quaStr.Length == 5) {
|
|
|
+ bowTargetQua.x = float.Parse(quaStr[0]);
|
|
|
+ bowTargetQua.y = float.Parse(quaStr[1]);
|
|
|
+ bowTargetQua.z = float.Parse(quaStr[2]);
|
|
|
+ bowTargetQua.w = float.Parse(quaStr[3]);
|
|
|
+ hasBowTargBtQua = true;
|
|
|
+ ArmBow.ins.phase = int.Parse(quaStr[4]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (key == "arrow") {
|
|
|
+ List<ArrowSync.SyncData> arrowSyncDataList = JsonConvert.DeserializeObject<List<ArrowSync.SyncData>>(data);
|
|
|
+ foreach (var item in arrowSyncMap) {
|
|
|
+ item.Value.hasSetSyncData = false;
|
|
|
+ }
|
|
|
+ GameObject arrowPrefab = ArmBow.ins.arrow;
|
|
|
+ foreach (var item in arrowSyncDataList) {
|
|
|
+ ArrowSync arrowSync;
|
|
|
+ arrowSyncMap.TryGetValue(item.id, out arrowSync);
|
|
|
+ if (arrowSync == null) {
|
|
|
+ GameObject arrowObj = GameObject.Instantiate(arrowPrefab);
|
|
|
+ GameObject.Destroy(arrowObj.GetComponent<BoxCollider>());
|
|
|
+ arrowSync = arrowObj.AddComponent<ArrowSync>();
|
|
|
+ arrowSync.SetSyncData(item, true);
|
|
|
+ arrowSyncMap[item.id] = arrowSync;
|
|
|
+ arrowObj.SetActive(true);
|
|
|
+ } else {
|
|
|
+ arrowSync.SetSyncData(item);
|
|
|
+ }
|
|
|
+ arrowSync.hasSetSyncData = true;
|
|
|
+ }
|
|
|
+ List<int> removeIDs = null;
|
|
|
+ foreach (var item in arrowSyncMap) {
|
|
|
+ if (!item.Value.hasSetSyncData) {
|
|
|
+ if (removeIDs == null) removeIDs = new List<int>();
|
|
|
+ removeIDs.Add(item.Key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (removeIDs != null) {
|
|
|
+ foreach (var id in removeIDs) {
|
|
|
+ ArrowSync arrowSync = arrowSyncMap[id];
|
|
|
+ arrowSyncMap.Remove(id);
|
|
|
+ if (arrowSync && arrowSync.gameObject) {
|
|
|
+ GameObject.Destroy(arrowSync.gameObject);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (key == "score") {
|
|
|
+ HitTargetNumber.Create(float.Parse(data));
|
|
|
+ AudioMgr.ins.PlayHit(AudioMgr.GetAudioSource(TargetBody.ins.gameObject));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void AutoSwitchBanUserControlBow() {
|
|
|
+ BowCamera.ins.banLogic = ArmBow.ins.banLogic = !IsMyPlayerRunning();
|
|
|
+ }
|
|
|
+
|
|
|
+ //记录可射击的靶子
|
|
|
+ TargetBody targetBody;
|
|
|
+
|
|
|
+ bool hasStart = false;
|
|
|
+ public override void Start() {
|
|
|
+ hasStart = true;
|
|
|
+ TargetView.ins.Show(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ void AddReadyView()
|
|
|
+ {
|
|
|
+ GameObject view = Resources.Load<GameObject>("Prefabs/Views/PKGameReadyView");
|
|
|
+ GameObject.Instantiate(view);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void HitTarget(float score) {
|
|
|
+ gameLogic.HitTarget(score);
|
|
|
+ HitTargetNumber.Create(score);
|
|
|
+ scoreWillSend = score.ToString();
|
|
|
+ }
|
|
|
+
|
|
|
+ public override bool DoNextShoot() {
|
|
|
+ return gameLogic.DoNextShoot(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override object[] Settle() {
|
|
|
+ return gameLogic.gameRes;
|
|
|
+ }
|
|
|
+ float uploadGameDataTime = 0;
|
|
|
+ float uploadBowTime = 0;
|
|
|
+ public override void Update() {
|
|
|
+ if (!IsMyPlayerInited()) return;
|
|
|
+ if (!hasStart) return;
|
|
|
+ AutoSwitchBanUserControlBow();
|
|
|
+ if (IsMyPlayerRunning()) {
|
|
|
+ gameLogic.Update(this);
|
|
|
+ upload1();
|
|
|
+ }
|
|
|
+ upload2();
|
|
|
+ gameDisplay.Update(this);
|
|
|
+ }
|
|
|
+ Dictionary<int, ArrowSync> arrowSyncMap = new Dictionary<int, ArrowSync>();
|
|
|
+ void upload1() {
|
|
|
+ uploadBowTime -= Time.deltaTime;
|
|
|
+ if (uploadBowTime <= 0) {
|
|
|
+ uploadBowTime = 0.1f;
|
|
|
+ Quaternion qua = BowCamera.ins.transform.rotation;
|
|
|
+ socketPlayer.UploadPKGameData("bow", qua.x + "," + qua.y + "," + qua.z + "," + qua.w + "," + ArmBow.ins.phase);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ string scoreWillSend = null;
|
|
|
+ void upload2() {
|
|
|
+ uploadGameDataTime -= Time.deltaTime;
|
|
|
+ if (uploadGameDataTime <= 0) {
|
|
|
+ uploadGameDataTime = 0.05f;
|
|
|
+ socketPlayer.UploadPKGameData("logic", gameLogic);
|
|
|
+
|
|
|
+ List<ArrowSync.SyncData> arrowSyncDataList = new List<ArrowSync.SyncData>();
|
|
|
+ foreach (var item in Arrow.arrowSet) {
|
|
|
+ if (item.outputSyncData == null || !item.outputSyncData.inited) continue;
|
|
|
+ arrowSyncDataList.Add(item.outputSyncData);
|
|
|
+ }
|
|
|
+ socketPlayer.UploadPKGameData("arrow", arrowSyncDataList);
|
|
|
+ if (scoreWillSend != null) {
|
|
|
+ socketPlayer.UploadPKGameData("score", scoreWillSend);
|
|
|
+ scoreWillSend = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void onBowReady() {
|
|
|
+ if (!IsMyPlayerRunning()) return;
|
|
|
+ gameLogic.singleShootReadyTime = gameLogic.singleShootReadyMaxTime;
|
|
|
+ gameLogic.singleShootTimeRunning = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void onBowShoot() {
|
|
|
+ if (!IsMyPlayerRunning()) return;
|
|
|
+ gameLogic.singleShootTimeRunning = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //gamelogic-data
|
|
|
+ public GameLogic gameLogic = new GameLogic();
|
|
|
+ public class GameLogic {
|
|
|
+ public int currentPlayerIndex = 0;
|
|
|
+ public int[] totalScores = {0, 0};
|
|
|
+ public float[] currentScores = {0, 0};
|
|
|
+ public int round = 1;
|
|
|
+ public int maxRound = 5;
|
|
|
+ public int[] shootCount = {0, 0};
|
|
|
+ public int maxShootCount = 3;
|
|
|
+ public float singleShootReadyTime = 20;
|
|
|
+ public float singleShootReadyMaxTime = 20;
|
|
|
+ public bool singleShootTimeRunning = false;
|
|
|
+ public string[] gameRes = {"平局", "平局"};
|
|
|
+ public bool gameEnd = false;
|
|
|
+ //玩家出场顺序
|
|
|
+ public Queue<int> appearPlayerIndexes = new Queue<int>();
|
|
|
+ public int[] sequencePlayerIndexes = new int[]{0, 1};
|
|
|
+ public int nextPlayerExcuteID = 0;
|
|
|
+ public void InitAppearPlayerIndexes()
|
|
|
+ {
|
|
|
+ if (round >= 2)
|
|
|
+ {
|
|
|
+ if (totalScores[0] < totalScores[1])
|
|
|
+ {
|
|
|
+ sequencePlayerIndexes = new int[]{0, 1};
|
|
|
+ }
|
|
|
+ else if (totalScores[1] < totalScores[0])
|
|
|
+ {
|
|
|
+ sequencePlayerIndexes = new int[]{1, 0};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int i = 0; i < maxShootCount; i++) {
|
|
|
+ appearPlayerIndexes.Enqueue(sequencePlayerIndexes[0]);
|
|
|
+ appearPlayerIndexes.Enqueue(sequencePlayerIndexes[1]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void SetCurrentPlayerIndexToNext() {
|
|
|
+ currentPlayerIndex = appearPlayerIndexes.Dequeue();
|
|
|
+ nextPlayerExcuteID++;
|
|
|
+ }
|
|
|
+ public void Update(PKGameMode_OnlinePK gm) {
|
|
|
+ if (singleShootTimeRunning && !gm.pauseTimeCounting) {
|
|
|
+ singleShootReadyTime -= Time.deltaTime;
|
|
|
+ if (singleShootReadyTime <= 0) {
|
|
|
+ singleShootReadyTime = 0;
|
|
|
+ singleShootTimeRunning = false;
|
|
|
+ HitTarget(0);
|
|
|
+ // BanBowReady();
|
|
|
+ // //超时显示
|
|
|
+ // Text timeoutText = PKGameView.ins.transform.Find("TimeoutText").GetComponent<Text>();
|
|
|
+ // Sequence seq = DOTween.Sequence();
|
|
|
+ // seq.Append(timeoutText.DOFade(1, 0.5f));
|
|
|
+ // seq.AppendInterval(1);
|
|
|
+ // seq.Append(timeoutText.DOFade(0, 0.5f));
|
|
|
+ // seq.AppendCallback(delegate(){
|
|
|
+ // if (DoNextShoot()) {
|
|
|
+ // UnbanBowReady();
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ DoNextShoot(gm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ public void HitTarget(float score) {
|
|
|
+ currentScores[currentPlayerIndex] += score;
|
|
|
+ shootCount[currentPlayerIndex]++;
|
|
|
+ }
|
|
|
+ public bool DoNextShoot(PKGameMode_OnlinePK gm) {
|
|
|
+ if (gm.gameMgr.gameOver) return false;
|
|
|
+ bool nextRound = false;
|
|
|
+ if (shootCount[0] == maxShootCount && shootCount[1] == maxShootCount ) {
|
|
|
+ shootCount = new int[]{0, 0};
|
|
|
+ nextRound = true;
|
|
|
+ //更新总比分
|
|
|
+ if (currentScores[0] == currentScores[1]) {
|
|
|
+ totalScores[0] += 1;
|
|
|
+ totalScores[1] += 1;
|
|
|
+ } else if (currentScores[0] > currentScores[1]) {
|
|
|
+ totalScores[0] += 2;
|
|
|
+ } else if (currentScores[0] < currentScores[1]) {
|
|
|
+ totalScores[1] += 2;
|
|
|
+ }
|
|
|
+ //根据总比分判断游戏是否结束
|
|
|
+ if (totalScores[0] == totalScores[1]) {
|
|
|
+ if (round == maxRound) {
|
|
|
+ if (round == 5) {
|
|
|
+ maxShootCount = 1;
|
|
|
+ maxRound = 6;
|
|
|
+ } else {
|
|
|
+ gameEnd = true;
|
|
|
+ gameRes = new string[]{"平局", "平局"};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (totalScores[0] >= 6 && totalScores[0] > totalScores[1]) {
|
|
|
+ gameEnd = true;
|
|
|
+ gameRes = new string[]{"胜利", "失败"};
|
|
|
+ } else if (totalScores[1] >= 6 && totalScores[1] > totalScores[0]) {
|
|
|
+ gameEnd = true;
|
|
|
+ gameRes = new string[]{"失败", "胜利"};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (gameEnd) {
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ //进入下一回合?
|
|
|
+ if (nextRound) {
|
|
|
+ round++;
|
|
|
+ currentScores[0] = currentScores[1] = 0;
|
|
|
+ InitAppearPlayerIndexes();
|
|
|
+ }
|
|
|
+ //本轮玩家登记
|
|
|
+ SetCurrentPlayerIndexToNext();
|
|
|
+ gm.BanBowReady();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //game-display
|
|
|
+ public GameDisplay gameDisplay = new GameDisplay();
|
|
|
+ public class GameDisplay {
|
|
|
+ readonly float[] targetDistancesOnRound = {10, 20, 30, 50, 70, 70};
|
|
|
+ public int[] playerRoleIDs = {1, 2};
|
|
|
+ public int showRoundValueOnReadyView = 0;
|
|
|
+
|
|
|
+ #region 用于控制显示更新的变量
|
|
|
+ int round = 0;
|
|
|
+ int nextPlayerExcuteID = 0;
|
|
|
+ bool gameEnd = false;
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ public void Update(PKGameMode_OnlinePK gm) {
|
|
|
+ if (round != gm.gameLogic.round) {
|
|
|
+ round = gm.gameLogic.round;
|
|
|
+ gm.targetBody.SetDistance(targetDistancesOnRound[round - 1]);
|
|
|
+ }
|
|
|
+ if (nextPlayerExcuteID != gm.gameLogic.nextPlayerExcuteID) {
|
|
|
+ nextPlayerExcuteID = gm.gameLogic.nextPlayerExcuteID;
|
|
|
+ gm.BanBowReady();
|
|
|
+ gm.AddReadyView();
|
|
|
+ //清除箭矢
|
|
|
+ foreach (var arrow in Arrow.arrowSet) {
|
|
|
+ try {
|
|
|
+ GameObject.Destroy(arrow.gameObject);
|
|
|
+ } catch (UnityException e) {
|
|
|
+ Debug.Log("Delete Arrow Error\n" + e.Message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!gameEnd && gm.gameLogic.gameEnd) {
|
|
|
+ gameEnd = true;
|
|
|
+ gm.gameMgr.StopGame();
|
|
|
+ GameObject view = Resources.Load<GameObject>("Prefabs/Views/PKGameSettleView");
|
|
|
+ GameObject.Instantiate(view);
|
|
|
+ }
|
|
|
+ if (!gm.IsMyPlayerRunning() && gm.hasBowTargBtQua) {
|
|
|
+ BowCamera.ins.transform.rotation = Quaternion.Lerp(BowCamera.ins.transform.rotation, gm.bowTargetQua, Time.deltaTime * 12);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|