unity3D学习之Nerve Sister工程文件.docx
《unity3D学习之Nerve Sister工程文件.docx》由会员分享,可在线阅读,更多相关《unity3D学习之Nerve Sister工程文件.docx(6页珍藏版)》请在冰豆网上搜索。

unity3D学习之NerveSister工程文件
神经猫这个游戏是前天才玩了玩,反正我一次都没围住它,看着那些点点不知道为什么一下就想起了数据结构里那些树的遍历,折腾了几下,感觉像是用贪心算法寻求每一步的最佳路径,这样的方法虽然往往不能求出最优的解,但也是近似最优,所以那只神经猫显然是一只十分聪明的猫~
好吧,其实这是在给自己找台阶下….进入正题,这次我们来看看如何实现神经猫,鉴于站长妹纸一直萌萌的状态,我决定把神经猫换成我们萌No萌Eat哒Pill站长大人,还是照旧,素材和工程文件放在文尾。
依旧是Native2D 工作流程,这次抠出来的素材资源显然有点不干净,自动Slice后再手动的调整裁剪下,不用重命名。
第一步:
搭建场景
把背景Sprite和开始及文字Sprite拖拽到场景里,并在背景上添加GameManger脚本,开始Sprite上添加GameStart脚本及碰撞器,置于开始按钮处。
拖拽出灰色的圆圈,添加上Spot脚本及碰撞器组件调整好大小,然后做成预制。
选中序列帧,创建站长萌哒哒动画,这里需要对动画的序列帧顺序做修改,按照素材里从左到右的顺序,在Animation视窗中直接把对应的序列帧拖到选定的位置上即可。
然后创建一个SpotEnum枚举,用于记录当前Spot的状态 文章来自【狗刨学习网】
GameStart脚本里检测鼠标单击事件,当点击后,调用父对象里CreateGame方法
[code]csharpcode:
publicenumSpotState{
UnClick=0,Clicked,OnSis
}
[code]csharpcode:
publicclassGameStart:
MonoBehaviour{
voidOnMouseDown()
{
SendMessageUpwards("CreateSpots");//创建圆圈背景
gameObject.SetActive(false);//
}
}
在CreateGame方法里,我们创建9行9列的灰色圆圈,,先看下GameManager类的公开字段
[code]csharpcode:
//预制引用
publicGameObjectspotPrefab;
publicGameObjectplayerPrefab;
publicGameObject[]gameOver;
//圆圈数字及位置信息
GameObject[,]spotList=newGameObject[9,9];
privateVector2beginVector2=newVector2(-2.3f,3.36f);
privateVector3playerOffset=newVector2(0,.4f);
privateGameObject_player;//萌哒站长的引用
privateGameObjectSpots;//圆圈的父对像
int_currentX=4;//当前萌哒站长所在圆圈的索引号
int_currentY=4;//当前萌哒站长所在圆圈的索引号对每个偶数行我们都需要将正行向左稍微移动一些距离,代码如下
[code]csharpcode:
voidCreateSpots()
{
Spots=newGameObject("Spots");//圆圈的父对象
Vector2_lineVector2=beginVector2;//每一行的起始坐标
//创建圆圈
for(inty=0;y<9;y++)
{
//对奇偶行的赋值
_lineVector2=y%2==0
?
newVector2(beginVector2.x,beginVector2.y-.6f*y)
:
newVector2(beginVector2.x-.3f,beginVector2.y-.6f*y);
for(intx=0;x<9;x++)
{
Vector2tempVector2=newVector2(_lineVector2.x+.6f*x,_lineVector2.y);
spotList[x,y]=Instantiate(spotPrefab,tempVector2,Quaternion.identity)asGameObject;
spotList[x,y].transform.parent=Spots.transform;
}
}
//初始创建萌哒妹纸
_player=Instantiate(playerPrefab,spotList[4,4].transform.position+playerOffset,Quaternion.identity)asGameObject;
spotList[4,4].GetComponent()._state=SpotState.OnSis;
_currentX=4;
_currentY=4;
//随机产生已经点击的圆圈
RandomClicked();
}如上代码所示,生成好81个小点后,我们实例化一个站长萌哒哒,将她y方向上的位置做一个调整,随机生成点击的圆圈和上一篇2048的初始操作类似
[code]csharpcode:
privatevoidRandomClicked()
{
inttimes=Random.Range(4,11);
intcnt=0;
while(cnt{
intx=Random.Range(0,9);
inty=Random.Range(0,9);
if(spotList[x,y].GetComponent()._state==SpotState.UnClick&&!
(x==4&&y==4))
{
spotList[x,y].GetComponent().SetClicked();
cnt++;
}
}接下来在Spot脚本中完成圆圈对鼠标点击事件的响应。
[code]csharpcode:
publicclassSpot:
MonoBehaviour
{
publicSpotState_state=SpotState.UnClick;
voidOnMouseDown()
{
if(_state==SpotState.UnClick)
{
SetClicked();//点击之后改变颜色和状态
FindObjectOfType().FindWay();//萌哒站长开始移动
}
}
publicvoidSetClicked()
{
GetComponent().material.color=newColor(249/255.0f,102/255.0f,57/255.0f);
_state=SpotState.Clicked;
}
}
每次点击后,都会在GameManeger脚本中对我们站长萌哒哒进行一个移动的操作,移动操作主要分为两个内容,第一块是在其周围六个方向寻找改路线上是否有已经Clicked的圆圈,
如果没有,那么就朝这个方向移动。
如果有,则向下个方向再作此查找操作
如果六个方向都有被Clicked的圆圈,那么就找被点击下的点离自己最远d那个方向移动,实现代码如下(以左上方向为例,具体步骤见代码注释):
[code]csharpcode:
//赋予当前萌哒站长所在圆圈的索引号
intx=_currentX;
inty=_currentY;
int[]MoveDirs=newint[6];//保留每个方向上与Clicked点的距离
#regionLeftUp
//找方向.左上
boolisFound=true;//设置查找标识符
while(isFound)
{
//边界检测,根据方向不一样
if(y<0||x<0)
{
break;
}
//当找到一个已经点击了的圆圈,保存其距离,并跳出循环
if(spotList[x,y].GetComponent()._state==SpotState.Clicked)
{
MoveDirs[(int)Move.LEFT_UP]=_currentY-y-1;
isFound=false;【08.06】注意:
此处break;}
//如果没跳出,按照该方向继续寻对下一个圆圈做判断
//!
每个方向这里的操作各不一样,根据移动的行号作判断
x=y%2==1?
x-1:
x;
y--;
}
//如果该方向上没有找到已经单击了圆圈,则直接移动萌哒站长
if(isFound)
{
MovePlayer(Move.LEFT_UP);
return;
}
#endregion其它五个方向基本逻辑完全一致,可以看工程文件,这里不再赘述。
接下来是没有方向畅通的情况下,通过对距离的对比,移动萌哒站长:
[code]csharpcode:
#regionChooseByDistance
//挑选最大的距离
intDirIndex=0,maxDis=0;
for(inti=0;i{
if(MoveDirs[i]>maxDis)
{
maxDis=MoveDirs[i];
DirIndex=i;
}
}
//朝这个方向移动
if(maxDis>0)
{
MovePlayer((Move)DirIndex);
}
//如果无法移动,则游戏结束
else
{
Instantiate(gameOver[1],transform.position,Quaternion.identity);
}
#endregion
接下来是MovePlayer实现,请看代码注释:
[code]csharpcode:
privatevoidMovePlayer(Moveindex)
{
//边界检测,判断萌哒妹纸是否逃脱
if(_currentX==0||_currentY==0||_currentX==8||_currentY==8)
{
Instantiate(gameOver[0],transform.position,Quaternion.identity);
return;
}
//标记萌哒站长站的圆圈为Unclick
spotList[_currentX,_currentY].GetComponent()._state=SpotState.UnClick;
//根据方向做移动
switch(index)
{
caseMove.LEFT_UP:
//根据方向更改萌哒站长的索引号
_currentX=_currentY%2==1?
_currentX-1:
_currentX;
_currentY--;
//更新位置及数据
_player.transform.position=spotList[_currentX,_currentY].transform.position+playerOffset;
spotList[_currentX,_currentY].GetComponent()._state=SpotState.OnSis;
break;
//.................省略做到这一步,基本的功能已经全部实现,接下来在Sprite里拖拽公告板,添加GameOver的脚本,里面是对鼠标点击事件的检测,调用GameManager里Reset方法重置游戏状态,代码如下:
[code]csharpcode:
publicclassGameOver:
MonoBehaviour{
voidOnMouseDown()
{
FindObjectOfType().Reset();
Destroy(gameObject);
}
}
[code]csharpcode:
publicvoidReset()
{
transform.GetChild(0).gameObject.SetActive(true);
Destroy(_player);
Destroy(Spots);
}
最后上一张游戏运行图