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

下面是工程源码下载地址

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

(0)

相关推荐

  • Unity3D实现简易五子棋源码

    本文实例为大家分享了Unity3d简易五子棋源码,供大家参考,具体内容如下 Unity3d部分 对C#源码进行了改写简化: using UnityEngine; using System.Collections; public class chess : MonoBehaviour { //四个锚点位置,用于计算棋子落点 public GameObject LeftTop; public GameObject RightTop; public GameObject LeftBottom; pub

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

    前言 经过前面<Unity3D入门教程>系列讲解,再加上我们自己的探索,相信大家已经掌握了Unity3D的相关知识和基本方法.本文将使用前面学到的知识,开发一款简单的五子棋程序.本文用到的东西其实不多,非常简单.在最后我们会把完整工程的源代码发布出来,以供初学者参考.先展示一下最后的运行效果吧. 1 准备工作 (1)开发环境:Win10 + Unity5.4.1 (2)图片素材准备: 黑棋子和白棋子 棋盘 获胜提示图片 2 开发流程 上文提到的素材可以直接下载我们给出的这些图,也可以自己制作.

  • C#实现微信跳一跳小游戏的自动跳跃助手开发实战

    一.前言: 前段时间微信更新了新版本后,带来的一款H5小游戏"跳一跳"在各朋友圈里又火了起来,类似以前的"打飞机"游戏,这游戏玩法简单,但加上了积分排名功能后,却成了"装逼"的地方,于是很多人花钱花时间的刷积分抢排名.后来越来越多的聪明的"程序哥们"弄出了不同方式不同花样的跳一跳助手(外挂?),有用JS实现的.有JAVA实现的.有Python实现的,有直接物理模式的.有机械化的.有量尺子的等等,简直是百花齐放啊-- 赶一下潮流

  • Android开发实现的简单五子棋游戏示例

    本文实例讲述了Android开发实现的简单五子棋游戏.分享给大家供大家参考,具体如下: 我刚刚在Android上写的一个五子棋的小程序,在这里跟大家分享一下. 写完以后感觉Android的SDK,虽然也是使用Java的,但是跟Java ME还是有很大不一样. 首先就是Android的SDK没有实现所有的Java ME标准,原来运行在KJava上的应用程序是不能在Android上直接跑的. 另外就是Android的SDK有大量的API是Android自己的,需要开发人员去了解. Android的开

  • Pygame坦克大战游戏开发实战详解代码

    导语 哈喽!哈喽——我是木木子 今天来升级下之前写的坦克大战游戏嘛,哈哈哈 其实也不算是修改,就是稍微的调试一下!​​ 因为之前写的界面都是英文的 ,有的小伙伴儿英文一点儿都不会的可能看着别扭,今天来一款中 文版的给大家嘛! 俗话说的好:“雨露均沾”.哈哈哈.jpg 小简介: <坦克大战>,1985年由日本开发商南梦宫(Namco)开发,是第一款可以双打的红白机游戏. 当时使用的还是小霸王. 很多小朋友以学习的名义买了以后偷偷打的打游戏还被家长发现了有 没得! <坦克大战>红白机原

  • 微信小程序实战之双人五子棋游戏是实现

    目录 一.项目展示 二.项目核心代码 三.效果展示 一.项目展示 微信小程序项目实例——双人五子棋 双人五子棋是一款游戏小程序 两位选手可以在15x15的棋盘上 进行五子棋竞技 同时小程序设置了悔棋功能 二.项目核心代码 点击落子 step: function(event) { var pos=event.currentTarget.dataset.pos; wx.setStorageSync('vak', this.data.vak); if(this.data.vak[pos]=="whit

  • java开发实现五子棋游戏

    本文实例为大家分享了java实现五子棋游戏的具体代码,供大家参考,具体内容如下 此游戏具有双人对战功能和人机对战功能 一.游戏界面的实现 一个游戏首先从设计界面开始 1.首先创建一个类,作用是通过对窗体组件的一些设置来实现简单游戏界面 public void gameUI(){ //窗体组件 MyFrame jf = new MyFrame(); jf.setSize(900, 800); jf.setTitle("冷丁-五子棋"); //居中显示 jf.setLocationRela

  • HTML5开发Kinect体感游戏的实例应用

    HTML5开发Kinect体感游戏的实例应用 一.简介 我们要做的是怎样一款游戏? 在前不久成都TGC2016展会上,我们开发了一款<火影忍者手游>的体感游戏,主要模拟手游章节<九尾袭来 >,用户化身四代,与九尾进行对决,吸引了大量玩家参与. 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就是说,我们只需要掌握前端相应技术,就可以开发基于Kinect的网页体感游戏. 二.实现原理 实现思路是什么? 使用H5开发基于Kinect的体感游戏,其实工作

  • C++实现五子棋游戏

    三子棋.五子棋之类的游戏,非常简单,对于初学者来说是一个不错的练手的小项目,以前用C语言写过三子棋游戏.最近在看C++,所以就想到在三子棋的基础上利用C++语言实现五子棋游戏. 主要功能: 有3个模式:0表示退出.1表示电脑vs玩家.2表示玩家vs玩家. 当一局完成之后选择'y'则又会进入选择模式. 源代码(VS2013编译器下写的): #include<iostream> #include<stdio.h> #include<stdlib.h> #include &l

  • 微信小程序五子棋游戏AI实现方法【附demo源码下载】

    本文实例讲述了微信小程序五子棋游戏AI实现方法.分享给大家供大家参考,具体如下: DEMO下载 五子棋AI篇DEMO 效果图 原理 1. 将棋盘中能够胜利的五子连珠方法遍历一个数组: 2. 当AI持棋时,遍历棋盘中所有棋子的空位: 3. 如果用户落子该位置,给用户该位置的五连珠方式进行加分:1连10分,2连20分,3连40分,4连80分: 4. 如果AI落子该位置,给AI该位置的五连珠方式进行加分:1连15分,2连25分,3连45分,4连85分: 5. 最后对该位置的分值进行比较,取最大分值位置

  • 微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】

    本文实例讲述了微信小程序五子棋游戏的棋盘,重置,对弈实现方法.分享给大家供大家参考,具体如下: DEMO下载 五子棋对弈.悔棋DEMO 效果图 分析 1. 采用微信小程序的canvas制作五子棋: 2. 确定棋盘大小及格数: 3. 绘制棋盘--通过棋盘宽高和格数计算间距,同时保存坐标点: 4. 黑方和白方下子--定义一个布尔变量代表各自的身份: 5. 重置棋盘--重新开始: 6. 通过判断当前棋手,悔棋时进行改变. 绘制棋盘 drawLine(arr){ arr.forEach(current

随机推荐