Unity3d制作一个简单粗暴的五子棋项目工程源码
Unity3d制作一个简单粗暴的五子棋
- 最终效果
- 项目源码
- 绘制棋盘
- 绘制构思
- 绘制代码
- 效果图
- 放置棋子
- 功能和效果
- 功能
- 效果
- 制作棋子
- 定义类和类型
- 棋子类型
- 棋盘格类
- 实现功能
- 初始棋盘格数据
- 创建棋子
- 实时同步棋子位置
- 放置棋子
- 结束判定
- 判定分析
- 结束判定实现
- 完善工程
- 新增UI
- 开始UI
- 结束UI
- 完善代码
- 点击函数
- 结束操作
- 总结
最终效果
效果是这样的gif动图展示
项目源码
先把源码贴这
https://download.csdn.net/download/qq_33789001/15743651
绘制棋盘
绘制构思
先定一个白色背景,然后盘由黑色的线绘制,
15*15的棋盘 就需要15条横着的线,和15条竖着的线构成。
预制两条横竖的线,那么这两条线的两边分别画7条线。
一个7次的for循环就搞定了。
还有五个点,这个就预制好改一下位置就完成。
绘制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class QiPanCreateor : MonoBehaviour
{public GameObject LineMH,LineMV;public GameObject Pnt1, Pnt2, Pnt3, Pnt4;float width = 40;void Start(){CreatorQiPan();}void CreatorQiPan() {Pnt1.transform.localPosition = new Vector3(-width * 4, -width * 4, 0);Pnt2.transform.localPosition = new Vector3(width * 4, -width * 4, 0);Pnt3.transform.localPosition = new Vector3(-width * 4, width * 4, 0);Pnt4.transform.localPosition = new Vector3(width * 4, width * 4, 0);for (int i = 0; i < 7; i++){GameObject H1 = GameObject.Instantiate<GameObject>(LineMH);GameObject H2 = GameObject.Instantiate<GameObject>(LineMH);GameObject V1 = GameObject.Instantiate<GameObject>(LineMV);GameObject V2 = GameObject.Instantiate<GameObject>(LineMV);H1.transform.SetParent(this.transform);H1.transform.localScale = Vector3.one;H1.transform.localPosition = new Vector3(0, width * (i + 1), 0);H2.transform.SetParent(this.transform);H2.transform.localScale = Vector3.one;H2.transform.localPosition = new Vector3(0, -width * (i + 1), 0);V1.transform.SetParent(this.transform);V1.transform.localScale = Vector3.one;V1.transform.localPosition = new Vector3(width * (i + 1), 0, 0);V2.transform.SetParent(this.transform);V2.transform.localScale = Vector3.one;V2.transform.localPosition = new Vector3(-width * (i + 1), 0, 0);}}
}
效果图
绘制的效果如下图:
今天就花这小点时间弄个棋盘,后续慢慢写!
放置棋子
功能和效果
功能
主要是实现一下这些功能:按下鼠标并移动,新棋子会跟随移动;松开鼠标,放置棋子;自动修正放置的位置在格子交叉处;不可在棋盘外和已放置的位置放置;黑白棋子交替放置。
效果
制作棋子
先预制两个棋子对象,用默认的Image组件,图片设置为内置的“Knob”。
定义类和类型
棋子类型
//定义棋子类型
public enum QiType {none = 0,white = 1, //白black = 2, //黑
}
这个就是简单明了,两种类型的棋子,黑白。
棋盘格类
这个类主要用于记录每个格子内的信息,便于后面进行格子相关的逻辑判断。
// 盘格类
public class QPGrid {public bool isPlace = false; //是否放置public QiType QiTp = QiType.none; //类型public Vector3 Pos; //位置 public GameObject Node = null; //对象节点
}
实现功能
初始棋盘格数据
void InitQiPanArray() {for (int i = 0; i < 15; i++)for (int j = 0; j < 15; j++) {QPGrid temp = new QPGrid();temp.Pos = new Vector3((i - 7) * width, (7 - j) * width, 0); //只用计算位置,其他默认QiPanArray[i, j] = temp; }
}
共有15*15个格子,我们对每个进行初始化,并赋值位置数据;位置数据通过格子大小计算出,用于放棋子位置修正。
创建棋子
//创建下一棋子void CreateNextQi() {if (NextQiType == QiType.white){GameObject go = GameObject.Instantiate<GameObject>(WhiteQi);go.transform.SetParent(WhiteQi.transform.parent);go.transform.localPosition = Vector3.zero;go.transform.localScale = Vector3.zero;NowQi = go;}else if (NextQiType == QiType.black){GameObject go = GameObject.Instantiate<GameObject>(BlackQi);go.transform.SetParent(BlackQi.transform.parent);go.transform.localPosition = Vector3.zero;go.transform.localScale = Vector3.zero;NowQi = go;}}
这个是通过复制之前预制的黑白棋对象实现,根据接下来的棋子类型来复制。
实时同步棋子位置
//同步当前棋子位置void SyncNowQiPos(float x,float y) {if (NowQi == null){CreateNextQi();}else{NowQi.transform.localScale = Vector3.one;NowQi.transform.localPosition = new Vector3(x, y, 0);}}
当鼠标按下并移动时,根据鼠标位置更新棋子的位置。
放置棋子
//尝试放置当前棋子void TryPlaceNowQi(float x, float y) {if ((x < 7.5f * width && x > -7.5f * width) && (y < 7.5f * width && y > -7.5f * width)){//在棋盘范围内int xidx = (int)Math.Round(x / width + 7, 0);int yidx = (int)Math.Round(7 - y / width, 0);if (!QiPanArray[xidx, yidx].isPlace){QiPanArray[xidx, yidx].isPlace = true;QiPanArray[xidx, yidx].QiTp = NextQiType;QiPanArray[xidx, yidx].Node = NowQi;NowQi.transform.localPosition = QiPanArray[xidx, yidx].Pos;if (NextQiType == QiType.white)NextQiType = QiType.black;elseNextQiType = QiType.white;NowQi = null;}else{NowQi.transform.localScale = Vector3.zero;}}else{NowQi.transform.localScale = Vector3.zero;}}
当鼠标松开时调用该函数,会根据鼠标位置设置放置位置,会有放置不成功的情况。
现在我们的游戏数据和操作功能有了,交替放黑白棋的功能也有了,接下来就是实现游戏结束的判断逻辑了。
结束判定
这输赢的判定就是率在八个方向的连续的五颗子即为赢。
判定分析
因为这的输赢判定简单,是最后落下的一颗棋子代表的一方有可能赢,就是最后落下的子能决定胜负,只用判定以它为中心关联的条线上的棋子是否构成五颗连续同颜色即可。
上图中四条不同颜色的线代表需要判定的方向,按这个思路,就是写几个for循环的事了。
结束判定实现
public bool CheckGameOver(int posx,int posy) {int count = 1; //连续棋子数//上下方向检测for (int i = posy + 1; i < 15; i++) {if (QiPanArray[posx, posy].QiTp == QiPanArray[posx, i].QiTp) {if (++count >= 5)return true;}elsebreak;}for (int i = posy - 1; i >= 0; i--) {if (QiPanArray[posx, posy].QiTp == QiPanArray[posx, i].QiTp){if (++count >= 5)return true;}elsebreak;}count = 1;//左右方向检测for (int i = posx + 1; i < 15; i++){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, posy].QiTp){if (++count >= 5)return true;}elsebreak;}for (int i = posx - 1; i >= 0; i--){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, posy].QiTp){if (++count >= 5)return true;}elsebreak;}count = 1;//右上方向检测for (int i = posx + 1, j = posy + 1; i < 15 && j < 15; i++,j++){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, j].QiTp){if (++count >= 5)return true;}elsebreak;}//左下方向检测for (int i = posx - 1, j = posy - 1; i >= 0 && j >= 0; i--,j--){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, j].QiTp){if (++count >= 5)return true;}elsebreak;}count = 1;//右下方向检测for (int i = posx + 1, j = posy - 1; i < 15 && j >= 0; i++, j--){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, j].QiTp){if (++count >= 5)return true;}elsebreak;}//左上方向检测for (int i = posx - 1, j = posy + 1; i >= 0 && j < 15; i--, j++){if (QiPanArray[posx, posy].QiTp == QiPanArray[i, j].QiTp){if (++count >= 5)return true;}elsebreak;}return false;}
这里的两个参数即int posx,int posy,是最后落下棋子所在的格子的下标。
完善工程
新增UI
这里新增的两个UI分别是开始UI和结束UI,都是自带的按钮组件和图片组件构成。
开始UI
结束UI
完善代码
这里主要实现几个按钮的点击功能,已经场景的切换。
点击函数
自己看代码吧:
//开始游戏public void Play(){StartPanel.SetActive(false);BackBtn.SetActive(true);isGaming = true;}//重新开始public void RePlay(){StartPanel.SetActive(false);OverPanel.SetActive(false);BackBtn.SetActive(true);for (int i = 0; i < 15; i++)for (int j = 0; j < 15; j++){QiPanArray[i, j].isPlace = false;QiPanArray[i, j].QiTp = QiType.none;if (QiPanArray[i, j].Node != null){Destroy(QiPanArray[i, j].Node);QiPanArray[i, j].Node = null;}}isGaming = true;}//返回大厅public void BackHall(){isGaming = false;StartPanel.SetActive(true);OverPanel.SetActive(false);for (int i = 0; i < 15; i++)for (int j = 0; j < 15; j++) {QiPanArray[i, j].isPlace = false;QiPanArray[i, j].QiTp = QiType.none;if (QiPanArray[i, j].Node != null) {Destroy(QiPanArray[i, j].Node);QiPanArray[i, j].Node = null;}}BackBtn.SetActive(false);}
结束操作
public void GameOver(){isGaming = false;OverPanel.SetActive(true);WinSide.text = NextQiType == QiType.white ? "白棋获胜!" : "黑棋获胜!";
}
总结
这个实现的比较快,不过只是实现了核心的玩法功能,其实可以延申开发的地方比较多,可以有兴趣写个人机对战的,还有平手的判定等这些都没有加。源码接近17KB,代码包含300多行,将就这看吧。
Unity3d制作一个简单粗暴的五子棋项目工程源码相关推荐
- Unity3d 制作一个简单的NPC对话系统
制作一个简单的NPC对话系统 文章目录 制作一个简单的NPC对话系统 前言 效果展示 进入对话区域 开始对话 Inspector面板可调选项 准备工作 NPC UI 代码 完整代码 详细逻辑 开启对话 ...
- Unity3d 实现节奏空间(Beat Saber)模型切割功能项目工程源码。
Unity3d 实现节奏空间(Beat Saber)核心玩法模型切割功能源码 前言 前言 之前公司的VR设备上安装了这个爆款音游,体验了几把后,感觉真的不错:加之现在很多短视频平台有各种玩游戏过程的合 ...
- Unity3D果汁店模拟经营完整项目工程源码
Fruit Juice Maker, Complete Time Management Game Kit Did you ever dream of owning and managing a sma ...
- 一个简单的Java计时器项目,附源码
学Java开发的小伙伴都会想着做一些项目来检验自己的学习成果,今天小千就来分享一个简单的Java计时器项目,源码也放在文中,大家可以参考一下. Java计时器项目 开发环境:win8+eclipse+ ...
- FPGA找工作写简历,你离高薪offer只差一个高端项目,提供工程源码和技术支持
这里写目录标题 1.前言 2.你或许很菜 3.工程源码 4.技术支持 5.工程源码和技术支持获取方式 1.前言 如果你是即将毕业的学生或是想转行做FPGA的工程师,你都会面临一个问题,那就是找工作,找 ...
- 【meng_项目】python+flask+html+css制作一个简单的生日祝福语网页
python+flask+html+css制作一个简单的生日祝福语网页 一个py文件: test.py 一个html文件: birthday_index.html 一张图片: ...
- 利用EasyDL制作一个简单的图片识别小项目
主要是利用EasyDL制作一个简单的傻瓜式猫狗图片识别,利用EasyDL,只需要几步简单的点击即可 *主要的步骤: 1.准备数据 2.训练模型 3.部署 4.H5 * 1.首先创建两个文件夹cat和d ...
- 使用 Flutter 制作一个简单的笑话生成器应用程序
在本教程中,我将向您展示如何使用 Flutter 制作一个简单的笑话生成器应用程序 对于这个项目,我们将从 RESTful API 获取数据 API的链接: 随机笑话 对于这个项目,我不会关注应用程序 ...
- 实例学习SSIS(一)--制作一个简单的ETL包
http://www.cnblogs.com/tenghoo/archive/2009/10/archive/2009/10/archive/2009/10/16/ssis_lookup.html 导 ...
最新文章
- 计算机演示题打不开,大神为你演示win7系统计算机上右键管理打不开的还原技巧...
- IOS UILabel组件
- django.template.exceptions.TemplateSyntaxError: ‘staticfiles‘ is not a registered tag library. Must
- rtk手簿Android代码,中海达rtk手机测量软件(Hi-Survey Road)
- tomcat宕机解决方法
- Apache架设代理服务器
- 基于Perclos&改进YOLOv7的疲劳驾驶DMS检测系统(源码&教程)
- promise.then链式调用顺序
- 盲人的福音:布里斯托大学团队让AI学会了键入盲文
- 惊世奇谈:乾隆生父不是雍正而是康熙?
- readline library not found
- MS-DOS系统的操作命令
- visio 画图记录
- 盘点春节营销刷屏的那些痛点指南!
- mssql数据库管理的简单介绍
- MATLAB中常用到的符号汇总(持续更新)
- setsockopt 设置socket
- 谷粒商城高级篇上(未完待续)
- Single Image Reflection Removal
- 小程聊微服务-数据抽取那点事(一)