diff --git a/Assets/Resources/Prefabs/ScrollItem/ReplayScrollItem.prefab b/Assets/Resources/Prefabs/ScrollItem/ReplayScrollItem.prefab index e4b3b83..f13b653 100644 --- a/Assets/Resources/Prefabs/ScrollItem/ReplayScrollItem.prefab +++ b/Assets/Resources/Prefabs/ScrollItem/ReplayScrollItem.prefab @@ -169,7 +169,7 @@ RectTransform: m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} + m_SizeDelta: {x: 90, y: 90} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &548835481879647278 CanvasRenderer: @@ -199,7 +199,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: 5a30ddccdc758dd45a470cfeb06cc240, type: 3} + m_Sprite: {fileID: 21300000, guid: 55f1b097831f89a4f853cb2f44d69e30, type: 3} m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 @@ -378,7 +378,7 @@ RectTransform: m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 120, y: 120} + m_SizeDelta: {x: 90, y: 90} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &1085849272306452399 CanvasRenderer: @@ -408,7 +408,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 21300000, guid: a8641453282ed4c4b9f416044a57055a, type: 3} + m_Sprite: {fileID: 21300000, guid: 4fbfde8fa7f268d46aaf3ba594cc3eea, type: 3} m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 @@ -453,7 +453,7 @@ RectTransform: m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5} m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 100, y: 100} + m_SizeDelta: {x: 120, y: 70} m_Pivot: {x: 0.5, y: 0.5} --- !u!222 &8616790052716066886 CanvasRenderer: @@ -483,7 +483,7 @@ MonoBehaviour: m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_Sprite: {fileID: 0} + m_Sprite: {fileID: 21300000, guid: 1cbdee33c27a55b49bb713cc1aacd29a, type: 3} m_Type: 0 m_PreserveAspect: 0 m_FillCenter: 1 diff --git a/Assets/Script/Game/GameLogic.cs b/Assets/Script/Game/GameLogic.cs index e4b1dbf..07b35ff 100644 --- a/Assets/Script/Game/GameLogic.cs +++ b/Assets/Script/Game/GameLogic.cs @@ -14,6 +14,9 @@ public partial class GameLogic : IDisposable private RenjuForbiddenMoveDetector _forbiddenDetector; // 렌주룰 금수 검사기 private List _forbiddenMoves = new (); // 현재 금수 위치 목록 private string _roomId; + private string _opponentNickname; + private int _opponentImageIndex; + private bool isFirstPlayer; #endregion @@ -73,7 +76,6 @@ public partial class GameLogic : IDisposable MultiPlayManager = new MultiplayManager((state, data) => { Debug.Log($"## {state}"); - switch (state) { case Constants.MultiplayManagerState.CreateRoom: @@ -83,12 +85,12 @@ public partial class GameLogic : IDisposable case Constants.MultiplayManagerState.JoinRoom: Debug.Log("## Join Room"); var joinRoomData = data as JoinRoomData; - + _roomId = joinRoomData.roomId; // TODO: 응답값 없을 때 서버에서 다시 받아오기 or AI 플레이로 넘기는 처리 필요 if (!ValidateRoomData(joinRoomData, "Join Room")) return; // 플레이어 셋업 - SetupPlayer(joinRoomData.isBlack, joinRoomData.roomId, joinRoomData.opponentNickname, joinRoomData.opponentImageIndex); + SetupPlayer(joinRoomData.isBlack, _roomId, joinRoomData.opponentNickname, joinRoomData.opponentImageIndex); // 메인 스레드에서 실행 - UI 업데이트는 메인 스레드에서 실행 필요 StartGameOnMainThread(); @@ -138,7 +140,7 @@ public partial class GameLogic : IDisposable Debug.Log("상대방의 무승부 요청 들어옴"); ExecuteOnMainThread(() => { - GameManager.Instance.panelManager.OpenDrawConfirmPanel("무승부 요청을 승락하시겠습니까?", () => + GameManager.Instance.panelManager.OpenDrawConfirmPanel("무승부 요청을 승낙하시겠습니까?", () => { GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Draw); EndGame(Enums.GameResult.Draw); @@ -153,7 +155,7 @@ public partial class GameLogic : IDisposable Debug.Log("무승부 요청 전송 완료"); break; case Constants.MultiplayManagerState.DrawAccepted: - Debug.Log("무승부 요청이 승락이 들어옴"); + Debug.Log("무승부 요청이 승낙이 들어옴"); ExecuteOnMainThread(() => { GameManager.Instance.panelManager.OpenEffectPanel(Enums.GameResult.Draw); @@ -161,7 +163,7 @@ public partial class GameLogic : IDisposable }); break; case Constants.MultiplayManagerState.DrawConfirmed: - Debug.Log("무승부 요청 승락 완료"); + Debug.Log("무승부 요청 승낙 완료"); break; case Constants.MultiplayManagerState.DrawRejected: Debug.Log("무승부 요청이 거부가 들어옴"); @@ -182,7 +184,87 @@ public partial class GameLogic : IDisposable EndGame(Enums.GameResult.Win); }); break; - } + case Constants.MultiplayManagerState.RevengeRequestSent: + Debug.Log("재대결 요청: 전송 완료"); + break; + case Constants.MultiplayManagerState.ReceiveRevengeRequest: + Debug.Log("상대방의 재대결 요청이 들어옴"); + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenDrawConfirmPanel("상대방의 재대결 요청을\n승낙하시겠습니까?", () => + { + MultiPlayManager.AcceptRevenge(); + }, () => + { + MultiPlayManager.RejectRevenge(); + }); + }); + break; + case Constants.MultiplayManagerState.RevengeAccepted: + Debug.Log("재대결 요청: 승낙이 들어옴"); + var revengeAcceptedData = data as RevengeData; + + // TODO: 응답값 없을 때 서버에서 다시 받아오기 or AI 플레이로 넘기는 처리 필요 + if (revengeAcceptedData == null) + { + Debug.Log("RevengeAccepted 응답값이 null 입니다"); + return; + } + + // 선공, 후공 처리 + isFirstPlayer = revengeAcceptedData.isBlack; + + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("상대방이\n재대결을 승낙하였습니다.\n게임이 다시 시작됩니다.", () => + { + InitBoardForRevenge(isFirstPlayer); + }); + }); + break; + case Constants.MultiplayManagerState.RevengeConfirmed: + Debug.Log("재대결 요청: 승낙 완료"); + var revengConfirmedData = data as RevengeData; + + // TODO: 응답값 없을 때 서버에서 다시 받아오기 or AI 플레이로 넘기는 처리 필요 + if (revengConfirmedData == null) + { + Debug.Log("RevengeConfirmed 응답값이 null 입니다"); + return; + } + + // 선공, 후공 처리 + isFirstPlayer = revengConfirmedData.isBlack; + + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("재대결 요청을\n승낙하였습니다.\n게임이 다시 시작됩니다.", () => + { + InitBoardForRevenge(isFirstPlayer); + }); + }); + break; + case Constants.MultiplayManagerState.RevengeRejected: + Debug.Log("재대결 요청: 거부가 들어옴"); + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("상대방이\n재대결 요청을\n거부하였습니다.", () => + { + GameManager.Instance.panelManager.CloseLoadingPanel(); + }); + }); + break; + case Constants.MultiplayManagerState.RevengeRejectionConfirmed: + Debug.Log("재대결 요청: 거부 완료"); + ExecuteOnMainThread(() => + { + GameManager.Instance.panelManager.OpenConfirmPanel("재대결 요청을\n거부하였습니다.", () => + { + GameManager.Instance.panelManager.CloseLoadingPanel(); + }); + }); + break; + } ReplayManager.Instance.InitReplayData(UserManager.Instance.Nickname,"nicknameB"); }); @@ -192,15 +274,18 @@ public partial class GameLogic : IDisposable private void SetupPlayer(bool isBlack, string roomId, string opponentNickname, int opponentImageIndex) { // 선공, 후공 처리 - var isFirstPlayer = isBlack; + isFirstPlayer = isBlack; + _opponentNickname = opponentNickname; + _opponentImageIndex = opponentImageIndex; + if (isFirstPlayer) { Debug.Log("해당 플레이어가 선공 입니다"); FirstPlayerState = new PlayerState(true, MultiPlayManager, roomId); SecondPlayerState = new MultiPlayerState(false, MultiPlayManager); - UpdateUIForFirstPlayer(opponentNickname, opponentImageIndex); + UpdateUIForFirstPlayer(_opponentNickname, _opponentImageIndex); } else { @@ -208,7 +293,7 @@ public partial class GameLogic : IDisposable FirstPlayerState = new MultiPlayerState(true, MultiPlayManager); SecondPlayerState = new PlayerState(false, MultiPlayManager, roomId); - UpdateUIForSecondPlayer(opponentNickname, opponentImageIndex); + UpdateUIForSecondPlayer(_opponentNickname, _opponentImageIndex); } } @@ -343,6 +428,35 @@ public partial class GameLogic : IDisposable }; } } + + private void InitBoardForRevenge(bool isFirstPlayer) + { + //보드 초기화 + _board = new Enums.PlayerType[15, 15]; + _totalStoneCounter = 0; + StoneController.InitStones(); + RequestDrawChance = false; + + SelectedRow = -1; + SelectedCol = -1; + _lastRow = -1; + _lastCol = -1; + + // 금수 감지기 초기화 + _forbiddenDetector.RenjuForbiddenMove(_board); + + //timer 초기화 + FioTimer.InitTimer(); + + // 플레이어 셋업 + SetupPlayer(isFirstPlayer, _roomId, _opponentNickname, _opponentImageIndex); + + // 로딩 패널 열려 있으면 닫기 + GameManager.Instance.panelManager.CloseLoadingPanel(); + + // 메인 스레드에서 실행 - UI 업데이트는 메인 스레드에서 실행 필요 + StartGameOnMainThread(); + } #endregion diff --git a/Assets/Script/Replay/ReplayCell.cs b/Assets/Script/Replay/ReplayCell.cs index 08a231e..999a6d6 100644 --- a/Assets/Script/Replay/ReplayCell.cs +++ b/Assets/Script/Replay/ReplayCell.cs @@ -17,23 +17,7 @@ public class ReplayCell : MonoBehaviour private ReplayRecord _storedReplayRecord; private Enums.PlayerType _myPlayerType; private string _opponentNickname; - - - //TODO:승, 패 외에 무승부 반영하기. bool => int - public void SetWinImage(bool isWin) - { - if (isWin == true) - { - winImage.gameObject.SetActive(true); - loseImage.gameObject.SetActive(false); - } - else - { - loseImage.gameObject.SetActive(true); - winImage.gameObject.SetActive(false); - } - } -//TODO: 무승부 이미지 제작해서 에디터에 추가해주세요 + public void SetWinImage(Enums.GameResult gameResult) { switch(gameResult) diff --git a/Assets/Script/Replay/ReplayManager.cs b/Assets/Script/Replay/ReplayManager.cs index 271c570..8b5bbc7 100644 --- a/Assets/Script/Replay/ReplayManager.cs +++ b/Assets/Script/Replay/ReplayManager.cs @@ -280,7 +280,6 @@ public class ReplayManager : Singleton { InitReplayBoard(_selectedReplayRecord); - //게임 매니저에서 가져온 코드입니다. _stoneController = GameObject.FindObjectOfType(); _stoneController.InitStones(); _gameLogic = new GameLogic(_stoneController, Enums.GameType.Replay); diff --git a/Assets/Sprites/Main UI/replay_draw.png b/Assets/Sprites/Main UI/replay_draw.png new file mode 100644 index 0000000..41c7acd Binary files /dev/null and b/Assets/Sprites/Main UI/replay_draw.png differ diff --git a/Assets/Sprites/Panel UI/DLose.png.meta b/Assets/Sprites/Main UI/replay_draw.png.meta similarity index 98% rename from Assets/Sprites/Panel UI/DLose.png.meta rename to Assets/Sprites/Main UI/replay_draw.png.meta index c800446..cac3c83 100644 --- a/Assets/Sprites/Panel UI/DLose.png.meta +++ b/Assets/Sprites/Main UI/replay_draw.png.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a8641453282ed4c4b9f416044a57055a +guid: 1cbdee33c27a55b49bb713cc1aacd29a TextureImporter: internalIDToNameTable: [] externalObjects: {} diff --git a/Assets/Sprites/Panel UI/DLose.png b/Assets/Sprites/Panel UI/DLose.png deleted file mode 100644 index 15fd2e4..0000000 Binary files a/Assets/Sprites/Panel UI/DLose.png and /dev/null differ diff --git a/Assets/Sprites/Panel UI/DWin.png b/Assets/Sprites/Panel UI/DWin.png deleted file mode 100644 index 9126603..0000000 Binary files a/Assets/Sprites/Panel UI/DWin.png and /dev/null differ diff --git a/Assets/Sprites/Panel UI/DWin.png.meta b/Assets/Sprites/Panel UI/DWin.png.meta deleted file mode 100644 index 00be0be..0000000 --- a/Assets/Sprites/Panel UI/DWin.png.meta +++ /dev/null @@ -1,140 +0,0 @@ -fileFormatVersion: 2 -guid: 5a30ddccdc758dd45a470cfeb06cc240 -TextureImporter: - internalIDToNameTable: [] - externalObjects: {} - serializedVersion: 13 - mipmaps: - mipMapMode: 0 - enableMipMap: 0 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - flipGreenChannel: 0 - isReadable: 0 - streamingMipmaps: 0 - streamingMipmapsPriority: 0 - vTOnly: 0 - ignoreMipmapLimit: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: 1 - aniso: 1 - mipBias: 0 - wrapU: 1 - wrapV: 1 - wrapW: 1 - nPOTScale: 0 - lightmap: 0 - compressionQuality: 50 - spriteMode: 1 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 1 - spriteTessellationDetail: -1 - textureType: 8 - textureShape: 1 - singleChannelComponent: 0 - flipbookRows: 1 - flipbookColumns: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - ignorePngGamma: 0 - applyGammaDecoding: 0 - swizzle: 50462976 - cookieLightType: 0 - platformSettings: - - serializedVersion: 3 - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Standalone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: iPhone - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - - serializedVersion: 3 - buildTarget: Android - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - ignorePlatformSupport: 0 - androidETC2FallbackOverride: 0 - forceMaximumCompressionQuality_BC6H_BC7: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - bones: [] - spriteID: 5e97eb03825dee720800000000000000 - internalID: 0 - vertices: [] - indices: - edges: [] - weights: [] - secondaryTextures: [] - nameFileIdTable: {} - mipmapLimitGroupName: - pSDRemoveMatte: 0 - userData: - assetBundleName: - assetBundleVariant: