欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity3D开发实战之五子棋游戏

程序员文章站 2023-11-18 20:37:10
前言 经过前面《unity3d入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了unity3d的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文...

前言

经过前面《unity3d入门教程》系列讲解,再加上我们自己的探索,相信大家已经掌握了unity3d的相关知识和基本方法。本文将使用前面学到的知识,开发一款简单的五子棋程序。本文用到的东西其实不多,非常简单。在最后我们会把完整工程的源代码发布出来,以供初学者参考。先展示一下最后的运行效果吧。

Unity3D开发实战之五子棋游戏

1 准备工作

(1)开发环境:win10 + unity5.4.1

(2)图片素材准备:

黑棋子和白棋子

Unity3D开发实战之五子棋游戏Unity3D开发实战之五子棋游戏

棋盘

Unity3D开发实战之五子棋游戏

获胜提示图片

Unity3D开发实战之五子棋游戏

Unity3D开发实战之五子棋游戏

2 开发流程

上文提到的素材可以直接下载我们给出的这些图,也可以自己制作。注意黑白棋子要做成png格式,以保证显示的时候棋子四个角是透明的。将用到的图片素材导入到工程当中。新建一个场景,创建一个plane,作为maincamera的子物体。将棋盘贴图拖动到plane上,并且将plane正面面向摄像机。

Unity3D开发实战之五子棋游戏

再创建四个sphere,作为plane的子物体,分别命名为lefttop、righttop、leftbottom、rightbottom。然后把他们的meshrenderer勾选掉。这些球是为了计算棋子落点所设置的,所以需要把它们与棋盘的四个角点对准。

Unity3D开发实战之五子棋游戏

然后我们创建一个chess.cs脚本,绑定到maincamera上。脚本中包含了所有的功能。需要绑定的一些物体如图所示。

Unity3D开发实战之五子棋游戏

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;
 } 
}

运行效果截图:

Unity3D开发实战之五子棋游戏

Unity3D开发实战之五子棋游戏

小结

本程序实现了五子棋的基本功能,纯属娱乐而作。暂时没有加入各种ui、网络模块等。本程序经过了简单的测试,没有什么问题,如果大家在使用的时候发现有什么bug,请联系我改正,谢谢。

下面是工程源码下载地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。