您的位置:首页 > 移动开发 > Cocos引擎

cocos2d 加载地图总结

2012-02-28 16:21 197 查看
刚刚完成“伞公主”的制作,其中背景地图的加载是一个很有难度的工作。为了完成这项任务我做了大量的工作,不能说非常全面至少应该有一些有用的经验,所以想总结下来,以备后用。特别是背景的移动
加载地图的方法:
1
。精灵+CCParallaxNode 具体参考:http://www.cnblogs.com/andyque/archive/2011/06/09/2074962.html

第一步建立ccpareallaxnode
在。h文件里面
CCParallaxNode *_backgroundNode;

在。m文件里面
// 1) Create the CCParallaxNode

_backgroundNode = [CCParallaxNode node];

[self addChild:_backgroundNode z:-1];
_planetsunrise = [CCSprite spriteWithFile:@"bg_planetsunrise.png"];

_galaxy = [CCSprite spriteWithFile:@"bg_galaxy.png"];

_spacialanomaly = [CCSprite spriteWithFile:@"bg_spacialanomaly.png"];

_spacialanomaly2 = [CCSprite spriteWithFile:@"bg_spacialanomaly2.png"];

第二步 声明背景精灵对象 比如:
// 2) Create the sprites we'll add to the CCParallaxNode

_spacedust1 = [CCSprite spriteWithFile:@"bg_front_spacedust.png"];

_spacedust2 = [CCSprite spriteWithFile:@"bg_front_spacedust.png"];
第三步 定义精灵相对的移动速度。
// 3) Determine relative movement speeds for space dust and background

CGPoint dustSpeed = ccp(0.1, 0.1);

CGPoint bgSpeed = ccp(0.05, 0.05);

第四步 将精灵对象加入到ccparallaxnode中
// 4) Add children to CCParallaxNode

[_backgroundNode addChild:_spacedust1 z:0 parallaxRatio:dustSpeed positionOffset:ccp(0,winSize.height/2)];

[_backgroundNode addChild:_spacedust2 z:0 parallaxRatio:dustSpeed positionOffset:ccp(_spacedust1.contentSize.width,winSize.height/2)];

[_backgroundNode addChild:_galaxy z:-1 parallaxRatio:bgSpeed positionOffset:ccp(0,winSize.height *0.7)];

[_backgroundNode addChild:_planetsunrise z:-1 parallaxRatio:bgSpeed positionOffset:ccp(600,winSize.height *0)];

[_backgroundNode addChild:_spacialanomaly z:-1 parallaxRatio:bgSpeed positionOffset:ccp(900,winSize.height *0.3)];

[_backgroundNode addChild:_spacialanomaly2 z:-1 parallaxRatio:bgSpeed positionOffset:ccp(1500,winSize.height *0.9)];

第五步 让背景移动 。
如果背景移动是在update方法中添加的,那么在init方法里面添加 [self scheduleUpdate]; 如果背景移动在其他的方法中实现,例如在update
background中实现,那么需要在init方法中添加
[self schedule:@selector(updatebackground:) interval:0.01];//处理背景移动
在update或者updatebackground中添加如下的语句
CGPoint backgroundScrollVel = ccp(-1000, 0);

_backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
注意:可以使用多个parraxnode,使用方法相似。
第六步 背景连续滚动。
具体解决办法在子龙山人的博客里面这里不再赘述,http://www.cnblogs.com/andyque/archive/2011/06/09/2074962.html

2 使用titlemap加载背景,具体参考:http://www.cnblogs.com/andyque/archive/2011/04/11/2012852.html。这种方法适合制作那些有固定大小的地图,而且地图是使用很多小的元素重复来组成的,例如坦克大战等游戏。
第一步下载tile地图编译器 再网上搜一些下载的连接,我当时使用的是java版的
java版的功能比较全面,地图在win7下创建,然后copy到mac下添加到项目中,其他的都跟子龙山人的教程上的相似。
第二步 建立地图。使用tile地图编译器可以创建多层次的背景地图,使用多个小元素地图可以创建一个很大的地图。
注意:地图的每一个图层必须只能使用一个元素图片,如果使用多个会在编译的时候报错。
第三步 将tile添加到cocos2d场景中
在。h文件中声明成员变量// Inside the HelloWorld class declaration

CCTMXTiledMap *_tileMap;

CCTMXLayer *_background;

// After the class declaration

@property (nonatomic, retain) CCTMXTiledMap *tileMap;

@property (nonatomic, retain) CCTMXLayer *background;
在。m文件中做如下的修改
// Right after the implementation section

@synthesize tileMap = _tileMap;

@synthesize background = _background;

// In dealloc

self.tileMap = nil;

self.background = nil;

// Replace the init method with the following

-(id) init

{

if( (self=[super init] )) {

self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"TileMap.tmx"];

self.background = [_tileMap layerNamed:@"Background"];

[self addChild:_tileMap z:-1];

}

return self;

}
将tmx文件添加到项目资源中。
第四步让tilemap背景地图移动起来
tilemap对象的使用类似于ccparallaxnode的使用,只是在update或者update background中添加的语句不同。
只不过不需要设置相对的移动速度,tilemap直接作为一个带有背景精灵的parallaxnode使用。
tilemap对象也可以使用多个并行使用。
第五步 tilemap循环移动。
tilemap对象本身不是用来做循环移动背景的最好的办法,它适合用来做加载式的固定的背景,但是由于tilemap内部有很好的内存回收机制,我在这里也使用了tilemap来制作循环的移动背景。提了tilemap对象的循环移动使用的是逻辑的方法,即在update里面判断一幅地图结束的位置,然后在这一个时刻重新加载一幅地图,判断的方式是利用tilemap对象的position的大小。(这个办法比较笨)

3使用ccparallaxnode和tilemap混合的方法来加载地图。由于我游戏中的地图是多层次,元素图片很多且没有规律,背景要求循环,等的很多要求,只有综合使用这两种方法,以能够快捷有效的加载背景地图。
使用的方法就是将tilemap对象作为ccparallaxnode的子对象加到里面然后移动ccparallaxnode并判断是否需要更新来重复加载背景。

第一步,声明tilemap对象和ccparallaxnode对象,并将tilemap对象添加到ccparallaxnode中,为了添加层次我声明了两个ccparallaxnode对象,封装在一个initbackground函数里面。
backgroundNode=[CCParallaxNode node];
backgroundNode1=[CCParallaxNode node];

_tileMapNode11 = [CCTMXTiledMap tiledMapWithTMXFile:@"title11.tmx"];
_tileMapNode21 = [CCTMXTiledMap tiledMapWithTMXFile:@"title21.tmx"];
_tileMapNode31 = [CCTMXTiledMap tiledMapWithTMXFile:@"title31.tmx"];
_tileMapNode41 = [CCTMXTiledMap tiledMapWithTMXFile:@"title41.tmx"];
_tileMapNode51 = [CCTMXTiledMap tiledMapWithTMXFile:@"title51.tmx"];

[self addChild:backgroundNode];
[self addChild:backgroundNode1 z:24];

//背景移动的更新 liulun gai 速度为2:3:4
CGPoint backgroundScrollVel1 = ccp(1,1);
CGPoint backgroundScrollVel2 = ccp(1.5,1.5);
CGPoint backgroundScrollVel3 = ccp(2,2);

[ backgroundNode addChild:_tileMapNode11 z:0 parallaxRatio:backgroundScrollVel1 positionOffset:ccp(0,0)];
[ backgroundNode addChild:_tileMapNode21 z:1 parallaxRatio:backgroundScrollVel2 positionOffset:ccp(0,0)];
[ backgroundNode addChild:_tileMapNode31 z:2 parallaxRatio:backgroundScrollVel3 positionOffset:ccp(0,0)];
[ backgroundNode addChild:_tileMapNode41 z:3 parallaxRatio:backgroundScrollVel3 positionOffset:ccp(0,0)];
[ backgroundNode1 addChild:_tileMapNode51 z:1 parallaxRatio:backgroundScrollVel3 positionOffset:ccp(0,0)];

这里面隐含了制作和添加tilemap对象的过程,具体可以参考子龙山人的博客 http://www.cnblogs.com/andyque/archive/2011/04/11/2012852.html 第二步 由于需要无限循环因此需要判断什么时候加载新的地图,根据每个tilemap的长度决定具体参数的大小。

// //判断游戏是又过了一个循环 直接换背景

if(backgroundNode.position.x <= -(2688*mapnum-480)){

[self addScrollingBackgroundWithTileMap];

}
第三步 实现更新地图的函数 addScrollingBackgroundWithTileMap在这里进行地图的重新加载以能显示接下来要出现的地图。使用一个参数来进行分类确定。
CGPoint backgroundScrollVel1 = ccp(1,1);
CGPoint backgroundScrollVel2 = ccp(1.5,1.5);
CGPoint backgroundScrollVel3 = ccp(2,2);
mapnum++;
//CCLOG(@"---------------------%d",mapnum);
switch (mapnum%4) {

case 1:
_tileMapNode11 = [CCTMXTiledMap tiledMapWithTMXFile:@"title11.tmx"];
_tileMapNode21 = [CCTMXTiledMap tiledMapWithTMXFile:@"title21.tmx"];
_tileMapNode31 = [CCTMXTiledMap tiledMapWithTMXFile:@"title31.tmx"];
_tileMapNode41 = [CCTMXTiledMap tiledMapWithTMXFile:@"title41.tmx"];
_tileMapNode51 = [CCTMXTiledMap tiledMapWithTMXFile:@"title51.tmx"];

[ backgroundNode addChild:_tileMapNode11 z:0 parallaxRatio:backgroundScrollVel1 positionOffset:ccp((mapnum-1)*2688,0)];
[ backgroundNode addChild:_tileMapNode21 z:1 parallaxRatio:backgroundScrollVel2 positionOffset:ccp((mapnum-1)*4032,0)];
[ backgroundNode addChild:_tileMapNode31 z:2 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode addChild:_tileMapNode41 z:3 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode1 addChild:_tileMapNode51 z:1 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];

break;

case 2:
_tileMapNode12 = [CCTMXTiledMap tiledMapWithTMXFile:@"title12.tmx"];
_tileMapNode22 = [CCTMXTiledMap tiledMapWithTMXFile:@"title22.tmx"];
_tileMapNode32 = [CCTMXTiledMap tiledMapWithTMXFile:@"title32.tmx"];
_tileMapNode42 = [CCTMXTiledMap tiledMapWithTMXFile:@"title42.tmx"];
_tileMapNode52 = [CCTMXTiledMap tiledMapWithTMXFile:@"title52.tmx"];

[ backgroundNode addChild:_tileMapNode12 z:0 parallaxRatio:backgroundScrollVel1 positionOffset:ccp((mapnum-1)*2688,0)];
[ backgroundNode addChild:_tileMapNode22 z:1 parallaxRatio:backgroundScrollVel2 positionOffset:ccp((mapnum-1)*4032,0)];
[ backgroundNode addChild:_tileMapNode32 z:2 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode addChild:_tileMapNode42 z:3 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode1 addChild:_tileMapNode52 z:1 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];

break;

case 3:
_tileMapNode13 = [CCTMXTiledMap tiledMapWithTMXFile:@"title13.tmx"];
_tileMapNode23 = [CCTMXTiledMap tiledMapWithTMXFile:@"title23.tmx"];
_tileMapNode33 = [CCTMXTiledMap tiledMapWithTMXFile:@"title33.tmx"];
_tileMapNode43 = [CCTMXTiledMap tiledMapWithTMXFile:@"title43.tmx"];
_tileMapNode53 = [CCTMXTiledMap tiledMapWithTMXFile:@"title53.tmx"];

[ backgroundNode addChild:_tileMapNode13 z:0 parallaxRatio:backgroundScrollVel1 positionOffset:ccp((mapnum-1)*2688,0)];
[ backgroundNode addChild:_tileMapNode23 z:1 parallaxRatio:backgroundScrollVel2 positionOffset:ccp((mapnum-1)*4032,0)];
[ backgroundNode addChild:_tileMapNode33 z:2 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode addChild:_tileMapNode43 z:3 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode1 addChild:_tileMapNode53 z:1 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];

break;

case 0:
_tileMapNode14 = [CCTMXTiledMap tiledMapWithTMXFile:@"title14.tmx"];
_tileMapNode24 = [CCTMXTiledMap tiledMapWithTMXFile:@"title24.tmx"];
_tileMapNode34 = [CCTMXTiledMap tiledMapWithTMXFile:@"title34.tmx"];
_tileMapNode44 = [CCTMXTiledMap tiledMapWithTMXFile:@"title44.tmx"];
_tileMapNode54 = [CCTMXTiledMap tiledMapWithTMXFile:@"title54.tmx"];

[ backgroundNode addChild:_tileMapNode14 z:0 parallaxRatio:backgroundScrollVel1 positionOffset:ccp((mapnum-1)*2688,0)];
[ backgroundNode addChild:_tileMapNode24 z:1 parallaxRatio:backgroundScrollVel2 positionOffset:ccp((mapnum-1)*4032,0)];
[ backgroundNode addChild:_tileMapNode34 z:2 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode addChild:_tileMapNode44 z:3 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];
[ backgroundNode1 addChild:_tileMapNode54 z:1 parallaxRatio:backgroundScrollVel3 positionOffset:ccp((mapnum-1)*5376,0)];

break;

default:

break;
}

第四步 重新加载一个地图之前的tilemap对象并没有及时被删除这样会造成内存过大问题,所以我们在一幅地图使用完后进行删除。在update函数里添加:

if(backgroundNode.position.x <= -(2688*(mapnum-1))){
//CCLOG(@"---------------------%d",mapnum);

switch (mapnum%5) {

case 1:
[backgroundNode removeChild:_tileMapNode14 cleanup:YES];
[backgroundNode removeChild:_tileMapNode24 cleanup:YES];
[backgroundNode removeChild:_tileMapNode34 cleanup:YES];
[backgroundNode removeChild:_tileMapNode44 cleanup:YES];
[backgroundNode1 removeChild:_tileMapNode54 cleanup:YES];

break;

case 2:
[backgroundNode removeChild:_tileMapNode11 cleanup:YES];
[backgroundNode removeChild:_tileMapNode21 cleanup:YES];
[backgroundNode removeChild:_tileMapNode31 cleanup:YES];
[backgroundNode removeChild:_tileMapNode41 cleanup:YES];
[backgroundNode1 removeChild:_tileMapNode51 cleanup:YES];

break;

case 3:
[backgroundNode removeChild:_tileMapNode12 cleanup:YES];
[backgroundNode removeChild:_tileMapNode22 cleanup:YES];
[backgroundNode removeChild:_tileMapNode32 cleanup:YES];
[backgroundNode removeChild:_tileMapNode42 cleanup:YES];
[backgroundNode1 removeChild:_tileMapNode52 cleanup:YES];

break;

case 0:
[backgroundNode removeChild:_tileMapNode13 cleanup:YES];
[backgroundNode removeChild:_tileMapNode23 cleanup:YES];
[backgroundNode removeChild:_tileMapNode33 cleanup:YES];
[backgroundNode removeChild:_tileMapNode43 cleanup:YES];
[backgroundNode1 removeChild:_tileMapNode53 cleanup:YES];

break;

default:

break;
}

}

第五步:使地图移动起来,方法和之前说过ccparallaxnode的一样。具体函数如下
-(void)updatebackground:(ccTime)dt{
if(_paused==false){
CGPoint backgroundScrollVel = ccp(-50,0);
backgroundNode.position = ccpAdd(backgroundNode.position, ccpMult( backgroundScrollVel, dt));
backgroundNode1.position = ccpAdd(backgroundNode1.position, ccpMult( backgroundScrollVel, dt));

}
else{
[[CCDirector sharedDirector] stopAnimation];
[[CCDirector sharedDirector] pause];
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
}
}
完成了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: