/// <summary> /// 인자로 주어진 플레이어가 잡아야 하는 목표의 번호 리스트를 반환합니다. /// 잘못된 입력이 주어지지 않는다면, 반환되는 리스트의 크기는 2입니다. /// </summary> /// <param name="playerIndex">플레이어 번호</param> /// <returns></returns> public List <int> GetTarget(int playerIndex) { if (playerIndex < 0 || playerIndex >= 5 || playerPermutation.Count != 5 || elementPermutation.Count != 5) { return(null); } List <int> t = new List <int>(); int i = elementPermutation.IndexOf(GetPlayerElement(playerIndex)); switch (i) { case 0: t.Add(playerPermutation[elementPermutation[1]]); t.Add(playerPermutation[elementPermutation[2]]); break; case 1: t.Add(playerPermutation[elementPermutation[2]]); t.Add(playerPermutation[elementPermutation[4]]); break; case 2: t.Add(playerPermutation[elementPermutation[3]]); t.Add(playerPermutation[elementPermutation[1]]); break; case 3: t.Add(playerPermutation[elementPermutation[4]]); t.Add(playerPermutation[elementPermutation[0]]); break; case 4: t.Add(playerPermutation[elementPermutation[0]]); t.Add(playerPermutation[elementPermutation[3]]); break; } return(t); }
//Called by commands from clients to process key input public void SendInput(KeyCode input, NetworkIdentity playerId) { if (!isServer) { return; } //Finds the player's data by cross-ref the playerId with the list of player id's int playerDataId = (int)playerId.netId.Value; int playerIndex = players.IndexOf(playerDataId); PlayerData inputSourceData = playerData.GetItem(playerIndex); //Creates a vector to represent intended move direction of player Vector2 moveDirection = Vector2.zero; if (input == KeyCode.W) { moveDirection = Vector2.down; } else if (input == KeyCode.A) { moveDirection = Vector2.left; } else if (input == KeyCode.S) { moveDirection = Vector2.up; } else if (input == KeyCode.D) { moveDirection = Vector2.right; } Vector2 playerHeadPos = new Vector2(inputSourceData.x, inputSourceData.y); Cell currHeadCell = data.GetMostCurrentCell(playerHeadPos); //Calculate movement if input is movement if (moveDirection != Vector2.zero) { Cell targetCell = data.GetMostCurrentCell(playerHeadPos + moveDirection); if (!targetCell.obstacle && !targetCell.occupied) { //Make all the cell updates needed to move the head of the snake data.QueueUpdateColor(targetCell.x, targetCell.y, inputSourceData.color); data.QueueUpdateOccupied(targetCell.x, targetCell.y, true); data.QueueUpdateIsHead(targetCell.x, targetCell.y, true); data.QueueUpdateDistToTail(targetCell.x, targetCell.y, currHeadCell.distToTail + 1); data.QueueUpdatePainted(targetCell.x, targetCell.y, true); data.QueueUpdatePlayer(targetCell.x, targetCell.y, inputSourceData.id); data.QueueUpdateIsHead(currHeadCell.x, currHeadCell.y, false); //Update the PlayerData with the new head position inputSourceData.SetX(targetCell.x); inputSourceData.SetY(targetCell.y); //Update variable for later use playerHeadPos += moveDirection; //Play SFX RpcPlayOneShotOnClients(0); } //Update length of tail after movement Cell updatedTargetCell = data.GetMostCurrentCell(playerHeadPos); if (updatedTargetCell.distToTail > inputSourceData.length) { bool finishedTailUpdate = false; Vector2 tailUpdateLocation = playerHeadPos; //Update distance for each segment of snake while (!finishedTailUpdate) { int newDist = data.GetMostCurrentCell(tailUpdateLocation).distToTail - 1; data.QueueUpdateDistToTail((int)tailUpdateLocation.x, (int)tailUpdateLocation.y, newDist); if (newDist < 0) { data.QueueUpdateOccupied((int)tailUpdateLocation.x, (int)tailUpdateLocation.y, false); } //Look for next further segment in all directions Vector2[] directions = new Vector2[] { Vector2.up, Vector2.left, Vector2.down, Vector2.right }; bool foundNext = false; foreach (Vector2 searchDir in directions) { Vector2 searchPos = tailUpdateLocation + searchDir; Cell checkCell = data.GetMostCurrentCell(searchPos); if (checkCell.occupied && checkCell.player == inputSourceData.id && checkCell.distToTail == newDist) { foundNext = true; tailUpdateLocation = searchPos; break; } } if (!foundNext) { finishedTailUpdate = true; } } } } //VERY IMPORTANT //Up until this point, all updates to the grid are being stored in a temporary hashmap. //This takes those updates and applies them to the synclist so that any cell updates //are applied with only one actual network update per cell data.ApplyUpdates(); //Updates the data of the player that produced the input across all instances of game playerData.RemoveAt(playerIndex); playerData.Insert(playerIndex, inputSourceData); //Update's player's camera to focus on new head cell playerId.GetComponentInParent <PlayerConnectionComponent>().RpcUpdateCamera(new Vector2Int(inputSourceData.x, inputSourceData.y)); }
public int GetPlayerElement(int playerIndex) { return(playerPermutation.IndexOf(playerIndex)); }