Unity3D开发实战之五子棋游戏

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,请联系我改正,谢谢。

下面是工程源码下载地址

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

激活谷谷主为您准备了激活教程,为节约您的时间请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/5286.html

(0)
上一篇 2024年 3月 8日
下一篇 2024年 3月 8日

相关推荐

  • 串口助手发送文件数据格式错误_串口助手发送文件数据格式错误怎么办

    串口助手发送文件数据格式错误_串口助手发送文件数据格式错误怎么办友善串口调试助手如何设置发送格式化-设置发送格式化方法      很多人不知道友善串口调试助手如何设置发送格式化?今日为你们带来的文章是友善串口调试助手设置发送格式化的方法,还有不清楚小伙伴和小编一起去学习一下吧。 &nbs

    2024年 6月 2日
  • linux设置环境变量的命令

    linux设置环境变量的命令在嵌入式开发中,小伙伴经常为配置开发环境头疼,比如我们最常见的交叉编译环境arm-linux-gcc工具链的搭建。我们经常会碰到命令无法找到,无法识别的错误提示。究其原因,其实大多数都是因为我们环境变量没有配置好而已。为了让大家更轻松

    激活谷笔记 2024年 5月 19日
  • 分区表坏了无法开机_分区表坏了无法开机怎么办

    分区表坏了无法开机_分区表坏了无法开机怎么办Linux运维工程师面试题整理1.Nginx反向代理,负载均衡,动静分离,工作原理及优化nginx配置反向代理。vim Nginx.confServer模块中配置Listen 80Server_name ip;在server段里面的location加上proxy_pass http://ip

    2024年 5月 26日
  • linux命令vim

    linux命令vim专注于Java领域优质技术,欢迎关注作者:vimtutor 来自:Vim教程网Vim的很多命令和功能与Linux系统的命令和功能及其相似,可以说是一脉相承。Vim教程网(https://vimjc.com)总结了10条Linux下提高效率的小技巧,并与Vim对应命令进行对比。(1) &lt

    激活谷笔记 2024年 5月 19日
  • socket 网络编程

    socket 网络编程socket编程什么是socket?简称套接字,是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多数是基于socket来完成通信的。socket是基于C/S架构的,

    激活谷笔记 2024年 5月 18日
  • player软件怎么使用_player使用方法

    player软件怎么使用_player使用方法Potplayer详细教程:入门使用&进阶操作技巧指南最近几年推荐potplayer的人一直不少。Potplayer主要优点是功能强大,可以播放大多数音频视频文件,CDDVD文件,并可以观看直播等。同时界面比较简洁,如

    2024年 5月 31日
  • cpu压力测试命令是什么_cpu压力测试命令是什么意思

    cpu压力测试命令是什么_cpu压力测试命令是什么意思给CPU进行压力测试-stress  在Linux环境中对CPU进行压力测试,主要是为了测试系统的CPU负载能力和稳定性,可以使用多种工具和命令来进行测试。本文主要介绍两种常用的CPU压力测试命

    2024年 5月 29日
  • jcf期刊录用周期

    jcf期刊录用周期计算机科学类SCI&EI【期刊简介】IF:5.5-6.0,JCR1/2区,中科院2区【检索情况】SCI&EI 双检(CCF-C类)【征稿领域】边缘计算、算法与机器学习的结合研究录用案例:3个月14天录用,录用后30天见刊,见刊后11天检索2023.08.

    激活谷笔记 2024年 5月 19日
  • fastreport中文详细教程

    fastreport中文详细教程Fast Reports, Inc.成立于1998年,多年来一直致力于开发快速报表软件:应用程序、库和插件。FastReport的报表生成器(无论VCL平台还是.NET平台),跨平台的多语言脚本引擎FastScript,桌面OLAP Fa

    激活谷笔记 2024年 5月 18日
  • 分析二叉排序树查找性能的最好情况和最坏情况_二叉排序树什么情况下查找效率最低

    分析二叉排序树查找性能的最好情况和最坏情况_二叉排序树什么情况下查找效率最低红黑树与普通的平衡二叉树除了颜色到底有什么区别?为什么要引入红黑树,它比普通的平衡二叉树究竟好在哪?类似问题:红黑树比 AVL 树具体更高效在哪里?一、摘要二叉树,作为一种数据结构,在实际开发中,有着非常广泛的应用,尤其是以平衡二叉树、红黑树为代表,在前几篇文章中,我们

    2024年 5月 25日
  • 半导体存储器分成两大类,其中_半导体存储器分成两大类,其中不包括

    半导体存储器分成两大类,其中_半导体存储器分成两大类,其中不包括第7章 半导体存储器一、学习辅导【1-1】内容提要及重点1)本章的内容提要1.半导体存储器的分类(1)按数据易失性与非易失性分为两大类:ROM只读存储器(read only memory)RAM随机存取存储器(Random

    2024年 5月 22日
  • IDEA激活2024.1.1(Jrebel 最新的 2023.4 、 2024.1 激活方法)

    IDEA激活2024.1.1(Jrebel 最新的 2023.4 、 2024.1 激活方法)

    激活谷笔记 2024年 6月 7日
关注微信