最近,我用了不少时间写了一个象棋游戏,旨在锻炼我的编写思维和能力,还有就是慢慢学习那80%的知识(20%的是基础知识);这个象棋游戏大体已经完成了,但还是有一些是我现在无法做到的,比如游戏里面的电脑,再比如怎样编写一个更好更健全的网络同步体系,这些都是我现在无法做到的;编写此博客的目的在于把我最近写这个项目的一些思路分享给大家,让我以后也可以看看,因为东西多了,脑子也记不住,需要写下来才能方便查找,好了废话说完了,该进入正题:
我的项目资源连接:
链接:https://pan.baidu.com/s/1xJOvEl6nhlMGRgnTEdaawg
提取码:knre
在项目资源里,有一部分是关于象棋联机的,由于联机我还没有学的太明白,在这里就不做说明了,我也会单独写一个关于游戏联机的博客,以此来记录学习知识,在以后方便查阅。
一、思路、方法
我的设计思路是:定义了两个枚举类型:第一个是关于棋的颜色的枚举类型,第二个是关于棋的名字的枚举类型,有了这两个枚举类型,我们就能很好的区分每个棋,这在后面的条件判断中也能很方便的调用,
//棋名
public enum ChessName
{
Shuai,//帅
Shi,//士
Xiang,//象
Ma,//马
Che,//车
Pao,//炮
Bing//兵
}
//队伍种类
public enum Team
{
Red,//红队
Black//黑队
}
分好了棋子,接着就是棋盘,在这里,我定义了一个GameObject类型的数组,其大小与棋盘一致,棋盘搞好了,就可以在上面摆棋子了,摆棋子当然需要坐标,所以你得先把32颗棋子的X、Y坐标给记录下来,这个不难,时间决定,我先把棋子坐标用数组记录下来,然后我们开始设计棋子类,我的想法是这个棋子类包含所有棋子的形态,这样我们就可以一个对象创建多个实例,而不是多个对象创建多个实例;所以这个棋子类要包含所有棋子的走法,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
//棋名
public enum ChessName
{
Shuai,//帅
Shi,//士
Xiang,//象
Ma,//马
Che,//车
Pao,//炮
Bing//兵
}
public class Chess : MonoBehaviour
{
//图片数组
public Sprite[] sprites;
//子物体Image上的Image组件
private Image selfImage;
//该棋子所属队伍
public Team selfTeam { set; get; }
//该棋子的棋名
public ChessName selfChessName { set; get; }
//该场景的第一个游戏逻辑组件
private Scene02GameController_1 GameController_1;
//在棋盘上的坐标的x轴
public int x { set; get; }
//在棋盘上的坐标的y轴
public int y { set; get; }
//游戏对象,作用:显示棋子能走的地方
public GameObject canDownChessPoint;
//盛放canUpChessPoint的容器
[HideInInspector]
public List<GameObject> canDownChessPoints = new List<GameObject>();
//控制canUpChessPoints的操作
[HideInInspector]
public bool isClick = false;
//用于区分楚河上方和下方的棋子,在棋子创建之初,初始化
public int distinguish { set; get; }
void Start () {
//获取子物体Image上的Image组件
selfImage = transform.Find("Image").GetComponent<Image>();
//如果棋的selfTeam属性为Red,则是红棋
if (selfTeam == Team.Red)
{
//根据selfChessName,即棋的名字选择并切换图片
switch (selfChessName)
{
case ChessName.Shuai:
selfImage.sprite = sprites[7];
break;
case ChessName.Shi:
selfImage.sprite = sprites[8];
break;
case ChessName.Xiang:
selfImage.sprite = sprites[9];
break;
case ChessName.Ma:
selfImage.sprite = sprites[10];
break;
case ChessName.Che:
selfImage.sprite = sprites[11];
break;
case ChessName.Pao:
selfImage.sprite = sprites[12];
break;
case ChessName.Bing:
selfImage.sprite = sprites[13];
break;
}
}
//否则,为黑棋
else
{
//根据selfChessName,即棋的名字选择并切换图片
switch (selfChessName)
{
case ChessName.Shuai:
selfImage.sprite = sprites[0];
break;
case ChessName.Shi:
selfImage.sprite = sprites[1];
break;
case ChessName.Xiang:
selfImage.sprite = sprites[2];
break;
case ChessName.Ma:
selfImage.sprite = sprites[3];
break;
case ChessName.Che:
selfImage.sprite = sprites[4];
break;
case ChessName.Pao:
selfImage.sprite = sprites[5];
break;
case ChessName.Bing:
selfImage.sprite = sprites[6];
break;
}
}
//获取该场景的第一个游戏逻辑组件
GameController_1 = GameObject.FindWithTag("GameController").GetComponent<Scene02GameController_1>();
//如果开始时y<5
if (y < 5)
{
distinguish = 1;
}
else
{
distinguish = 2;
}
}
private void Update()
{
if (isClick)
{
//如果鼠标左键按下
if (Input.GetMouseButtonDown(0))
{
//如果canUpChessPoints的长度不为零
if (canDownChessPoints.Count != 0)
{
foreach (GameObject game in canDownChessPoints)
{
//删除
Destroy(game);
}
//清空canUpChessPoints里所有的元素
canDownChessPoints.Clear();
}
//把isClick设置为flase
isClick = false;
}
}
}
//当指针移入该控件时调用
public void OnPointerEnter()
{
//如果游戏没有结束了
if (!GameController_1.isGameOver && !GameController_1.isPause)
{
//如果该棋子是我方棋子
if (selfTeam == GameController_1.selfTeam)
{
//则加深棋子整体的颜色
selfImage.color = new Color((float)186 / 255, (float)186 / 255, (float)186 / 255);
}
}
}
//当指针移出该控件时调用
public void OnPointerExit()
{
//设置棋子整体的颜色
selfImage.color = new Color(1, 1, 1);
}
//当指针在该控件上按下时调用
public void OnPointerDown()
{
//如果游戏没有结束了
if (!GameController_1.isGameOver && !GameController_1.isPause)
{
//如果你选择的颜色与棋子的颜色一致
if (selfTeam == GameController_1.selfTeam)
{
if (!isClick)
{
JudgeWalking();
//延迟执行本属于OnPointerDownDelay方法里代码
Invoke("OnPointerDownDelay", 0.1f);
}
}
}
}
//判断行走
public void JudgeWalking()
{
//如果他是帅
if (selfChessName == ChessName.Shuai)
{
//向右摸索前进一格
if (x + 1 <= 5)
{
ShuaiShiBingGo(x + 1, y);
}
//向左摸索前进一格
if (x - 1 >= 3)
{
ShuaiShiBingGo(x - 1, y);
}
//如果是楚河下方的帅
if (y > 5)
{
//向下摸索前进一格
if (y + 1 < 10)
{
ShuaiShiBingGo(x, y + 1);
}
//向上摸索前进一格
if (y - 1 >= 7)
{
ShuaiShiBingGo(x, y - 1);
}
}
//如果是楚河上方的帅
else
{
//向下摸索前进一格
if (y + 1 <= 2)
{
ShuaiShiBingGo(x, y + 1);
}
//向上摸索前进一格
if (y - 1 >= 0)
{
ShuaiShiBingGo(x, y - 1);
}
}
}
//如果他是士
else if (selfChessName == ChessName.Shi)
{
//如果是楚河下方的的士
if (y > 5)
{
//向右下方摸索前进
if (x + 1 <= 5 && y + 1 < 10)
{
ShuaiShiBingGo(x + 1, y + 1);
}
//向右上方摸索前进
if (x + 1 <= 5 && y - 1 >= 7)
{
ShuaiShiBingGo(x + 1, y - 1);
}
//向左下方摸索前进
if (x - 1 >= 3 && y + 1 < 10)
{
ShuaiShiBingGo(x - 1, y + 1);
}
//向右上方摸索前进
if (x - 1 >= 3 && y - 1 >= 7)
{
ShuaiShiBingGo(x - 1, y - 1);
}
}
//否则,士楚河上方的士
else
{
//向右下方摸索前进
if (x + 1 <= 5 && y + 1 <= 2)
{
ShuaiShiBingGo(x + 1, y + 1);
}
//向右上方摸索前进
if (x + 1 <= 5 && y - 1 >= 0)
{
ShuaiShiBingGo(x + 1, y - 1);
}
//向左下方摸索前进
if (x - 1 >= 3 && y + 1 <= 2)
{
ShuaiShiBingGo(x - 1, y + 1);
}
//向右上方摸索前进
if (x - 1 >= 3 && y - 1 >= 0)
{
ShuaiShiBingGo(x - 1, y - 1);
}
}
}
//如果他是象
else if (selfChessName == ChessName.Xiang)
{
//如果distinguish为一
if (distinguish == 1)
{
//向右下方走
if (x + 2 < 9 && y + 2 < 5)
{
//表示是否能走
bool isGo = false;
//判断是否有棋子阻挡
MaXiangGo(x + 1, y + 1, ref isGo);
if (isGo)
{
MaXiangGo(x + 2, y + 2, ref isGo);
}
}
//向右上方走
if (x + 2 < 9 && y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(x + 1, y - 1, ref isGo);
if (isGo)
{
MaXiangGo(x + 2, y - 2, ref isGo);
}
}
//向左下方走
if (x - 2 >= 0 && y + 2 < 5)
{
bool isGo = false;
MaXiangGo(x - 1, y + 1, ref isGo);
if (isGo)
{
MaXiangGo(x - 2, y + 2, ref isGo);
}
}
//向右上方走
if (x - 2 >= 0 && y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(x - 1, y - 1, ref isGo);
if (isGo)
{
MaXiangGo(x - 2, y - 2, ref isGo);
}
}
}
//否则:
else
{
//向右下方走
if (x + 2 < 9 && y + 2 < 10)
{
bool isGo = false;
MaXiangGo(x + 1, y + 1, ref isGo);
if (isGo)
{
MaXiangGo(x + 2, y + 2, ref isGo);
}
}
//向右上方走
if (x + 2 < 9 && y - 2 >= 5)
{
bool isGo = false;
MaXiangGo(x + 1, y - 1, ref isGo);
if (isGo)
{
MaXiangGo(x + 2, y - 2, ref isGo);
}
}
//向左下方走
if (x - 2 >= 0 && y + 2 < 10)
{
bool isGo = false;
MaXiangGo(x - 1, y + 1, ref isGo);
if (isGo)
{
MaXiangGo(x - 2, y + 2, ref isGo);
}
}
//向右上方走
if (x - 2 >= 0 && y - 2 >= 5)
{
bool isGo = false;
MaXiangGo(x - 1, y - 1, ref isGo);
if (isGo)
{
MaXiangGo(x - 2, y - 2, ref isGo);
}
}
}
}
//如果他是马
else if (selfChessName == ChessName.Ma)
{
//向右摸索
if (x + 2 < 9)
{
//isGo是表示该方向的前一格有没有棋子
//如果有就为false,表示不能通过
//如果没有就为true,表示可以通过
bool isGo = false;
//开始检查
MaXiangGo(x + 1, y, ref isGo);
if (isGo)//结果判断
{
//马走的两个路线
if (y + 1 < 10)
{
MaXiangGo(x + 2, y + 1, ref isGo);
}
if (y - 1 >= 0)
{
MaXiangGo(x + 2, y - 1, ref isGo);
}
}
}
//向左摸索
if (x - 2 >= 0)
{
//isGo是表示该方向的前一格有没有棋子
//如果有就为false,表示不能通过
//如果没有就为true,表示可以通过
bool isGo = false;
//开始检查
MaXiangGo(x - 1, y, ref isGo);
if (isGo)//结果判断
{
//马走的两个路线
if (y + 1 < 10)
{
MaXiangGo(x - 2, y + 1, ref isGo);
}
if (y - 1 >= 0)
{
MaXiangGo(x - 2, y - 1, ref isGo);
}
}
}
//向下摸索
if (y + 2 < 10)
{
bool isGo = false;
MaXiangGo(x, y + 1, ref isGo);
if (isGo)
{
if (x + 1 < 9)
{
MaXiangGo(x + 1, y + 2, ref isGo);
}
if (x - 1 >= 0)
{
MaXiangGo(x - 1, y + 2, ref isGo);
}
}
}
//向上摸索
if (y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(x, y - 1, ref isGo);
if (isGo)
{
if (x + 1 < 9)
{
MaXiangGo(x + 1, y - 2, ref isGo);
}
if (x - 1 >= 0)
{
MaXiangGo(x - 1, y - 2, ref isGo);
}
}
}
}
//如果他是车
else if (selfChessName == ChessName.Che)
{
//向右摸索前进
for (int i = 1; x + i < 9; i++)
{
if (CheGo(x + i, y))
{
break;
}
}
//向左摸索前进
for (int i = 1; x - i >= 0; i++)
{
if (CheGo(x - i, y))
{
break;
}
}
//向下摸索前进
for (int i = 1; y + i < 10; i++)
{
if (CheGo(x, y + i))
{
break;
}
}
//向上摸索前进
for (int i = 1; y - i >= 0; i++)
{
if (CheGo(x, y - i))
{
break;
}
}
}
//如果他是炮
else if (selfChessName == ChessName.Pao)
{
//向右摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; x + i < 9; i++)
{
if (PaoGo(x + i, y, ref fire))
{
break;
}
}
}
//向左摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; x - i >= 0; i++)
{
if (PaoGo(x - i, y, ref fire))
{
break;
}
}
}
//向下摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; y + i < 10; i++)
{
if (PaoGo(x, y + i, ref fire))
{
break;
}
}
}
//向上摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; y - i >= 0; i++)
{
if (PaoGo(x, y - i, ref fire))
{
break;
}
}
}
}
//如果他是兵
else if (selfChessName == ChessName.Bing)
{
//控制兵是否能左右行走
bool around = false;
//如果这是楚河上方的兵
if (distinguish == 1)
{
//向前摸索行走
if (y + 1 < 10)
{
ShuaiShiBingGo(x, y + 1);
}
//如果这个兵过了楚河
if (y >= 5)
{
around = true;
}
}
//否则是楚河下方的兵
else
{
//向前摸索行走
if (y - 1 >= 0)
{
ShuaiShiBingGo(x, y - 1);
}
//如果这个兵过了楚河
if (y <= 4)
{
around = true;
}
}
//这个兵是否能左右行走
if (around)
{
//向右摸索前进一格
if (x + 1 < 9)
{
ShuaiShiBingGo(x + 1, y);
}
//向左摸索前进一格
if (x - 1 >= 0)
{
ShuaiShiBingGo(x - 1, y);
}
}
}
}
//延迟执行本属于OnPointerDownDelay方法里代码
public void OnPointerDownDelay()
{
//设置isClick为true
isClick = true;
}
//帅、士、兵的走法
private void ShuaiShiBingGo(int a, int b)
{
//如果棋盘上的(b,a)坐标为空
if (GameController_1.checkerboard[b, a] != null)
{
//如果该坐标上有棋子,且为敌方棋子
if (GameController_1.checkerboard[b, a].GetComponent<Chess>().selfTeam != selfTeam)
{
//则该座标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
}
//否则
else
{
//该坐标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game的CanUpChessPoint的Chess
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
}
//车的走法
private bool CheGo(int a, int b)
{
//如果棋盘上的(b,a)坐标为空
if (GameController_1.checkerboard[b, a] != null)
{
//如果该坐标上有棋子,且为敌方棋子
if (GameController_1.checkerboard[b, a].GetComponent<Chess>().selfTeam != selfTeam)
{
//则该座标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
//运行到此行,说明前方有我方棋子,因被我方棋子挡住,就不能前进
//返回true,让上面执行break退出for循环
return true;
}
//否则
else
{
//该坐标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
//运行到此行,说明该点无棋子,可以行走,可以继续向前摸索
//返回false,让上面不执行break继续for循环
return false;
}
}
//炮的走法
private bool PaoGo(int a, int b, ref bool fire)
{
//如果棋盘上的(b,a)坐标为空
if (GameController_1.checkerboard[b, a] != null)
{
//如果fire为true,则表示进入开炮状态
if (fire)
{
//如果该坐标上有棋子,且为敌方棋子
if (GameController_1.checkerboard[b, a].GetComponent<Chess>().selfTeam != selfTeam)
{
//则该座标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
//运行到此行,说明前方有我方棋子,因被我方棋子挡住,就不能前进
//返回true,让上面执行break退出for循环
return true;
}
//否则
else
{
//fire设为true,表示可以打炮
fire = true;
//运行到此行,说明刚刚开始隔棋打棋,虽然该点有棋子,但是要作为支点
//返回false,让上面不执行break,继续for循环
return false;
}
}
//否则
else
{
//如果fire为true,则表示进入开炮状态
if (fire)
{
//运行到此行,说明已经隔棋打棋,不过该点没有棋子
//返回false,让上面不执行break,继续for循环
return false;
}
//否则
else
{
//该坐标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
//运行到此行,说明该点无棋子,可以行走,可以继续向前摸索
//返回false,让上面不执行break,继续for循环
return false;
}
}
}
//马、象的走法
private void MaXiangGo(int a, int b, ref bool isGo)
{
//如果棋盘上的(b,a)坐标为空
if (GameController_1.checkerboard[b, a] != null)
{
//能否通行
if (isGo)
{
//如果该坐标上有棋子,且为敌方棋子
if (GameController_1.checkerboard[b, a].GetComponent<Chess>().selfTeam != selfTeam)
{
//则该座标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
}
}
//否则
else
{
//能否通行
if (isGo)
{
//该坐标可以作为下棋的点
GameObject game = Instantiate(canDownChessPoint,
transform.position + new Vector3((a - x) * 0.5f, (y - b) * 0.5f, 0), Quaternion.identity);
//设置canUpChessPoint实例对象的x和y
game.GetComponent<CanDownChessPoint>().x = a;
game.GetComponent<CanDownChessPoint>().y = b;
//将自身传给game
game.GetComponent<CanDownChessPoint>().chess = transform.gameObject;
//加入到该容器中
canDownChessPoints.Add(game);
}
else
{
//设置为true,就是能通行
isGo = true;
}
}
}
}
以上就是我设计的棋子类,除了棋子类,我还设计了一个棋子可行走区域的类,他在游戏是用一块半透明的黑布来作为本身,他的作用:是表示可行走区域,玩家点击之后,棋子可以移动到点击点;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class CanDownChessPoint : MonoBehaviour
{
//绑定的棋子chess
public GameObject chess { get; set; }
//该场景的第一个游戏逻辑组件
private Scene02GameController_1 GameController_1;
//在棋盘上的坐标的x轴
public int x { set; get; }
//在棋盘上的坐标的y轴
public int y { set; get; }
//黑棋赢的Text游戏对象
private GameObject blackWinText;
//红棋赢的Text游戏对象
private GameObject redWinText;
void Start () {
//获取该场景的第一个游戏逻辑组件
GameController_1 = GameObject.Find("GameController").GetComponent<Scene02GameController_1>();
//获取黑棋赢的Text游戏对象
blackWinText = GameObject.Find("Canvas").transform.Find("BlackWinText").gameObject;
//获取红棋赢的Text游戏对象
redWinText = GameObject.Find("Canvas").transform.Find("RedWinText").gameObject;
//在这里获取移动的棋子
GameController_1.moveChess = chess;
}
//当指针在该控件上按下
public void OnPointerDown()
{
//获取chess原来的坐标x、y
int temporaryX = chess.GetComponent<Chess>().x;
int temporaryY = chess.GetComponent<Chess>().y;
//获取要被吃的棋子,如果没有就为null
GameObject game = null;
//棋盘数组上的原来位置设为空
GameController_1.checkerboard[chess.GetComponent<Chess>().y, chess.GetComponent<Chess>().x] = null;
//如果棋盘上[y,x]的位置有他方棋子,则吃掉它
if (GameController_1.checkerboard[y, x] != null)
{
//获取要被吃的棋子
game = GameController_1.checkerboard[y, x];
//隐藏要被吃的棋子
game.SetActive(false);
}
//在棋盘上[y,x]的位置设置该棋子对象
GameController_1.checkerboard[y, x] = chess;
//更新棋子对象的x和y
chess.GetComponent<Chess>().x = x;
chess.GetComponent<Chess>().y = y;
//执行绝杀方法
GameController_1.Lonely();
//如果绝杀isLonely为true,则棋盘上有棋将军
if (GameController_1.isLonely)
{
//如果被将军方与下棋方相同
if (GameController_1.lonelyObjectTeam == chess.GetComponent<Chess>().selfTeam)
{
//则不能下棋
//把要移动的棋子移回原来的位置
GameController_1.checkerboard[temporaryY, temporaryX] = chess;
//如果他吃了棋子
if (game != null)
{
//就把该位置给吃掉的棋子,并显示他
GameController_1.checkerboard[y, x] = game;
game.SetActive(true);
}
//否则,该位置就为null
else
{
GameController_1.checkerboard[y, x] = null;
}
//重置棋子对象的x和y
chess.GetComponent<Chess>().x = temporaryX;
chess.GetComponent<Chess>().y = temporaryY;
}
//否则
else
{
//吃掉棋子
Destroy(game);
//移动要移动的棋子
chess.transform.position = transform.position;
//切换下棋
if (GameController_1.selfTeam == Team.Red)
{
GameController_1.selfTeam = Team.Black;
}
else
{
GameController_1.selfTeam = Team.Red;
}
}
GameController_1.isLonely = false;
}
//否则
else
{
//吃掉棋子
Destroy(game);
//移动要移动的棋子
chess.transform.position = transform.position;
//切换下棋
if (GameController_1.selfTeam == Team.Red)
{
GameController_1.selfTeam = Team.Black;
}
else
{
GameController_1.selfTeam = Team.Red;
}
}
}
}
以上就是这个类的全部代码,在我这个游戏里除了这两个类,还有一个游戏逻辑类,游戏逻辑类用来处理游戏开始时、游戏进行时、游戏结束时的一些事件;比如将军、绝杀等象棋里的一些事件,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
//队伍种类
public enum Team
{
Red,//红队
Black//黑队
}
public class Scene02GameController_1 : MonoBehaviour {
//棋子预制体
public GameObject chess;
[HideInInspector]
public List<GameObject> chessBox= new List<GameObject>();//我方棋子容器
[HideInInspector]
public GameObject[,] checkerboard = new GameObject[10,9];//整个棋盘数组
//开始时棋子所在的点
public Vector2[] pointBox;
//红方帅游戏对象
private GameObject redShuai;
//黑方帅游戏对象
private GameObject blackShuai;
//我选择的棋的颜色
public Team selfTeam = Team.Red;
[HideInInspector]
public bool isGameOver = false;//控制游戏结束
[HideInInspector]
public bool isPause = false;//控制游戏暂停
//黑棋赢的Text游戏对象
private GameObject blackWinText;
//红棋赢的Text游戏对象
private GameObject redWinText;
//游戏设置对象
private GameObject setting;
//是否绝杀
public bool isLonely { set; get; }
//被将军的帅的颜色
public Team lonelyObjectTeam { set; get; }
//移动的棋子对象
public GameObject moveChess { set; get; }
void Start () {
//获取黑棋赢的Text游戏对象
blackWinText = GameObject.Find("Canvas").transform.Find("BlackWinText").gameObject;
//获取红棋赢的Text游戏对象
redWinText = GameObject.Find("Canvas").transform.Find("RedWinText").gameObject;
//获取游戏设置对象
setting = GameObject.Find("Canvas").transform.Find("Setting").gameObject;
//创建32颗棋子
CreateChess();
//设置绝杀bool值
isLonely = false;
}
private void Update()
{
//如果谁输了
if (isGameOver)
{
if (Input.GetKeyDown(KeyCode.Space))
{
RenewStart();
}
}
//如果按了Esc键
if (Input.GetKeyDown(KeyCode.Escape))
{
//第二次按关闭,设置为false
if (isPause)
{
//隐藏Setting游戏对象
setting.SetActive(false);
//是否暂停关闭
isPause = false;
}
//第一次按打开,设置为true
else
{
//显示Setting游戏对象
setting.SetActive(true);
//是否暂停打开
isPause = true;
}
}
}
//重新开始游戏
public void RenewStart()
{
//禁止显示Text游戏对象
blackWinText.SetActive(false);
redWinText.SetActive(false);
//清空棋盘数组
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 9; j++)
{
if (checkerboard[i, j] != null)
{
Destroy(checkerboard[i, j]);
}
}
}
//初始化棋盘数组
checkerboard = new GameObject[10, 9];
//创建32颗棋子
CreateChess();
//游戏没有结束
isGameOver = false;
}
//创建32颗棋子
public void CreateChess()
{
//总共要创建32颗棋子
for (int i = 0; i < pointBox.Length; i++)
{
//创建一颗棋子
GameObject game = Instantiate(chess, new Vector3(-2 + pointBox[i].x * 0.5f, 2.25f - pointBox[i].y * 0.5f, 0), Quaternion.identity);
//如果我选的时红棋
if (selfTeam == Team.Red)
{
//把前16个棋子设为黑棋
if (i < 16)
{
game.GetComponent<Chess>().selfTeam = Team.Black;
}
//把后16个棋子设为红棋
else
{
game.GetComponent<Chess>().selfTeam = Team.Red;
//把该棋子加入到我方棋子容器
chessBox.Add(game);
}
}
//否则,我选的是黑棋
else
{
//把前16个棋子设为红棋
if (i < 16)
{
game.GetComponent<Chess>().selfTeam = Team.Red;
}
//把后16个棋子设为黑棋
else
{
game.GetComponent<Chess>().selfTeam = Team.Black;
//把该棋子加入到我方棋子容器
chessBox.Add(game);
}
}
//设置每一颗棋的selfChessName,即棋上面的汉字
switch (i)
{
case 0:
game.GetComponent<Chess>().selfChessName = ChessName.Che;
break;
case 1:
game.GetComponent<Chess>().selfChessName = ChessName.Ma;
break;
case 2:
game.GetComponent<Chess>().selfChessName = ChessName.Xiang;
break;
case 3:
game.GetComponent<Chess>().selfChessName = ChessName.Shi;
break;
case 4:
game.GetComponent<Chess>().selfChessName = ChessName.Shuai;
break;
case 5:
game.GetComponent<Chess>().selfChessName = ChessName.Shi;
break;
case 6:
game.GetComponent<Chess>().selfChessName = ChessName.Xiang;
break;
case 7:
game.GetComponent<Chess>().selfChessName = ChessName.Ma;
break;
case 8:
game.GetComponent<Chess>().selfChessName = ChessName.Che;
break;
case 9:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 10:
game.GetComponent<Chess>().selfChessName = ChessName.Pao;
break;
case 11:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 12:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 13:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 14:
game.GetComponent<Chess>().selfChessName = ChessName.Pao;
break;
case 15:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 16:
game.GetComponent<Chess>().selfChessName = ChessName.Che;
break;
case 17:
game.GetComponent<Chess>().selfChessName = ChessName.Ma;
break;
case 18:
game.GetComponent<Chess>().selfChessName = ChessName.Xiang;
break;
case 19:
game.GetComponent<Chess>().selfChessName = ChessName.Shi;
break;
case 20:
game.GetComponent<Chess>().selfChessName = ChessName.Shuai;
break;
case 21:
game.GetComponent<Chess>().selfChessName = ChessName.Shi;
break;
case 22:
game.GetComponent<Chess>().selfChessName = ChessName.Xiang;
break;
case 23:
game.GetComponent<Chess>().selfChessName = ChessName.Ma;
break;
case 24:
game.GetComponent<Chess>().selfChessName = ChessName.Che;
break;
case 25:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 26:
game.GetComponent<Chess>().selfChessName = ChessName.Pao;
break;
case 27:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 28:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 29:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
case 30:
game.GetComponent<Chess>().selfChessName = ChessName.Pao;
break;
case 31:
game.GetComponent<Chess>().selfChessName = ChessName.Bing;
break;
}
//把棋子放到棋盘数组中
checkerboard[(int)pointBox[i].y, (int)pointBox[i].x] = game;
//让棋子获得它在棋盘中的位置,数组位置
game.GetComponent<Chess>().x = (int)pointBox[i].x;
game.GetComponent<Chess>().y = (int)pointBox[i].y;
//获取红方、黑方的帅
if (game.GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
if (game.GetComponent<Chess>().selfTeam == Team.Red)
{
redShuai = game;
}
else
{
blackShuai = game;
}
}
}
}
//当指针点击Quit时调用
public void OnPointerQuit()
{
//跳到场景一
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(0);
}
//当指针点击Again时调用
public void OnPointerAgain()
{
//隐藏Setting游戏对象
setting.SetActive(false);
//是否暂停打开
isPause = false;
//重新开始游戏
RenewStart();
}
public void Lonely()
{
//这是对所有棋的检测
foreach(GameObject game in checkerboard)
{
if (game != null)
{
JudgeWalking(game);
if (isLonely)
{
break;
}
}
}
//下面是对帅的检测
//如果两个帅在同一行
if (redShuai.GetComponent<Chess>().x == blackShuai.GetComponent<Chess>().x)
{
//此代码块的控制值
int a = 0;
//扫描这一列
for (int i = 0; i < 10; i++)
{
//如果棋盘这个位置有棋子
if (checkerboard[i, redShuai.GetComponent<Chess>().x] != null)
{
//如果该棋子为帅
if (checkerboard[i, redShuai.GetComponent<Chess>().x].GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
a++;
if (a == 2)
{
//绝杀bool值为true,意为:将军
isLonely = true;
//获取被将军的帅的颜色
lonelyObjectTeam = moveChess.GetComponent<Chess>().selfTeam;
break;
}
}
//否则
else
{
if (a != 0)
{
break;
}
}
}
}
}
}
//判断行走
public void JudgeWalking(GameObject game)
{
Chess chess = game.GetComponent<Chess>();
//如果他是帅
if (chess.selfChessName == ChessName.Shuai)
{
//向右摸索前进一格
if (chess.x + 1 <= 5)
{
ShuaiShiBingGo(chess.x + 1, chess.y, chess);
}
//向左摸索前进一格
if (chess.x - 1 >= 3)
{
ShuaiShiBingGo(chess.x - 1, chess.y, chess);
}
//如果是楚河下方的帅
if (chess.y > 5)
{
//向下摸索前进一格
if (chess.y + 1 < 10)
{
ShuaiShiBingGo(chess.x, chess.y + 1, chess);
}
//向上摸索前进一格
if (chess.y - 1 >= 7)
{
ShuaiShiBingGo(chess.x, chess.y - 1, chess);
}
}
//否则是楚河上方的帅
else
{
//向下摸索前进一格
if (chess.y + 1 <= 2)
{
ShuaiShiBingGo(chess.x, chess.y + 1, chess);
}
//向上摸索前进一格
if (chess.y - 1 >= 0)
{
ShuaiShiBingGo(chess.x, chess.y - 1, chess);
}
}
}
//如果他是士
else if (chess.selfChessName == ChessName.Shi)
{
//如果是楚河下方的的士
if (chess.y > 5)
{
//向右下方摸索前进
if (chess.x + 1 <= 5 && chess.y + 1 < 10)
{
ShuaiShiBingGo(chess.x + 1, chess.y + 1, chess);
}
//向右上方摸索前进
if (chess.x + 1 <= 5 && chess.y - 1 >= 7)
{
ShuaiShiBingGo(chess.x + 1, chess.y - 1, chess);
}
//向左下方摸索前进
if (chess.x - 1 >= 3 && chess.y + 1 < 10)
{
ShuaiShiBingGo(chess.x - 1, chess.y + 1, chess);
}
//向右上方摸索前进
if (chess.x - 1 >= 3 && chess.y - 1 >= 7)
{
ShuaiShiBingGo(chess.x - 1, chess.y - 1, chess);
}
}
//否则,士楚河上方的士
else
{
//向右下方摸索前进
if (chess.x + 1 <= 5 && chess.y + 1 <= 2)
{
ShuaiShiBingGo(chess.x + 1, chess.y + 1, chess);
}
//向右上方摸索前进
if (chess.x + 1 <= 5 && chess.y - 1 >= 0)
{
ShuaiShiBingGo(chess.x + 1, chess.y - 1, chess);
}
//向左下方摸索前进
if (chess.x - 1 >= 3 && chess.y + 1 <= 2)
{
ShuaiShiBingGo(chess.x - 1, chess.y + 1, chess);
}
//向右上方摸索前进
if (chess.x - 1 >= 3 && chess.y - 1 >= 0)
{
ShuaiShiBingGo(chess.x - 1, chess.y - 1, chess);
}
}
}
//如果他是象
else if (chess.selfChessName == ChessName.Xiang)
{
//如果distinguish为一
if (chess.distinguish == 1)
{
//向右下方走
if (chess.x + 2 < 9 && chess.y + 2 < 5)
{
//表示是否能走
bool isGo = false;
//判断是否有棋子阻挡
MaXiangGo(chess.x + 1, chess.y + 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x + 2, chess.y + 2, ref isGo, chess);
}
}
//向右上方走
if (chess.x + 2 < 9 && chess.y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(chess.x + 1, chess.y - 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x + 2, chess.y - 2, ref isGo, chess);
}
}
//向左下方走
if (chess.x - 2 >= 0 && chess.y + 2 < 5)
{
bool isGo = false;
MaXiangGo(chess.x - 1, chess.y + 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x - 2, chess.y + 2, ref isGo, chess);
}
}
//向右上方走
if (chess.x - 2 >= 0 && chess.y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(chess.x - 1, chess.y - 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x - 2, chess.y - 2, ref isGo, chess);
}
}
}
//否则:
else
{
//向右下方走
if (chess.x + 2 < 9 && chess.y + 2 < 10)
{
bool isGo = false;
MaXiangGo(chess.x + 1, chess.y + 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x + 2, chess.y + 2, ref isGo, chess);
}
}
//向右上方走
if (chess.x + 2 < 9 && chess.y - 2 >= 5)
{
bool isGo = false;
MaXiangGo(chess.x + 1, chess.y - 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x + 2, chess.y - 2, ref isGo, chess);
}
}
//向左下方走
if (chess.x - 2 >= 0 && chess.y + 2 < 10)
{
bool isGo = false;
MaXiangGo(chess.x - 1, chess.y + 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x - 2, chess.y + 2, ref isGo, chess);
}
}
//向右上方走
if (chess.x - 2 >= 0 && chess.y - 2 >= 5)
{
bool isGo = false;
MaXiangGo(chess.x - 1, chess.y - 1, ref isGo, chess);
if (isGo)
{
MaXiangGo(chess.x - 2, chess.y - 2, ref isGo, chess);
}
}
}
}
//如果他是马
else if (chess.selfChessName == ChessName.Ma)
{
//向右摸索
if (chess.x + 2 < 9)
{
//isGo是表示该方向的前一格有没有棋子
//如果有就为false,表示不能通过
//如果没有就为true,表示可以通过
bool isGo = false;
//开始检查
MaXiangGo(chess.x + 1, chess.y, ref isGo, chess);
if (isGo)//结果判断
{
//马走的两个路线
if (chess.y + 1 < 10)
{
MaXiangGo(chess.x + 2, chess.y + 1, ref isGo, chess);
}
if (chess.y - 1 >= 0)
{
MaXiangGo(chess.x + 2, chess.y - 1, ref isGo, chess);
}
}
}
//向左摸索
if (chess.x - 2 >= 0)
{
//isGo是表示该方向的前一格有没有棋子
//如果有就为false,表示不能通过
//如果没有就为true,表示可以通过
bool isGo = false;
//开始检查
MaXiangGo(chess.x - 1, chess.y, ref isGo, chess);
if (isGo)//结果判断
{
//马走的两个路线
if (chess.y + 1 < 10)
{
MaXiangGo(chess.x - 2, chess.y + 1, ref isGo, chess);
}
if (chess.y - 1 >= 0)
{
MaXiangGo(chess.x - 2, chess.y - 1, ref isGo, chess);
}
}
}
//向下摸索
if (chess.y + 2 < 10)
{
bool isGo = false;
MaXiangGo(chess.x, chess.y + 1, ref isGo, chess);
if (isGo)
{
if (chess.x + 1 < 9)
{
MaXiangGo(chess.x + 1, chess.y + 2, ref isGo, chess);
}
if (chess.x - 1 >= 0)
{
MaXiangGo(chess.x - 1, chess.y + 2, ref isGo, chess);
}
}
}
//向上摸索
if (chess.y - 2 >= 0)
{
bool isGo = false;
MaXiangGo(chess.x, chess.y - 1, ref isGo, chess);
if (isGo)
{
if (chess.x + 1 < 9)
{
MaXiangGo(chess.x + 1, chess.y - 2, ref isGo, chess);
}
if (chess.x - 1 >= 0)
{
MaXiangGo(chess.x - 1, chess.y - 2, ref isGo, chess);
}
}
}
}
//如果他是车
else if (chess.selfChessName == ChessName.Che)
{
//向右摸索前进
for (int i = 1; chess.x + i < 9; i++)
{
if (CheGo(chess.x + i, chess.y, chess))
{
break;
}
}
//向左摸索前进
for (int i = 1; chess.x - i >= 0; i++)
{
if (CheGo(chess.x - i, chess.y, chess))
{
break;
}
}
//向下摸索前进
for (int i = 1; chess.y + i < 10; i++)
{
if (CheGo(chess.x, chess.y + i, chess))
{
break;
}
}
//向上摸索前进
for (int i = 1; chess.y - i >= 0; i++)
{
if (CheGo(chess.x, chess.y - i, chess))
{
break;
}
}
}
//如果他是炮
else if (chess.selfChessName == ChessName.Pao)
{
//向右摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; chess.x + i < 9; i++)
{
if (PaoGo(chess.x + i, chess.y, ref fire, chess))
{
break;
}
}
}
//向左摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; chess.x - i >= 0; i++)
{
if (PaoGo(chess.x - i, chess.y, ref fire, chess))
{
break;
}
}
}
//向下摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; chess.y + i < 10; i++)
{
if (PaoGo(chess.x, chess.y + i, ref fire, chess))
{
break;
}
}
}
//向上摸索前进
{
bool fire = false;//是否开炮
for (int i = 1; chess.y - i >= 0; i++)
{
if (PaoGo(chess.x, chess.y - i, ref fire, chess))
{
break;
}
}
}
}
//如果他是兵
else if (chess.selfChessName == ChessName.Bing)
{
//控制兵是否能左右行走
bool around = false;
//如果这是楚河上方的兵
if (chess.distinguish == 1)
{
//向前摸索行走
if (chess.y + 1 < 10)
{
ShuaiShiBingGo(chess.x, chess.y + 1, chess);
}
//如果这个兵过了楚河
if (chess.y >= 5)
{
around = true;
}
}
//否则是楚河下方的兵
else
{
//向前摸索行走
if (chess.y - 1 >= 0)
{
ShuaiShiBingGo(chess.x, chess.y - 1, chess);
}
//如果这个兵过了楚河
if (chess.y <= 4)
{
around = true;
}
}
//这个兵是否能左右行走
if (around)
{
//向右摸索前进一格
if (chess.x + 1 < 9)
{
ShuaiShiBingGo(chess.x + 1, chess.y, chess);
}
//向左摸索前进一格
if (chess.x - 1 >= 0)
{
ShuaiShiBingGo(chess.x - 1, chess.y, chess);
}
}
}
}
//帅、士、兵的走法
private void ShuaiShiBingGo(int a, int b, Chess chess)
{
//如果棋盘上的(b,a)坐标为空
if (checkerboard[b, a] != null)
{
//如果该坐标上有棋子,且为敌方棋子
if (checkerboard[b, a].GetComponent<Chess>().selfTeam != chess.selfTeam)
{
if(checkerboard[b, a].GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
//绝杀bool值为true,意为:将军
isLonely = true;
//获取被将军的帅的颜色
lonelyObjectTeam = checkerboard[b, a].GetComponent<Chess>().selfTeam;
}
}
}
}
//车的走法
private bool CheGo(int a, int b, Chess chess)
{
//如果棋盘上的(b,a)坐标为空
if (checkerboard[b, a] != null)
{
//如果该坐标上有棋子,且为敌方棋子
if (checkerboard[b, a].GetComponent<Chess>().selfTeam != chess.selfTeam)
{
if (checkerboard[b, a].GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
//绝杀bool值为true,意为:将军
isLonely = true;
//获取被将军的帅的颜色
lonelyObjectTeam = checkerboard[b, a].GetComponent<Chess>().selfTeam;
}
}
//运行到此行,说明前方有我方棋子,因被我方棋子挡住,就不能前进
//返回true,让上面执行break退出for循环
return true;
}
//否则
else
{
//运行到此行,说明该点无棋子,可以行走,可以继续向前摸索
//返回false,让上面不执行break继续for循环
return false;
}
}
//炮的走法
private bool PaoGo(int a, int b, ref bool fire, Chess chess)
{
//如果棋盘上的(b,a)坐标为空
if (checkerboard[b, a] != null)
{
//如果fire为true,则表示进入开炮状态
if (fire)
{
//如果该坐标上有棋子,且为敌方棋子
if (checkerboard[b, a].GetComponent<Chess>().selfTeam != chess.selfTeam)
{
if (checkerboard[b, a].GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
//绝杀bool值为true,意为:将军
isLonely = true;
//获取被将军的帅的颜色
lonelyObjectTeam = checkerboard[b, a].GetComponent<Chess>().selfTeam;
}
}
//运行到此行,说明前方有我方棋子,因被我方棋子挡住,就不能前进
//返回true,让上面执行break退出for循环
return true;
}
//否则
else
{
//fire设为true,表示可以打炮
fire = true;
//运行到此行,说明刚刚开始隔棋打棋,虽然该点有棋子,但是要作为支点
//返回false,让上面不执行break,继续for循环
return false;
}
}
//否则
else
{
//运行到此行,说明该点无棋子,可以行走,可以继续向前摸索
//返回false,让上面不执行break,继续for循环
return false;
}
}
//马、象的走法
private void MaXiangGo(int a, int b, ref bool isGo, Chess chess)
{
//如果棋盘上的(b,a)坐标为空
if (checkerboard[b, a] != null)
{
//能否通行
if (isGo)
{
//如果该坐标上有棋子,且为敌方棋子
if (checkerboard[b, a].GetComponent<Chess>().selfTeam != chess.selfTeam)
{
if (checkerboard[b, a].GetComponent<Chess>().selfChessName == ChessName.Shuai)
{
//绝杀bool值为true,意为:将军
isLonely = true;
//获取被将军的帅的颜色
lonelyObjectTeam = checkerboard[b, a].GetComponent<Chess>().selfTeam;
}
}
}
}
//否则
else
{
//能否通行
if (!isGo)
{
isGo = true;
}
}
}
}
在这个象棋游戏里,绝杀我还没有写,就是输赢我没有写,这个以后会把它补上;
以上是单人模式的代码,但是由于没有电脑,所以我这个游戏是不完善的,原因是我现在还没有能力写出一个好的象棋AI,这是我在做游戏方面所欠缺的,