unity3d游戏开发(一)——圈圈叉叉

参考:http://game.ceeger.com/forum/read.php?tid=1719

———————————————————开始————————————— 
好吧,吹了那么多我们开始吧,先发个最终截图 

 
当然,你觉得3个格子太少,你还可以扩展成任意格子的,只要你有足够的创意.... 
 
游戏是自娱自乐的  圈圈先下一步,然后叉叉下一步,圈圈再下一步..... 
———————————先来制作UI部分————————————————— 
  
我的游戏基本上用ngui作为ui层,我会在第一节课详细的讲一下ngui的操作,灰常详细的... 
以后我的教程都会忽略这部分的详细过程... 
我的教程中绝对不会出现一句系统自带的GUI东西,我都会用NGUI来代替它 
  
让我们打开一个全新的unity项目,然后删除掉主相机,导入ngui... 
接着NGUi菜单- > Create a New UI ->然后会出现一个这样的面板,点Create your UI 
 
—————————————————新手可跳过这部分—————————— 
我建议你们新建一个命名为2dLayer的层,然后设置成它,至于为什么这样做,是为了养成一个良好的习惯,为了以后3d和2d的东西混杂一起时,物理碰撞光线渲染什么的都可以简单的通过这个层,Default这个层在我看来是很危险的   因为你不知何时何地某个东西和它发生了关系.... 
顺便日西下我其他项目的层... 
 
——————————————————请继续—————————— 
  
这时候场景还是空空如也  不过我们的看到场景中多了一个由UI Root (2D)构成的树结构的东西 
 
然后我们最好先确定我们最终要导出的程序屏幕大小是多少,比如我的屏幕设置成了800*600 
那么我们先选择UI Root (2D)->然后在右边的属性面板中这样 
UIRoot这个脚本的Auto删掉勾,然后Manual Height设置成600... 
(注意Transform的Scale是自动设置的   你不用动它) 
 
然后选择Panel,然后Ngui菜单->Create a widget -> 出现了一个新面板 
这时候先不要着急, 先放到一边,点回资源文件夹中NGUI  Examples自带的SciFi 的 资源  SciFi Atlas 
 像这样   直接拖动SciFi Atlas 到新面板的Atlas中, Font 也是如此,将SciFi Font - Header 拖到新面板的Font中 
 
这样子,Template选择Label 
 
成功出现一个New Label的字样在屏幕上.... 
=,=这个Label用来给我们的游戏提示输赢信息..... 
—————— 
然后我们再一次这样子创建一个button....方法和上面几乎一样,这时Altas和Font应该不用再拖动了 
Template选择button, 
background选择Dark, 
在屏幕上出现了一个button了,然后选择button,删除掉UIButton offset 这个脚本(我可不想选什么的时候都乱动一下) 
菜单-> component -> NGUI -> interaction -> button message 的脚本 
 
请将button message 脚本的target设置为 UI Root(2d) 
然后 Function Name 设置为 ButtonPress   
这里这样设置是为了下面我们的程序来调用的.... 
将boxCollider 的 x 和 y  分别设置成40,这个东西很重要  因为我们鼠标点击的时候就靠这个... 
好了 到此我希望你还能跟得上我的节奏.... 
选择button,然后将它下面的子物体Label删去... 添加两个新的Sprite... 
添加方法和上面的一样:菜单 -> NGUI - > create a widget ... 
Template 选择 sprite 然后 
其中一个sprite选择 X ,  然后将名字改成Chacha 
另一个sprite选择 Button , 然后将名字改成Quan 
 
Chacha的Depth改成1,Scale 改成(25,25,1) 
Quan的Depth改成2,Scale 改成(40,40,1) 
SlicedSprite (Dark)的Depth改成0,Scale 改成(50,50,1) 
  
其中一个Chacha的截图 
 
大功告成 
到此为止,我们的UI/交互层 算是全部做好了.... 
  
  
—————————————————新手可跳过这部分—————————— 
我们在游戏制做过程中一定要规划好游戏的逻辑层次关系,比如我推崇最起码的三层游戏结构 
UI/交互层 <--> 逻辑层 <--> 数据层    这样的关系  各层之间留有一定的接口可以相互访问,绝对不要将所有的东西放在一起,这样会混乱得难以管理的
游戏越大型  这样的层次就越重要.... 
不过这个圈圈叉叉游戏还是用不到数据层了... 
  
  
—————————————————下面我们开始逻辑层的接口部分—————————— 
终于要开始写代码了   基动啊..... 
创建一个名为QuanQuan的c#脚本,然后付在UI Root (2D)上,我们目前整个游戏都靠这个脚本来管理 
首先我们想到的肯定是把这个Label和Button 作为2d的接入口传到脚本中 
    public GameObject gamePanel;   //将Panel这个物体拖到这里 
    public GameObject ShowLable;   //将Label这个物体拖到这里 
    public GameObject _Qizi;            //将Button这个物体拖到这里 
简单吧...然后我们定义棋盘的大小,我们先规定这个棋盘必须是n*n的-,-就是长和宽一样啦 
    public int number_N = 3;  //棋盘大小 
    public int TwohengWidth = 50; //两个棋子的距离 
最后如图:public的接口算是写好了.... 
(注 那个HengWidth属性在这个游戏中大家可无视....,还有number_N 请设置成3) 
———————————然后我们讨论下核心的判断部分———————————————— 
这种明显的方块格子的游戏,很多时候我们一眼就应该想到用 int[][] 这样的2维数组来存储和判断信息.... 
我们这里设置空的方块为0   叉叉的用-1表示     圈圈用1表示 
每下一步的时候,判断横边,竖边,斜边 每一边相加的结果是不是3或者是-3  这样子就可以判断输赢了 
比如一开始的状态 

0 , 0 , 0 
0 , 0 , 0 
0 , 0 , 0 

某种赢了的状态 

 0 ,   0 ,  0 
 1,    1 ,  1 
  -1 , -1 ,  0 

————————————游戏的状态机制———————————————— 
我们下棋的时候总是这样:我下完一步,然后到你下一步,一直到最终结束 
    enum GameState 
    { 
        MyAction, 
        AiAction, 
        GameOver, 
    } 
GameState gameState = GameState.MyAction; 
—————————————start()应该放什么————————————— 
首先算出一个左下角的原点OriginPoint,以方便我们排列整个棋盘 
然后根据棋盘的大小创建3*3个棋子(复制于_Qizi) 
                mQizi[i, j] = Instantiate(_Qizi) as GameObject; 
                mQizi[i, j].name = "qizi_"+i+"_"+j; //命名很重要  因为我们在button获取信息时就是通过name的不同来区分不同物体的 
                mQizi[i, j].transform.parent = _Qizi.transform.parent; //设置相同的父物体方便我们管理 
                mQizi[i, j].transform.localPosition = new Vector3(OriginPoint.x + (j) * TwohengWidth, OriginPoint.y + (i) * TwohengWidth, 0); 
                mQizi[i, j].transform.localScale = new Vector3(1, 1, 1); //父物体改变后我们应该重新设置scale 
               mQizi[i,j].transform.FindChild("Quan").GetComponent().enabled = false; 
               mQizi[i,j].transform.FindChild("Chacha").GetComponent().enabled = false; 
—————————————updata应该放什么——————————————— 
nothing , 这个简单的游戏机制导致我们不用设置“等待”和 “过渡” 这样的东西.... 
—————————————扩展学习部分——————— 
通常我们见到的简单的状态机都是类似这样的设置..   
void updata() 

   if (gameState == MyAction){} 
   else if(gameState == AiAction){} 
    else if(gameState==GameOver){} 

———————————button怎么交互——————————————— 
还记得池塘边的夏荷么  还记得上面的Button message 发送给ui root的fun 函数么 
我们对物体进行  y_x 这样的命名就是方便干这个的... 
void ButtonPress(GameObject o)  这个函数要通过GameObject o这样的参数得到它自身 
简单来说,我们点了button之后就sendmessage给这个函数了 
  
  
通过对button的名字的操作   可以得到物体所处的横竖坐标 
string[] _strArr = (o.name).Split(new char[]{'_'}); 
int _row = Convert.ToInt32(_strArr[1]); 
int _column = Convert.ToInt32(_strArr[2]); 
比如这个qizi_0_0就是表示左下角数起的0,0 这个棋子 
int数组中坐标排列方式 

(2,0),(2,1),(2,2) 
(1,0),(1,1),(1,2) 
(0,0),(0,1),(0,2) 

然后我们判断现在的游戏状态(也就是是谁在下) 
if (gameState == GameState.MyAction) 这样 
  
然后判断下的棋子是不是空格(只有空格子能下) 
if (isNullStep(BoxMatrix , _row, _column)) 
能下的空格子的话就改变BoxMatrix【】【】的值,改成1或者-1 
———————重要的逻辑判断——————— 
分为4大步骤: 
1先判断横列 
2判断数列 
3如果是斜边的话,判断斜边的列 
4如果TotleStep ==棋盘大小,则和局  游戏结束 
这里说得好简单   其实真正写起来这个好复杂.... 
—————————— 

完整代码:

using UnityEngine;
using System.Collections;
using System;/*** by:KuKu小夭* email:djy2130@qq.com*/public class QuanQuan : MonoBehaviour {public GameObject gamePanel;public GameObject ShowLable;public GameObject _Qizi;public int number_N = 3;//行列数public int TwohengWidth = 50;//两个横边之间的间隔private int BoxHeight;private int BoxWidth;private int[,] BoxMatrix;private Vector3 OriginPoint;//左下角原点的位置private int TotleStep = 0;//总共下的次数,如果次数等于棋盘的大小则和局private int _winTotle = 4; //几个子连一起为赢。enum GameState{MyAction,AiAction,GameOver,}GameState gameState = GameState.MyAction;void Start(){BoxHeight = number_N;BoxWidth = number_N;BoxMatrix = new int[BoxHeight, BoxWidth];//0 表示空,1表示圈,-1表示叉//创建一个和棋盘等数量的int数组OriginPoint = new Vector3(-(BoxWidth - 1) * 0.5f * TwohengWidth, -(BoxHeight - 1) * 0.5f * TwohengWidth, 0);/*if (number_N%2==0){OriginPoint = new Vector3(-(BoxWidth-1) * 0.5f * TwohengWidth, -(BoxHeight-1) * 0.5f * TwohengWidth, 0);}else{OriginPoint = new Vector3(-(BoxWidth-1) * 0.5f * TwohengWidth, -(BoxHeight-1) * 0.5f * TwohengWidth, 0);}*/ //最重要的部分GameObject[,] mQizi = new GameObject[BoxWidth,BoxHeight];for (int i = 0; i < BoxWidth; i++){for (int j = 0; j < BoxHeight; j++){BoxMatrix[i, j] = 0; mQizi[i, j] = Instantiate(_Qizi) as GameObject;mQizi[i, j].name = "qizi_"+i+"_"+j; //命名很重要  因为我们在button获取信息时就是通过name的不同来区分不同物体的mQizi[i, j].transform.parent = _Qizi.transform.parent;mQizi[i, j].transform.localPosition = new Vector3(OriginPoint.x + (j) * TwohengWidth, OriginPoint.y + (i) * TwohengWidth, 0);mQizi[i, j].transform.localScale = new Vector3(1, 1, 1);}}_Qizi.transform.localPosition = new Vector3(-1000, 0, 0);//这个东西移到屏幕外//Destroy(_Qizi);
    }//动作void ButtonPress(GameObject o){if (gameState == GameState.MyAction){string[] _strArr = (o.name).Split(new char[]{'_'});int _row = Convert.ToInt32(_strArr[1]);int _column = Convert.ToInt32(_strArr[2]);//Debug.Log(_row + "," + _column);if (isNullStep(BoxMatrix , _row, _column)){BoxMatrix[_row, _column] = 1;o.transform.FindChild("Quan").GetComponent<UISprite>().enabled = true;bool isGameover = Logic(BoxMatrix, _row, _column);if (isGameover) { gameState = GameState.GameOver; }else{  gameState = GameState.AiAction;}}}else if (gameState == GameState.AiAction){string[] _strArr = (o.name).Split(new char[] { '_' });int _row = Convert.ToInt32(_strArr[1]);int _column = Convert.ToInt32(_strArr[2]);//Debug.Log(_row + "," + _column);if (isNullStep(BoxMatrix , _row, _column)){BoxMatrix[_row, _column] = -1;o.transform.FindChild("Chacha").GetComponent<UISprite>().enabled = true;bool isGameover = Logic(BoxMatrix, _row, _column);if (isGameover) { gameState = GameState.GameOver; }else { gameState = GameState.MyAction; }}}}bool isNullStep(int[,] _Matrix, int row, int column){if (_Matrix[row, column] == 0){return true;}return false;}bool Logic(int[,] _Matrix,int row, int column){//check rowint _totle =0 ; for(int i=0; i < number_N;i++){_totle += _Matrix[i,column];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}//check column_totle = 0;for(int i=0; i < number_N;i++){_totle += _Matrix[row,i];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}////check left xie 这里只判断最长的斜对角线//if(row ==column){//    _totle = 0;//    for (int i = 0; i < number_N; i++)//    {//        _totle += _Matrix[i, i];//    }//    if (_totle == number_N)//    {//        Winner(1); return true;//    }//    else if (_totle == -1 * number_N)//    {//        Winner(2); return true;//    }//}////check right xie  这里只判断对角线//if(row == number_N - 1 - column)//{//    _totle = 0;//    for (int i = 0; i < number_N; i++)//    {//        _totle += _Matrix[i, number_N - i-1];//    }//    if (_totle == number_N)//    {//        Winner(1); return true;//    }//    else if (_totle == -1 * number_N)//    {//        Winner(2); return true;//    }//}int iCount = row + column;//check left xie_totle = 0;//把棋盘分成两部分,沿对角线分if (iCount < number_N)      //在对角线下部分,必定有[x,0]
        {for (int j = 0; j < iCount + 1; j++){_totle += _Matrix[iCount - j, j];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}}else    //在对角线上,必定有[8,x]
        {int i = 2 * (number_N - 1) - iCount;for (int j = number_N - 1, k = number_N - 1 - i; j >= number_N - 1 - i; j--, k++){_totle += _Matrix[j, k];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}}//check right xie_totle = 0;if (column >= row) //对角线下方
        {        int i = number_N - (column - row);for (int j = 0; j < i; j++){_totle += _Matrix[j, j + column - row];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}}else    //对角线上方
        {int i = number_N + (column - row);for (int j = 0; j < i; j++){_totle += _Matrix[j - column + row, j];}if (_totle == _winTotle){Winner(1); return true;}else if (_totle == -1 * _winTotle){Winner(2); return true;}}//检查是不是和局TotleStep++;if (TotleStep == BoxHeight * BoxWidth){Winner(3);return true;}return false;}void Winner(int player){if (player==1){ShowLable.GetComponent<UILabel>().enabled = true;ShowLable.GetComponent<UILabel>().text = "winner 1";}else if (player == 2){ShowLable.GetComponent<UILabel>().enabled = true;ShowLable.GetComponent<UILabel>().text = "winner 2";}else{ShowLable.GetComponent<UILabel>().enabled = true;ShowLable.GetComponent<UILabel>().text = "no winner";}}
}

 

 

项目下载地址:http://pan.ceeger.com/viewfile.php?file_id=1823&file_key=0KzsoygG

转载于:https://www.cnblogs.com/martianzone/p/3368392.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/493759.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯张正友:攻克可进化机器人,6个研究趋势与7大技术突破点

来源&#xff1a;腾讯AI实验室11月2日&#xff0c;机器人及多媒体技术专家、腾讯Robotics X实验室主任张正友博士&#xff0c;在2018年腾讯全球合作伙伴大会的人工智能分论坛上&#xff0c;展示了腾讯在机器人领域的思考。包括&#xff1a;腾讯将人工智能&#xff08;AI&#x…

摩拜开锁方式

摩拜作为共享单车中发展得比较好的一个&#xff0c;最近又因为被美团收购和抛弃同龄人的文章上了新闻&#xff0c;我们从技术上看&#xff0c;它的解锁时候的通信方式是怎样的呢&#xff1f; 注意到摩拜的一款车车筐里面装了太阳能电池&#xff0c;所以能源问题容易解释。我们先…

前沿地带:从量子计算到量子互联网

来源&#xff1a;资本实验室当我们进入互联网时代&#xff0c;科技进步和社会发展就建立在了数据与计算能力的基础之上。庞大的数据量与快速的计算能力这两大基本因素决定着我们进入未来社会的速度&#xff0c;而在当前的各种新技术中&#xff0c;量子计算无疑是最具未来感的新…

千万级负载均衡架构设计

负载均衡 &#xff08;Load Balancing&#xff09; 负载均衡建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 大型网站负载均衡的利器 全局负载均衡系统&#xf…

科学为什么重要?马化腾公开信引热议,透露企业未来发展方向

来源&#xff1a;世界科技创新论坛摘要&#xff1a;美国强大的源泉&#xff0c;不是因为它有原子弹&#xff0c;航空母舰&#xff0c;隐性飞机&#xff0c;或者芯片&#xff0c;而在于它牢牢地掌握着基础科学的最前沿。科学一点都马虎不得&#xff0c;没有捷径可走&#xff0c;…

吴恩达斯坦福大学机器学习 CS229 课程学习笔记(二)

终于要开始正式的学习了。看了第一节课最大的印象是Ng老师的优雅&#xff0c;儒雅&#xff0c;偏英式的发音&#xff08;突然意识到他从小在伦敦长大&#xff09;。配着字幕看的视频&#xff0c;但还是希望能锻炼一下自己的听力&#xff0c;也只有在自己看过一遍印象才深刻&…

当自动驾驶汽车撞过来的时候,你希望它如何判断?

来源&#xff1a;网易智能 摘要&#xff1a;据报道&#xff0c;当无人驾驶汽车在繁忙的街道上发生碰撞的时候&#xff0c;它该优先避免让谁受伤呢&#xff1f;它该杀死谁&#xff0c;而不杀死谁呢&#xff1f;麻省理工学院的一项研究表明&#xff0c;你的回答将取决于你来自哪里…

细数黑客攻击的七大战术

不计其数的黑客们游荡在因特网中来欺骗那些容易上当的用户。它们多年使用着重复的攻击手段&#xff0c;毫无创新地利用着我们懒惰、误判和一些犯二的行为。 不过每年&#xff0c;恶意软件研究人员总会遇到一些引人侧目的攻击手段。这些攻击手段在不断拓展恶意攻击的范围。新的攻…

人工智能黑暗面

来源&#xff1a;大数据文摘编译&#xff1a;DonFJ、蒋宝尚机器学习是现在大家都打了鸡血想用或者在用的技术。但是&#xff0c;你以为只有好人能用它吗&#xff1f;Too young too simple&#xff01;接下来&#xff0c;我将揭秘AI技术黑暗的一面——犯罪份子和人工智能的孽缘。…

认识蚁群算法

好像是看罗胖的罗辑思维&#xff0c;看到过一种说法&#xff0c;越是准入门槛高的&#xff0c;难以取代的行业&#xff0c;所需的工具是越简单的。摄影师需要昂贵的镜头&#xff0c;而画家却只需要简单的纸笔&#xff0c;尽管照片比画逼真得多&#xff0c;但是却无法取代绘画的…

薛定谔的猫跳进了生物学界,化学家表示:没有我可能办不到

来源&#xff1a;原理摘要&#xff1a;在生物科学界流传着“物理学家累了就来生物界玩一玩”的调侃。确实&#xff0c;现今学科之间密不可分&#xff0c;生物学的发展对特定物理技术的需求也越大。但是这样化学家却不满意了&#xff1f;1943年&#xff0c;物理学家薛定谔在都柏…

图像配准之特征点匹配的思考

最近赶时髦&#xff0c;看了一些智能优化算法如蚁群算法&#xff0c;还有机器学习的一些东西&#xff0c;就想着怎么把这些先进的东西用在图像配准中。头脑风暴了一下&#xff0c;觉得在已经检测到两幅图像的特征点的基础上&#xff0c;就如何对它们进行匹配似乎有优化的空间。…

指针%p输出的一些认识

还是看源码发现的问题 static int import_lowe_features( char*filename, struct feature** features ) 这个函数的作用是将txt文件中的Lowe的特征点导入到feature结构体中。在这个函数中第二个参数是指向结构体的指针的指针。 f calloc( n, sizeof(struct feature) );//在内存…

全球智慧医疗产业发展现状

来源&#xff1a;无锡情报所摘要&#xff1a;全球智慧医疗市场主要集中在美国、欧洲、日本和中国,而产品生产主要集中在美国、欧洲和日本。 随着大数据、云计算、物联网和人工智能技术快速发展和普及&#xff0c;运用互联网应用平台提升医疗资源的使用效率、提高救治和服务水平…

2018AI和机器学习界的12个重大收购案

来源&#xff1a;网络大数据据IDC声称&#xff0c;到2018年&#xff0c;全球人工智能(AI)和认知系统支出将达到190亿美元&#xff0c;这比2017年的支出总额增加约54%。并购在不断发生。仅2017年就见证了几起大宗收购&#xff0c;比如雅虎被Verizon收购、苹果收购Shazam等。知名…

PCA对特征点描述子降维

降维在机器学习领域其实是很重要的一部分&#xff0c;因为在高维情形下回出现样本稀疏&#xff0c;计算距离、内积困难&#xff0c;是所有机器学习面临的共同问题&#xff0c;被称为维数灾难&#xff08;Curse of dimensionality&#xff09;&#xff0c;而降维就是解决的一个办…

C语言基础知识整理

一、 关于sizeof和strlen。Sizeof&#xff08;&#xff09;用于计算某类型或者某变量在内存中所占空间。比如整数分为short型&#xff0c;int型&#xff0c;long整型&#xff0c;分别占2,2/4,4个字节&#xff0c;int型具体占用几个字节和编译系统有关。我们输入字符串时通常用c…

【2017-2019】Gartner战略技术趋势一览

来源&#xff1a;学术plus 、装备参考近期&#xff0c;Gartner公布了2019年十大战略技术趋势的预测&#xff0c;值此之际&#xff0c;本文总结回顾并简要分析了2017-2019三年的战略趋势变化。Gartner副总裁兼研究员David Cearley指出&#xff1a;在智能、数字、网格三大领域下的…

目标检测必看——RCNN是怎样融合了分类与回归,CNN与SVM

人和动物的区别之一是人能使用工具&#xff0c;而在人开始使用磨制石器时人类进入新石器时代。在目标检测领域&#xff0c;也有一个划时代的算法&#xff0c;在它之后目标检测开始进入深度学习的时代——它就是今天的主角&#xff1a;R-CNN。在RCNN之后&#xff0c;出现了更多优…

《自然》杂志:面对“电车难题”,不同国家的人有不同的道德选择

来源&#xff1a;36Kr电车难题原本只是一个思想实验。但是无人车的发展却绕不开这个问题。因为机器在无论如何都会撞死人的情况下必须靠预先植入的道德代码做出判断&#xff1a;该牺牲谁&#xff0c;该保谁。但是一项有全球230万人参与的调查表明&#xff1a;这个问题并不存在普…