Merge branch 'main' into DO-56-승급-패널-구현

This commit is contained in:
HaeinLEE 2025-03-28 17:17:44 +09:00
commit e8e21bc479
6 changed files with 130 additions and 12 deletions

View File

@ -31,6 +31,7 @@
RevengeConfirmed, // 재대결 수락 전송 확인
RevengeRejected, // 재대결 거절 수신
RevengeRejectionConfirmed, // 재대결 거절 전송 확인
ReceiveTimeout // 상대방이 타임 아웃일 때
ReceiveTimeout, // 상대방이 타임 아웃일 때
OpponentDisconnected
};
}

View File

@ -34,6 +34,7 @@ public partial class GameLogic : IDisposable
public int SelectedRow { get; private set; }
public int SelectedCol { get; private set; }
public FioTimer FioTimer { get; private set; }
public bool GameInProgress { get; private set; } // 게임 진행 중인지 확인
#endregion
@ -118,7 +119,13 @@ public partial class GameLogic : IDisposable
break;
case Constants.MultiplayManagerState.EndGame:
Debug.Log("## End Game");
// TODO: End Room 처리
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenConfirmPanel("상대방이 방을 나갔습니다.", () =>
{
// TODO: 무승부/항복 등 버튼 동작 안하도록 처리
});
});
break;
case Constants.MultiplayManagerState.DoSurrender:
Debug.Log("상대방의 항복 요청 들어옴");
@ -141,6 +148,7 @@ public partial class GameLogic : IDisposable
TimerPause();
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenLoadingPanel(true, true, false, false);
GameManager.Instance.panelManager.OpenDrawConfirmPanel("무승부 요청을 승낙하시겠습니까?", () =>
{
GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Draw);
@ -153,32 +161,52 @@ public partial class GameLogic : IDisposable
});
break;
case Constants.MultiplayManagerState.DrawRequestSent:
{
Debug.Log("무승부 요청 전송 완료");
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenLoadingPanel(true, true, false, false);
});
TimerPause();
break;
}
case Constants.MultiplayManagerState.DrawAccepted:
Debug.Log("무승부 요청이 승낙이 들어옴");
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.CloseLoadingPanel();
GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Draw);
EndGame(Enums.GameResult.Draw);
});
break;
case Constants.MultiplayManagerState.DrawConfirmed:
{
Debug.Log("무승부 요청 승낙 완료");
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.CloseLoadingPanel();
});
break;
}
case Constants.MultiplayManagerState.DrawRejected:
Debug.Log("무승부 요청이 거부가 들어옴");
TimerUnpause();
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.CloseLoadingPanel();
GameManager.Instance.panelManager.OpenConfirmPanel("무승부 요청을 거부하였습니다.", () => { });
});
break;
case Constants.MultiplayManagerState.DrawRejectionConfirmed:
{
Debug.Log("무승부 요청 거부 완료");
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenLoadingPanel(true, true, false, false);
});
TimerUnpause();
break;
}
case Constants.MultiplayManagerState.ReceiveTimeout:
Debug.Log("상대방이 타임 아웃 됨");
ExecuteOnMainThread(() =>
@ -192,6 +220,7 @@ public partial class GameLogic : IDisposable
break;
case Constants.MultiplayManagerState.ReceiveRevengeRequest:
Debug.Log("상대방의 재대결 요청이 들어옴");
ChangeGameInProgress(true);
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenDrawConfirmPanel("상대방의 재대결 요청을\n승낙하시겠습니까?", () =>
@ -267,7 +296,18 @@ public partial class GameLogic : IDisposable
});
});
break;
}
case Constants.MultiplayManagerState.OpponentDisconnected:
Debug.Log("상대방 강제 종료");
ExecuteOnMainThread(() =>
{
GameManager.Instance.panelManager.OpenConfirmPanel("연결이 끊어졌습니다.", () =>
{
GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Win);
EndGame(Enums.GameResult.Win);
});
});
break;
}
ReplayManager.Instance.InitReplayData(UserManager.Instance.Nickname,"nicknameB");
});
@ -328,6 +368,9 @@ public partial class GameLogic : IDisposable
// 메인스레드에서 게임 시작
private void StartGameOnMainThread()
{
ChangeGameInProgress(true);
Debug.Log("GameInProgress 변경 true");
ExecuteOnMainThread(() =>
{
// 로딩 패널 열려있으면 닫기
@ -476,6 +519,7 @@ public partial class GameLogic : IDisposable
// 기존 멀티플레이 상태 초기화
MultiPlayManager = null;
_roomId = null;
GameType = Enums.GameType.SinglePlay;
// 싱글 플레이 상태로 변경
@ -510,6 +554,12 @@ public partial class GameLogic : IDisposable
}
}
// 타이머 일시정지
private void TimerPause() => FioTimer.PauseTimer();
// 타이머 일시정지 해제
private void TimerUnpause() => FioTimer.StartTimer();
// 이전에 표시된 금수 마크 제거
private void ClearForbiddenMarks()
{
@ -533,17 +583,25 @@ public partial class GameLogic : IDisposable
return AI_NAMIES[index];
}
// 타이머 일시정지
private void TimerPause() => FioTimer.PauseTimer();
// 타이머 일시정지 해제
private void TimerUnpause() => FioTimer.StartTimer();
#endregion
public void ChangeGameInProgress(bool inProgress)
{
if (GameInProgress == inProgress)
return;
GameInProgress = inProgress;
}
public void Dispose()
{
MultiPlayManager?.LeaveRoom(_roomId);
MultiPlayManager?.Dispose();
}
public void ForceQuit()
{
MultiPlayManager?.ForceQuit(_roomId);
MultiPlayManager?.Dispose();
}
}

View File

@ -152,4 +152,15 @@ public class GameManager : Singleton<GameManager>
_gameLogic.EndGame(Enums.GameResult.Draw);
}
private void OnApplicationQuit()
{
Debug.Log("앱 종료 감지: 소켓 연결 정리 중...");
if(_gameLogic.GameInProgress)
_gameLogic?.ForceQuit();
else
_gameLogic?.Dispose();
}
}

View File

@ -1,4 +1,6 @@
public partial class GameLogic
using UnityEngine;
public partial class GameLogic
{
// 돌 카운터 증가 함수
public void CountStoneCounter() => _totalStoneCounter++;
@ -85,5 +87,13 @@
SetState(null);
ReplayManager.Instance.SaveReplayDataResult(result);
//TODO: 게임 종료 후 행동 구현
ChangeGameInProgress(false);
Debug.Log("GameInProgress 변경 false");
}
public void SetLastPositioned(int row, int col)
{
_lastRow = row;
_lastCol = col;
}
}

View File

@ -113,6 +113,8 @@ public class MultiplayManager : IDisposable
_socket.On("revengeConfirmed", RevengeConfirmed);
_socket.On("revengeRejected", RevengeRejected);
_socket.On("revengeRejectionConfirmed", RevengeRejectionConfirmed);
// 강제 종료 처리
_socket.On("opponentDisconnected", OpponentDisconnected);
_socket.Connect();
}
@ -216,6 +218,18 @@ public class MultiplayManager : IDisposable
_roomId = null; // 방 나가면 roomId 초기화
}
public void ForceQuit(string roomId)
{
if (string.IsNullOrEmpty(_roomId))
{
Debug.LogError("Disconnect 호출 실패: _roomId가 설정되지 않음");
return;
}
_socket.Emit("disconnect", new { roomId = _roomId });
_roomId = null; // 방 나가면 roomId 초기화
}
public void RequestSurrender()
{
if (string.IsNullOrEmpty(_roomId))
@ -338,6 +352,13 @@ public class MultiplayManager : IDisposable
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message);
}
private void DerawRejectionConfirmed(SocketIOResponse response)
{
var data = response.GetValue<MessageData>();
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.DrawRejectionConfirmed, data.message);
}
#endregion
#region
@ -414,6 +435,13 @@ public class MultiplayManager : IDisposable
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.RevengeRejectionConfirmed, data.message);
}
private void OpponentDisconnected(SocketIOResponse response)
{
var data = response.GetValue<MessageData>();
_onMultiplayStateChanged?.Invoke(Constants.MultiplayManagerState.OpponentDisconnected, data.message);
}
#endregion
public void Dispose()

View File

@ -215,6 +215,16 @@ public class ReplayManager : Singleton<ReplayManager>
{
ReplayManager.Instance.PushUndoMove(targetMove);
_gameLogic.RemoveStone(targetMove.columnIndex, targetMove.rowIndex);
if (_placedStoneStack.Count > 0)
{
var undoLastMove = _placedStoneStack.Peek();
_gameLogic.StoneController.SetStoneState(Enums.StoneState.LastPositioned, undoLastMove.columnIndex, undoLastMove.rowIndex);
_gameLogic.SetLastPositioned(undoLastMove.columnIndex, undoLastMove.rowIndex);
}
else
{
_gameLogic.SetLastPositioned(-1, -1);
}
}
public void ReplayFirst()