Unity3D开发实战之五子棋游戏
前言
经过前面《unity3d入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了unity3d的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。先展示一下最后的运行效果吧。
1 准备工作
(1)开发环境:win10 + unity5.4.1
(2)图片素材准备:
黑棋子和白棋子
棋盘
获胜提示图片
2 开发流程
上文提到的素材可以直接下载我们给出的这些图,也可以自己制作。注意黑白棋子要做成png格式,以保证显示的时候棋子四个角是透明的。将用到的图片素材导入到工程当中。新建一个场景,创建一个plane,作为maincamera的子物体。将棋盘贴图拖动到plane上,并且将plane正面面向摄像机。
再创建四个sphere,作为plane的子物体,分别命名为lefttop、righttop、leftbottom、rightbottom。然后把他们的meshrenderer勾选掉。这些球是为了计算棋子落点所设置的,所以需要把它们与棋盘的四个角点对准。
然后我们创建一个chess.cs脚本,绑定到maincamera上。脚本中包含了所有的功能。需要绑定的一些物体如图所示。
chess.cs脚本如下:
using unityengine; using system.collections; public class chess : monobehaviour { //四个锚点位置,用于计算棋子落点 public gameobject lefttop; public gameobject righttop; public gameobject leftbottom; public gameobject rightbottom; //主摄像机 public camera cam; //锚点在屏幕上的映射位置 vector3 ltpos; vector3 rtpos; vector3 lbpos; vector3 rbpos; vector3 pointpos;//当前点选的位置 float gridwidth =1; //棋盘网格宽度 float gridheight=1; //棋盘网格高度 float mingriddis; //网格宽和高中较小的一个 vector2[,] chesspos; //存储棋盘上所有可以落子的位置 int[,] chessstate; //存储棋盘位置上的落子状态 enum turn {black, white } ; turn chessturn; //落子顺序 public texture2d white; //白棋子 public texture2d black; //黑棋子 public texture2d blackwin; //白子获胜提示图 public texture2d whitewin; //黑子获胜提示图 int winner = 0; //获胜方,1为黑子,-1为白子 bool isplaying = true; //是否处于对弈状态 void start () { chesspos = new vector2[15, 15]; chessstate =new int[15,15]; chessturn = turn.black; } void update () { //计算锚点位置 ltpos = cam.worldtoscreenpoint(lefttop.transform.position); rtpos = cam.worldtoscreenpoint(righttop.transform.position); lbpos = cam.worldtoscreenpoint(leftbottom.transform.position); rbpos = cam.worldtoscreenpoint(rightbottom.transform.position); //计算网格宽度 gridwidth = (rtpos.x - ltpos.x) / 14; gridheight = (ltpos.y - lbpos.y) / 14; mingriddis = gridwidth < gridheight ? gridwidth : gridheight; //计算落子点位置 for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { chesspos[i, j] = new vector2(lbpos.x + gridwidth * i, lbpos.y + gridheight * j); } } //检测鼠标输入并确定落子状态 if (isplaying && input.getmousebuttondown(0)) { pointpos = input.mouseposition; for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { //找到最接近鼠标点击位置的落子点,如果空则落子 if (dis(pointpos, chesspos[i, j]) < mingriddis / 2 && chessstate[i,j]==0) { //根据下棋顺序确定落子颜色 chessstate[i, j] = chessturn == turn.black ? 1 : -1; //落子成功,更换下棋顺序 chessturn = chessturn == turn.black ? turn.white : turn.black; } } } //调用判断函数,确定是否有获胜方 int re = result(); if (re == 1) { debug.log("黑棋胜"); winner = 1; isplaying = false; } else if(re==-1) { debug.log("白棋胜"); winner = -1; isplaying = false; } } //按下空格重新开始游戏 if (input.getkeydown(keycode.space)) { for (int i = 0; i < 15; i++) { for (int j = 0; j < 15; j++) { chessstate[i, j] = 0; } } isplaying = true; chessturn = turn.black; winner = 0; } } //计算平面距离函数 float dis(vector3 mpos, vector2 gridpos) { return mathf.sqrt(mathf.pow(mpos.x - gridpos.x, 2)+ mathf.pow(mpos.y - gridpos.y, 2)); } void ongui() { //绘制棋子 for(int i=0;i<15;i++) { for (int j = 0; j < 15; j++) { if (chessstate[i, j] == 1) { gui.drawtexture(new rect(chesspos[i,j].x-gridwidth/2, screen.height-chesspos[i,j].y-gridheight/2, gridwidth,gridheight),black); } if (chessstate[i, j] == -1) { gui.drawtexture(new rect(chesspos[i, j].x - gridwidth / 2, screen.height - chesspos[i, j].y - gridheight / 2, gridwidth, gridheight), white); } } } //根据获胜状态,弹出相应的胜利图片 if (winner == 1) gui.drawtexture(new rect(screen.width * 0.25f, screen.height * 0.25f, screen.width * 0.5f, screen.height * 0.25f), blackwin); if (winner == -1) gui.drawtexture(new rect(screen.width * 0.25f, screen.height * 0.25f, screen.width * 0.5f, screen.height * 0.25f), whitewin); } //检测是够获胜的函数,不含黑棋禁手检测 int result() { int flag = 0; //如果当前该白棋落子,标定黑棋刚刚下完一步,此时应该判断黑棋是否获胜 if(chessturn == turn.white) { for (int i = 0; i < 11; i++) { for (int j = 0; j < 15; j++) { if (j < 4) { //横向 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1) { flag = 1; return flag; } //纵向 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1) { flag = 1; return flag; } //右斜线 if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1) { flag = 1; return flag; } //左斜线 //if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1) //{ // flag = 1; // return flag; //} } else if (j >= 4 && j < 11) { //横向 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1) { flag = 1; return flag; } //纵向 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1) { flag = 1; return flag; } //右斜线 if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1) { flag = 1; return flag; } //左斜线 if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1) { flag = 1; return flag; } } else { //横向 //if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1) //{ // flag = 1; // return flag; //} //纵向 if (chessstate[i, j] == 1 && chessstate[i + 1, j] == 1 && chessstate[i + 2, j] == 1 && chessstate[i + 3, j] == 1 && chessstate[i + 4, j] == 1) { flag = 1; return flag; } //右斜线 //if (chessstate[i, j] == 1 && chessstate[i + 1, j + 1] == 1 && chessstate[i + 2, j + 2] == 1 && chessstate[i + 3, j + 3] == 1 && chessstate[i + 4, j + 4] == 1) //{ // flag = 1; // return flag; //} //左斜线 if (chessstate[i, j] == 1 && chessstate[i + 1, j - 1] == 1 && chessstate[i + 2, j - 2] == 1 && chessstate[i + 3, j - 3] == 1 && chessstate[i + 4, j - 4] == 1) { flag = 1; return flag; } } } } for (int i = 11; i < 15; i++) { for (int j = 0; j < 11; j++) { //只需要判断横向 if (chessstate[i, j] == 1 && chessstate[i, j + 1] == 1 && chessstate[i, j + 2] == 1 && chessstate[i, j + 3] == 1 && chessstate[i, j + 4] == 1) { flag = 1; return flag; } } } } //如果当前该黑棋落子,标定白棋刚刚下完一步,此时应该判断白棋是否获胜 else if(chessturn == turn.black) { for (int i = 0; i < 11; i++) { for (int j = 0; j < 15; j++) { if (j < 4) { //横向 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1) { flag = -1; return flag; } //纵向 if (chessstate[i, j] == -1 && chessstate[i + 1, j] == -1 && chessstate[i + 2, j] == -1 && chessstate[i + 3, j] == -1 && chessstate[i + 4, j] == -1) { flag = -1; return flag; } //右斜线 if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1) { flag = -1; return flag; } //左斜线 //if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1) //{ // flag = -1; // return flag; //} } else if (j >= 4 && j < 11) { //横向 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] ==- 1) { flag = -1; return flag; } //纵向 if (chessstate[i, j] == -1 && chessstate[i + 1, j] == -1 && chessstate[i + 2, j] == -1 && chessstate[i + 3, j] == -1 && chessstate[i + 4, j] == -1) { flag = -1; return flag; } //右斜线 if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1) { flag = -1; return flag; } //左斜线 if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1) { flag = -1; return flag; } } else { //横向 //if (chessstate[i, j] == -1 && chessstate[i, j + 1] ==- 1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1) //{ // flag = -1; // return flag; //} //纵向 if (chessstate[i, j] == -1 && chessstate[i + 1, j] ==- 1 && chessstate[i + 2, j] ==- 1 && chessstate[i + 3, j] ==- 1 && chessstate[i + 4, j] == -1) { flag = -1; return flag; } //右斜线 //if (chessstate[i, j] == -1 && chessstate[i + 1, j + 1] == -1 && chessstate[i + 2, j + 2] == -1 && chessstate[i + 3, j + 3] == -1 && chessstate[i + 4, j + 4] == -1) //{ // flag = -1; // return flag; //} //左斜线 if (chessstate[i, j] == -1 && chessstate[i + 1, j - 1] == -1 && chessstate[i + 2, j - 2] == -1 && chessstate[i + 3, j - 3] == -1 && chessstate[i + 4, j - 4] == -1) { flag = -1; return flag; } } } } for (int i = 11; i < 15; i++) { for (int j = 0; j < 11; j++) { //只需要判断横向 if (chessstate[i, j] == -1 && chessstate[i, j + 1] == -1 && chessstate[i, j + 2] == -1 && chessstate[i, j + 3] == -1 && chessstate[i, j + 4] == -1) { flag = -1; return flag; } } } } return flag; } }
运行效果截图:
小结
本程序实现了五子棋的基本功能,纯属娱乐而作。暂时没有加入各种ui、网络模块等。本程序经过了简单的测试,没有什么问题,如果大家在使用的时候发现有什么bug,请联系我改正,谢谢。
下面是工程源码下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Unity实现简易日志输出功能