推箱子大家都知道吧,在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#写的地图编辑器!欢迎交流!