一共设有3个类,分别管理网络、棋子、角色。
- 网络类里主要是关于Photon的通信和ui上的处理
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
using DG.Tweening;
public enum PlayerType
{
none=-1,
black,
white,
}
public class NetWorkManager : MonoBehaviourPunCallbacks
{
public GameObject mPlayer;
public PlayerType playerTurn = PlayerType.black;
public List<Vector2> piecePos = new List<Vector2>();
private PhotonView photonView;
public GameObject mGoGameOver;
public AudioSource audio;
[Header("Room")]
public InputField mInputRoom;
public Button mBtnEnter;
private string mRoom;
private List<string> mRoomList = new List<string>();
public int mRoomMaxCount = 2;
public GameObject mGoHintCount;
public GameObject mGoRoom;
public GameObject mGoCheckerboard;
public Text mTxtRoomName;
[Header("界面")]
public GameObject mGoInterface;
public GameObject mBtnStart;
public GameObject mGoStartHint;
public GameObject mGoStart;
public Text mTxtThis;
public Text mTxtOther;
public Text mTxtChess;
private void Awake()
{
Screen.SetResolution(480, 800, false);
photonView = GetComponent<PhotonView>();
}
void Start()
{
PhotonNetwork.ConnectUsingSettings();
mBtnEnter.onClick.AddListener(() => {
mRoom = mInputRoom.text;
if (!string.IsNullOrEmpty(mRoom) && PhotonNetwork.IsConnected)
{
if (GetRoomCount() > mRoomMaxCount)
{
photonView.RPC("HintCount", RpcTarget.All);
}
else
{
RoomOptions room = new RoomOptions();
room.MaxPlayers = 2;
PhotonNetwork.JoinOrCreateRoom(mRoom, room, TypedLobby.Default);
}
}
});
mBtnStart.GetComponent<Button>().onClick.AddListener(() => {
if (GetRoomCount() == mRoomMaxCount)
{
photonView.RPC("OnStart", RpcTarget.All);
}
else
{
mGoStartHint.SetActive(true);
}
});
}
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
}
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
photonView.RPC("CreateRoom", RpcTarget.All);
if (mPlayer != null)
{
GameObject go = PhotonNetwork.Instantiate(mPlayer.name, Vector3.zero, mPlayer.transform.rotation);
if (PhotonNetwork.IsMasterClient)
{
go.GetComponent<Player>().Init(PlayerType.black, this);
}
else
{
go.GetComponent<Player>().Init(PlayerType.white, this);
}
}
}
/// <summary>
/// 是否可以下棋
/// </summary>
/// <param name="_pos"></param>
/// <returns></returns>
public bool IsChess(int[] _pos)
{
if (_pos.Length != 2) return false;
if (_pos[0] < 0 || _pos[0] > 14 || _pos[1] < 0 || _pos[1] > 14) return false;
foreach (var item in piecePos)
{
if (item.x == _pos[0] && item.y == _pos[1]) return false;
}
return true;
}
#region PunRPC
[PunRPC]
private void OnPunRPC(int[] _pos)
{
playerTurn = playerTurn == PlayerType.black ? PlayerType.white : PlayerType.black;
if (_pos.Length != 2) return;
piecePos.Add(new Vector2(_pos[0], _pos[1]));
}
[PunRPC]
private void OnOver()
{
mGoGameOver.SetActive(true);
}
[PunRPC]
private void CreateRoom()
{
photonView.RPC("AppendRoom", RpcTarget.All);
mGoCheckerboard.SetActive(true);
mGoRoom.SetActive(false);
mGoInterface.SetActive(true);
mTxtRoomName.text = mRoom;
if (PhotonNetwork.IsMasterClient)
{
mTxtThis.text = "白棋";
mTxtOther.text = "黑棋";
}
else
{
mTxtThis.text = "黑棋";
mTxtOther.text = "白棋";
}
switch (playerTurn)
{
case PlayerType.black:
mTxtChess.text = "请持黑色玩家下棋";
break;
case PlayerType.white:
mTxtChess.text = "请持白色玩家下棋";
break;
}
}
[PunRPC]
private void HintCount()
{
mGoHintCount.SetActive(true);
//DOVirtual.DelayedCall(1.5f, () => {
// mGoHintCount.SetActive(false);
//});
}
[PunRPC]
public void OnStart()
{
mGoStart.SetActive(true);
mBtnStart.SetActive(false);
mGoStartHint.SetActive(false);
}
[PunRPC]
public void AppendRoom()
{
mRoomList.Add(mRoom);
}
[PunRPC]
public void PlayChess()
{
switch (playerTurn)
{
case PlayerType.black:
mTxtChess.text = "请持黑色玩家下棋";
break;
case PlayerType.white:
mTxtChess.text = "请持白色玩家下棋";
break;
}
}
public void RPC(int[] _pos)
{
photonView.RPC("OnPunRPC", RpcTarget.All, _pos);
photonView.RPC("PlayChess", RpcTarget.All);
}
public void GameOver()
{
photonView.RPC("OnOver", RpcTarget.All);
}
private int GetRoomCount()
{
int _count = 0;
foreach (var item in mRoomList)
{
if (item == mRoom)
{
_count++;
}
}
return _count;
}
#endregion
public void Audio()
{
audio.Play();
}
}
- 角色类是棋子的控制对象,棋子生成、落子位置、可落子范围,当前位置可落子等
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Photon.Pun;
using UnityEngine;
public enum Dir
{
Up,
Down,
left,
Right,
leftUp,
RightDown,
leftDown,
RightUp,
}
public class Player : MonoBehaviour
{
public Vector3 zeroPointPosition;
public float cellWidth;
public int row, column;
public PlayerType playerType = PlayerType.none;
public GameObject mGoBlack, mGoWhite;
private PhotonView photonView;
private Vector3 mousePos, offsetPos,piecePos;
public List<Piece> pieces = new List<Piece>();
private NetWorkManager netWorkManager;
private void Awake()
{
photonView = GetComponent<PhotonView>();
}
void Update()
{
if (!photonView.IsMine) return;
if (netWorkManager.playerTurn != playerType) return;
if (Input.GetMouseButtonDown(0))
{
//计算位置
mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
offsetPos = mousePos - zeroPointPosition;
row = (int)Mathf.Round(offsetPos.y / cellWidth);
column = (int)Mathf.Round(offsetPos.x / cellWidth);
//判断该位置能不能下
int[] rowColumnValue = { row, column };
if (!netWorkManager.IsChess(rowColumnValue)) return;
//创建棋子
piecePos = new Vector3(column * cellWidth, row * cellWidth, zeroPointPosition.z) + zeroPointPosition;
GameObject goPiece = null;
switch (playerType)
{
case PlayerType.black:
goPiece = PhotonNetwork.Instantiate(mGoBlack.name, piecePos, mGoBlack.transform.rotation);
break;
case PlayerType.white:
goPiece = PhotonNetwork.Instantiate(mGoWhite.name, piecePos, mGoWhite.transform.rotation);
break;
}
//播放音频
netWorkManager.Audio();
//设置棋子位置并保存
Piece _piece = goPiece.GetComponent<Piece>();
pieces.Add(_piece);
_piece.SetRowColumnValue(rowColumnValue);
//切换下棋角色且记录所有棋子位置
netWorkManager.RPC(rowColumnValue);
//判断是否5连
bool result = _piece.IsFive(pieces);
if (result)
{
netWorkManager.GameOver();
}
}
}
public void Init(PlayerType _type, NetWorkManager _manager)
{
playerType = _type;
netWorkManager = _manager;
}
}
- 棋子类主要是5连完成判断
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
public class Piece : MonoBehaviour
{
public int row;
public int column;
public PlayerType playerType = PlayerType.none;
private PhotonView photonView;
void Awake()
{
photonView = GetComponent<PhotonView>();
}
[PunRPC]
private void RowColumn(int[] _rowColumnValue)
{
if (_rowColumnValue.Length != 2) return;
row = _rowColumnValue[0];
column = _rowColumnValue[1];
}
public void SetRowColumnValue(int[] _rowColumnValue)
{
photonView.RPC("RowColumn", RpcTarget.All, _rowColumnValue);
}
/// <summary>
/// 是否5连
/// </summary>
/// <returns></returns>
public bool IsFive(List<Piece> _pieces)
{
if((PieceCount(_pieces, Dir.Up) + PieceCount(_pieces, Dir.Down) + 1)==5
|| (PieceCount(_pieces, Dir.left) + PieceCount(_pieces, Dir.Right) + 1) == 5
|| (PieceCount(_pieces, Dir.leftUp) + PieceCount(_pieces, Dir.RightDown) + 1) == 5
|| (PieceCount(_pieces, Dir.leftDown) + PieceCount(_pieces, Dir.RightUp) + 1) == 5
)
{
return true;
}
return false;
}
public int PieceCount(List<Piece> _pieces, Dir _dir)
{
int count = 0;
switch (_dir)
{
case Dir.Up:
foreach (var item in _pieces)
{
if (row + 1 == item.row && column == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.Up);
}
}
break;
case Dir.Down:
foreach (var item in _pieces)
{
if (row - 1 == item.row && column == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.Down);
}
}
break;
case Dir.left:
foreach (var item in _pieces)
{
if (row == item.row && column - 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.left);
}
}
break;
case Dir.Right:
foreach (var item in _pieces)
{
if (row == item.row && column + 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.Right);
}
}
break;
case Dir.leftUp:
foreach (var item in _pieces)
{
if (row - 1 == item.row && column + 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.leftUp);
}
}
break;
case Dir.RightDown:
foreach (var item in _pieces)
{
if (row + 1 == item.row && column - 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.RightDown);
}
}
break;
case Dir.leftDown:
foreach (var item in _pieces)
{
if (row - 1 == item.row && column - 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.leftDown);
}
}
break;
case Dir.RightUp:
foreach (var item in _pieces)
{
if (row + 1 == item.row && column + 1 == item.column)
{
count++;
count += item.PieceCount(_pieces, Dir.RightUp);
}
}
break;
}
return count;
}
}