推箱子大家都知道吧,在cocos2d上简单实现了一个!
typedef enum { None=-1, Wall=0, Worker, Box, Passageway, Destination, WorkerInDest, RedBox, } Map_State; //代表堆栈长度 #define MaxNum 300
这个枚举很重要, Wall:墙, Worke:工人,Box:箱子,Passageway:通道,Destination:目的地,WorkerInDest:工人在目的地,RedBox:箱子在目的地,游戏中会根据这些不同的类型,生成对应的精灵贴图,也就是说至少有7张图,我这里用Num1.png、Num2.png...Num7.png七张图来表示。游戏开始前我会有一个关卡的配置的plist,里面是一个一维数组:010101234567... 通过这个就可以进行初始化布局!
游戏初始化:
//游戏进入函数 -(void) show { CGSize size = [[CCDirector sharedDirector] winSize]; movableSprites = [[NSMutableArray alloc] init]; labelStep = [CCLabelBMFont labelWithString:@"0" fntFile:@"mine.fnt"]; labelStep.position = ccp( size.width -30 , size.height-15 ); [self addChild:labelStep]; //后退按钮 flagBt=[CCSprite spriteWithSpriteFrameName:@"btnFlaged.png"]; flagBt.position=ccp(40,70); [self addChild:flagBt z:1 tag:1000]; [movableSprites addObject:flagBt]; //向上按钮 upBt=[CCSprite spriteWithSpriteFrameName:@"up.png"]; upBt.position=ccp(230,90); [self addChild:upBt z:1 tag:1001]; [movableSprites addObject:upBt]; //向下按钮 downBt=[CCSprite spriteWithSpriteFrameName:@"down.png"]; downBt.position=ccp(230,30); [self addChild:downBt z:1 tag:1002]; [movableSprites addObject:downBt]; //向左按钮 leftBt=[CCSprite spriteWithSpriteFrameName:@"left.png"]; leftBt.position=ccp(180,60); [self addChild:leftBt z:1 tag:1003]; [movableSprites addObject:leftBt]; //向右按钮 rightBt=[CCSprite spriteWithSpriteFrameName:@"right.png"]; rightBt.position=ccp(280,60); [self addChild:rightBt z:1 tag:1004]; [movableSprites addObject:rightBt]; //初始化 [self intiGameConfig]; } //游戏初始化 -(void) intiGameConfig { W=30;//每个方块宽度 m_col=10;//方块矩阵列数 m_row=10;//方块矩阵行数 m_count=m_row*m_col;//方块矩阵方块总数 //栈顶 s_top=-1; stackStep=(int *)malloc(sizeof(int)*MaxNum);//保存走过的方向,1上2下3左4右 boxStatus=(int *)malloc(sizeof(int)*MaxNum);//保存行走时是否推了箱子 //初始化二维数组 myArrays=(int **)malloc(sizeof(int)*10); for (int i=0; i<10; i++) { myArrays[i]=(int *)malloc(sizeof(int)*10); } //读取关卡配置,一维数组:01010123456... NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"level3" ofType:@"plist"]; NSArray *Positions = [NSArray arrayWithContentsOfFile:plistPath]; int tx=0; int ty=0; int type=-1; for (int i=0; i<m_count; i++) { tx=i/m_col;//行 ty=i%m_col;//列 type=[[Positions objectAtIndex:i] intValue]; myArrays[tx][ty]=type;//保存方块类型 //方块精灵 CCSprite *p=[CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"Num%i.png",type]]; p.tag=i; //p.anchorPoint=ccp(0, 0); p.position=ccp(10+15+ty*W,130+15+tx*W); [movableSprites addObject:p]; [self addChild:p z:1]; //找着工人位置 if (type==Worker) { x=tx; y=ty; //tag=i=x*m_col+y; } } }
工人行走功能实现:
-(void) ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event { CGPoint touchlocation = [touch locationInView: [touch view]]; touchlocation =[[CCDirector sharedDirector] convertToGL:touchlocation]; CCSprite * newSprite = nil; if (newSprite == nil) { for (CCSprite *sprite in movableSprites) { if (CGRectContainsPoint(sprite.boundingBox, touchlocation)) { newSprite = sprite; break; } } } if (newSprite==nil) { CCLOG(@"NO CCSprite has beend touched!"); } else { int x_1; int y_1; int x_2; int y_2; int na = [newSprite tag]; //CCLOG(@"tounchTag:%i",na); switch (na) { case 1000: CCLOG(@"后退"); // [self GoBack]; break; case 1001: CCLOG(@"上"); x_1=x+1; y_1=y; x_2=x+2; y_2=y; [self MoveTo:1 x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 1002: CCLOG(@"下"); x_1=x-1; y_1=y; x_2=x-2; y_2=y; [self MoveTo:2 x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 1003: CCLOG(@"左"); x_1=x; y_1=y-1; x_2=x; y_2=y-2; [self MoveTo:3 x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 1004: CCLOG(@"右"); x_1=x; y_1=y+1; x_2=x; y_2=y+2; [self MoveTo:4 x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; default: break; } } } //换图 -(void) changeSpritePic:(int) xx yy:(int) yy type:(int) type { int tag=xx*m_col+yy; CCSprite *p=(CCSprite *)[self getChildByTag:tag]; CCSpriteFrame* hpframe = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"Num%i.png",type]]; [p setDisplayFrame:hpframe]; } //检测是否完成 -(BOOL) IsFinish { BOOL bFinish=YES; for (int i=0; i<m_col; i++) { for (int j=0; j<m_col; j++) { if (myArrays[i][j]==Destination||myArrays[i][j]==WorkerInDest) { bFinish=NO; break; } } } return bFinish; } -(void) MoveMan:(int)xx yy:(int)yy { if (myArrays[xx][yy]==Worker) { //如果是通路 myArrays[xx][yy]=Passageway; [self changeSpritePic:xx yy:yy type:Passageway]; } else if(myArrays[xx][yy]==WorkerInDest) { myArrays[xx][yy]=Destination; [self changeSpritePic:xx yy:yy type:Destination]; } } //是否在方块矩阵内 -(BOOL) IsInGameArea:(int)row col:(int)col { return (row>=0&&row<m_row&&col>=0&&col<m_col); } -(void) MoveTo:(int)path x1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 { Map_State P1,P2; P1=P2=None; if ([self IsInGameArea:x1 col:y1]) { P1=myArrays[x1][y1]; } if ([self IsInGameArea:x2 col:y2]) { P2=myArrays[x2][y2]; } //前面是通道 if (P1==Passageway) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=Worker; [self changeSpritePic:x1 yy:y1 type:Worker]; [self inStack:path box:0]; } //前面是目的地 if (P1==Destination) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=WorkerInDest; [self changeSpritePic:x1 yy:y1 type:WorkerInDest]; [self inStack:path box:0]; } //前面是墙 if (P1==Wall||![self IsInGameArea:x1 col:y1]) { return; } //前面是箱子 if (P1==Box) { if (P2==Wall||![self IsInGameArea:x2 col:y2]||P2==Box) { return; } } //前面是箱子,前面的前面是路 if (P1==Box && P2==Passageway) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=Worker; myArrays[x2][y2]=Box; [self changeSpritePic:x1 yy:y1 type:Worker]; [self changeSpritePic:x2 yy:y2 type:Box]; [self inStack:path box:1]; } //前面是箱子,前面的前面是目的地 if (P1==Box && P2==Destination) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=Worker; myArrays[x2][y2]=RedBox; [self changeSpritePic:x1 yy:y1 type:Worker]; [self changeSpritePic:x2 yy:y2 type:RedBox]; [self inStack:path box:1]; } //前面是目的地的箱子,前面的前面是路 if (P1==RedBox && P2==Passageway) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=WorkerInDest; myArrays[x2][y2]=Box; [self changeSpritePic:x1 yy:y1 type:WorkerInDest]; [self changeSpritePic:x2 yy:y2 type:Box]; [self inStack:path box:1]; } //前面是目的地的箱子,前面的前面是目的地 if (P1==RedBox && P2==Destination) { [self MoveMan:x yy:y]; x=x1; y=y1; myArrays[x1][y1]=WorkerInDest; myArrays[x2][y2]=RedBox; [self changeSpritePic:x1 yy:y1 type:WorkerInDest]; [self changeSpritePic:x2 yy:y2 type:RedBox]; [self inStack:path box:1]; } //判断是否完成 if ([self IsFinish]) { //显示完成界面 [self showWin]; } } //进栈 -(void) inStack:(int) path box:(int)box { if (s_top+1<MaxNum) { s_top++; [labelStep setString:[NSString stringWithFormat:@"%i",s_top+1]]; stackStep[s_top]=path; boxStatus[s_top]=box; } else { CCLOG(@"堆栈满了!"); } //[self printStack]; } //出栈 -(CGPoint) outStack { CGPoint temp; if (s_top==-1) { CCLOG(@"堆栈空了!"); temp.x=0; temp.y=0; } else { temp.x=stackStep[s_top]; temp.y=boxStatus[s_top]; s_top--; [labelStep setString:[NSString stringWithFormat:@"%i",s_top+1]]; } return temp; } -(void) showWin { winLayer *layer=[winLayer node]; [layer showWinLayer]; [self addChild:layer z:2]; }
后退功能实现:
//后退函数 -(void) GoBack { //后退专用 int x_1;//人的前面(箱子) int y_1; int x_2;//人的后面 int y_2; CGPoint p=[self outStack]; int na=p.x; if (na==0) { return ; } switch (na) { case 1: CCLOG(@"下"); // x_1=x+1; y_1=y; x_2=x-1; y_2=y; [self MoveBack:p.y x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 2: CCLOG(@"上"); // x_1=x-1; y_1=y; x_2=x+1; y_2=y; [self MoveBack:p.y x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 3: CCLOG(@"右"); // x_1=x; y_1=y-1; x_2=x; y_2=y+1; [self MoveBack:p.y x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; case 4: CCLOG(@"左"); // x_1=x; y_1=y+1; x_2=x; y_2=y-1; [self MoveBack:p.y x1:x_1 y1:y_1 x2:x_2 y2:y_2]; break; default: break; } } -(void) MoveBack:(int)box x1:(int)x1 y1:(int)y1 x2:(int)x2 y2:(int)y2 { Map_State P1,P2; P1=P2=None; //p1:前面,箱子,p2:后面 if ([self IsInGameArea:x1 col:y1]) { P1=myArrays[x1][y1]; } if ([self IsInGameArea:x2 col:y2]) { P2=myArrays[x2][y2]; } //后面是路 if (P2==Passageway) { // myArrays[x2][y2]=Worker; [self changeSpritePic:x2 yy:y2 type:Worker]; } //后面是目的地 if (P2==Destination) { // myArrays[x2][y2]=WorkerInDest; [self changeSpritePic:x2 yy:y2 type:WorkerInDest]; } [self MoveMan:x yy:y]; //前面是箱子并且当时走这一步时推了箱子 if (P1==Box&&box==1) { // if (myArrays[x][y]==Destination) { myArrays[x][y]=RedBox; [self changeSpritePic:x yy:y type:RedBox]; } if (myArrays[x][y]==Passageway) { myArrays[x][y]=Box; [self changeSpritePic:x yy:y type:Box]; } myArrays[x1][y1]=Passageway; [self changeSpritePic:x1 yy:y1 type:Passageway]; } //前面是目的地的箱子并且当时走这一步时推了箱子 if (P1==RedBox&&box==1) { // if (myArrays[x][y]==Destination) { myArrays[x][y]=RedBox; [self changeSpritePic:x yy:y type:RedBox]; } if (myArrays[x][y]==Passageway) { myArrays[x][y]=Box; [self changeSpritePic:x yy:y type:Box]; } myArrays[x1][y1]=Destination; [self changeSpritePic:x1 yy:y1 type:Destination]; } x=x2; y=y2; }
好了,就这么多,回头我会再贴一个,C#写的地图编辑器!欢迎交流!