一、概括
本文讲述用Egret配合Eui仿制一款之前的热门休闲游戏《围住神经猫》,这款游戏在当时1几年的时候挺火的,所以想着模仿下。
二、演示视频
三、开发过程
1.主界面
没什么ui交互,就一个开始游戏的触发。
2.场景加载
module ziyi{
export class pot2 extends basicui{
private allpot2_g:eui.Group;
public constructor(cd?: any) {
super();
}
private pots2:Array<Array<eui.Image>>;
//子类初始化操作
protected pre_init(): void {
this.pots2=new Array<Array<eui.Image>>();
for(let i:number=0;i<9;i++){
var tmp:Array<eui.Image>=new Array<eui.Image>();
this.pots2.push(tmp);
for(let j:number=0;j<9;j++){
var tmpgroup =<eui.Group> this.allpot2_g.getElementAt(i);
var tmpimg=<eui.Image>tmpgroup.getElementAt(j);
this.pots2[i].push(tmpimg);
this.pots2[i][j].visible=true;
this.pots2[i][j].touchEnabled=false;
}
}
}
public visibleSet(i:number,j:number):void{
this.pots2[i][j].visible=true;
}
public allVisibleSet():void{
for(let i:number=0;i<9;i++){
for(let j:number=0;j<9;j++){
this.pots2[i][j].visible=false;
}
}
}
public getpots2():Array<Array<eui.Image>>{
return this.pots2;
}
public getall():eui.Group{
return this.allpot2_g;
}
}
}
3.初始化场景
扫描二维码关注公众号,回复:
17217817 查看本文章
通过代码,添加好红灰两组二维组的格子,初始化红格子不可见。
private obstacles:Array<Array<number>>;
private init():void{
this.succeccText.text="";
this.succbtn.visible=false;
this.failbtn.visible=false;
this.pabtn.visible=false;
this.row=4;
this.col=4;
//this.loadTime();
this.timer.start(); //开始计时
for(let ii:number=0;ii<9;ii++){
for(let jj:number=0;jj<9;jj++){
this.p1[ii][jj].touchEnabled=true; //空格可按
this.p1[ii][jj].visible=true;
}
}
this.cat.visible=true;
this.obstacles=new Array<Array<number>>();
for(let i:number=0;i<9;i++){
var tmp:Array<number>=new Array<number>();
this.obstacles.push(tmp);
for(let j:number=0;j<9;j++){
this.obstacles[i].push(0);
}
}
//在中心点方圆3步内(相对于矩阵而非真实排列)随机设置五个障碍点
for(let i:number=0;i<5;i++){
var x:number=Math.ceil(Math.random()*3-1);
var y:number=Math.ceil(Math.random()*3-1);
if(x==0&&y==0){
i=i-1;
}else{
this.obstacles[4+x][4+y]=1;//障碍点设置之后更细障碍矩阵
this.p1[4+x][4+y].visible=false;//被设置障碍点的位置的灰色点不可视
}
}
//在图中随机选取8个位置设置障碍点
for(let i:number=0;i<8;i++){
var x:number=Math.ceil(Math.random()*9-1);
var y:number=Math.ceil(Math.random()*9-1);
if((x==4&&y==4)||this.obstacles[x][y]==1)
{
i=i-1;
}
else{
this.obstacles[x][y]=1;
this.p1[x][y].visible=false;
}
}
}
然后通过代码随机生成13个障碍点,并开启可视,将障碍点作为数据标识“1”存入obstacles二维数组中。
4.路径记录(最短路径算法)--核心代码
private initmap():void{//初始化map图,将边缘点设置为1,正常点设置为0,障碍点设置为-1
for(let i:number=0;i<9;i++){
for(let j:number=0;j<9;j++){
this.map[i][j]=0;
}
}
this.changeflag=0;
for(let i:number=0;i<9;i++){
for(let j:number=0;j<9;j++){
if(this.isObstacle[i][j]==1)
{
this.map[i][j]=-1;
}
}
}
for(let i:number=0;i<9;i++){
if(this.isObstacle[i][0]==0){
this.map[i][0]=1;
}
if(this.isObstacle[i][8]==0){
this.map[i][8]=1;
}
if(this.isObstacle[8][i]==0){
this.map[8][i]=1;
}
if(this.isObstacle[0][i]==0){
this.map[0][i]=1;
}
}
}
public setcolandrow(i:number,j:number){
this.row=i;
this.col=j;
}
private recurshort():void{//回溯进行map最短距离的更新
this.changeflag=0;
for(let i:number=1;i<8;i++){
for(let j:number=1;j<8;j++){
//上
if(this.map[i][j-1]>0&&(this.map[i][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i][j-1]+1;
}
//下
if(this.map[i][j+1]>0&&(this.map[i][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i][j+1]+1;
}
//左
if(this.map[i-1][j]>0&&(this.map[i-1][j]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i-1][j]+1;
}
//右
if(this.map[i+1][j]>0&&(this.map[i+1][j]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i+1][j]+1;
}
if(i%2==0){
//奇数行,左上(i-1,j-1)左下(i+1,j-1)
//左上
if(this.map[i-1][j-1]>0&&(this.map[i-1][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i-1][j-1]+1;
}
//左下
if(this.map[i+1][j-1]>0&&(this.map[i+1][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i+1][j-1]+1;
}
}else{
//偶数行,右上(i-1,j+1)右下(i+1,j+1)
//右上
if(this.map[i-1][j+1]>0&&(this.map[i-1][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i-1][j+1]+1;
}
//右下
if(this.map[i+1][j+1]>0&&(this.map[i+1][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
this.changeflag=1;
this.map[i][j]=this.map[i+1][j+1]+1;
}
}
}
}
if(this.changeflag==1)
{
//changeflag为1说明距离矩阵改变,需要回溯
this.recurshort();
}
}
private move():number{
//已经走在边界了,成功逃脱
if(this.row==0||this.row==8||this.col==0||this.col==8){
return -1;
}
var d1:number=this.map[this.row-1][this.col];//猫所处位置的上
var d2:number=this.map[this.row+1][this.col];//猫所处位置的下
var d3:number=this.map[this.row][this.col-1];//猫所处位置的左
var d4:number=this.map[this.row][this.col+1];//猫所处位置的右
if(this.row%2==0){
//奇数行,左上左下
var d5:number=this.map[this.row-1][this.col-1];//猫所处位置的左上
var d6:number=this.map[this.row+1][this.col-1];//猫所处位置的左下
}else{
//偶数行,右上右下
var d5:number=this.map[this.row-1][this.col+1];//猫所处位置的右上
var d6:number=this.map[this.row+1][this.col+1];//猫所处位置的右上
}
var min:number=Math.min(d1,Math.min(d2,Math.min(d3,Math.min(d4,Math.min(d5,d6)))));
var max:number=Math.max(d1,Math.max(d2,Math.max(d3,Math.max(d4,Math.max(d5,d6)))));
if(max==0){//max为0说明已经被困住但是还可以走
this.flag=true;
if(max==d1){
return 1;//上
}else if(max==d2){
return 2;//下
}else if(max==d3){
return 3;//左
}else if(max==d4){
return 4;//右
}else if(max==d5){
return 5;//左上或右上
}else if(max==d6){
return 6;//左下或右下
}
}else if(max==-1){//max为-1说明六个方向都是障碍,即成功围住
return 0;
}else if(min==1){//min为1说明猫已经走到了边缘,可以逃脱
return -1;
}
if(d1==-1){
d1=100;
}
if(d2==-1){
d2=100;
}
if(d3==-1){
d3=100;
}
if(d4==-1){
d4=100;
}
if(d5==-1){
d5=100;
}
if(d6==-1){
d6=100;
}
min=Math.min(d1,Math.min(d2,Math.min(d3,Math.min(d4,Math.min(d5,d6)))));
if(min==d1){
return 1;//上
}else if(min==d2){
return 2;//下
}else if(min==d3){
return 3;//左
}else if(min==d4){
return 4;//右
}else if(min==d5){
return 5;//左上或右上
}else if(min==d6){
return 6;//左下或右下
}
}
findpath()类用来计算存储路径数据的,首先将内部二维数组初始化为0,然后接收外部Main中的obstacles的障碍物标识,通过边缘1,障碍物-1,正常0的标识对obstacles二维数据存储,根据边缘数据求得往中心点的路径标识为2,3,4。在每次点击制造障碍物的时候进行更新,同时猫会根据自己附近最少的那个标识进行移动,一旦标识为0则证明没有路可以走,然后进行变猫(动画),一旦走到标识1的位置则证明游戏胜利。
反之,附近标识为-1的情况则失败
四、总结:
这款《围住疯狂猫》难度不难,主要运用到了最短路径的算法,然后就是灵活运用二维数组存储数据,依我来看,这个寻路算法还有缺陷。有待提高,或者可以设定它的随机概率。不然,很容易预判到猫的移动轨迹(那边近走那边)。。。