Hi,
some time ago we recognized that our fps drops down when we dont split our tilemaps.
So we splitted them into 16x11 parts. (32x32 pixel each tiles)
There are only 2x2 parts around the camera center active at the same time ( visible = YES ) that means we got 4 parts active.
Each part got 4 layers, where the 1st and the 4th layer are rarly mapped.
That means we got maximal 16*11*4*4 tiles at the same time visible.
Heres the code how we read and add the maps in our game:
// Read the map with the ID: newMapID
tilemap = [[CCTMXTiledMap alloc] initWithTMXFile:[NSString stringWithFormat:@"Map%d.tmx",newMapID]];
// Now add the map to our layer.
[self addChild:tilemap];
// gathering some map informations:
mapWidth = (int)tilemap.mapSize.width;
int height = (int)tilemap.mapSize.height;
mapPixWidth = mapWidth * (int)tilemap.tileSize.width;
// deadY is our line where our player will die after crossing it.
deadY = [[[tilemap properties] objectForKey:@"DeadY"] intValue]*32+16;
// Find what collision mask we want for this map:
if([[[tilemap properties] objectForKey:@"CMask"] isEqualToString:@"desertcastle"])
cmask=0;
else if([[[tilemap properties] objectForKey:@"CMask"] isEqualToString:@"cave"])
cmask=1;
else if([[[tilemap properties] objectForKey:@"CMask"] isEqualToString:@"forest"])
cmask=2;
// Prepare gathering all tile data for the collision layer (2nd layer)
memset(gamedata.collisionMap,0,sizeof(unsigned int)*13000);
// our map is splitted in 16x11 parts, we calculate now how many parts our map includes:
for(int i=0;i<(int)ceil((float)tilemap.mapSize.width/16.0f);i++){
for(int a=0;a<(int)ceil((float)tilemap.mapSize.height/11.0f);a++){
// THE BELOW LAYER:
[self reorderChild:[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]] z:1];
// The collision layer
[self reorderChild:[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]] z:2];
// The decoration layer
[self reorderChild:[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]] z:3];
// THE ABOVE LAYER: (7 becauze player is above all events and this layer is above the player)
[self reorderChild:[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]] z:7];
// We dont want antialiased textures on the map, this should be faster at the same time
[[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].texture setAliasTexParameters];
[[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].texture setAliasTexParameters];
[[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].texture setAliasTexParameters];
[[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].texture setAliasTexParameters];
// becauze we splitted the map into 16x11 parts we have to move them for the right
// position.
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].position = ccp(512*i,32*(tilemap.mapSize.height-a*11));
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].position = ccp(512*i,32*(tilemap.mapSize.height-a*11));
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].position = ccp(512*i,32*(tilemap.mapSize.height-a*11));
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].position = ccp(512*i,32*(tilemap.mapSize.height-a*11));
// set the anchor point to top left cornor
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].anchorPoint = ccp(0,1);
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].anchorPoint = ccp(0,1);
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].anchorPoint = ccp(0,1);
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].anchorPoint = ccp(0,1);
// make all parts invisible becauze later we only change the visible atribute of the
// parts inside the view
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible = NO;
// now gather all collision datas: (this should be unintersiting for the thread issue)
unsigned int tid;
for(int y1=0;y1<(int)MIN(11,(int)tilemap.mapSize.height-a*11);y1++){
for(int x1=0;x1<(int)MIN(16,(int)tilemap.mapSize.width-i*16);x1++){
tid = [[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]] tileGIDAt:ccp(x1,y1)];
if(i*16+a*11*mapWidth+x1+y1*mapWidth >= 13000)
NSLog(@"error for tile pos id: %i",i*16+a*11*mapWidth+x1+y1*mapWidth);
else
gamedata.collisionMap[i*16+a*11*mapWidth+x1+y1*mapWidth] |= MAX(0,tid-1);
}
}
}
}
(E1P3-4 is Layer 1 Horizontal Part 3 and Vertical Part 4)
Before our cave map ( look the image below ) we have 60fps but on this map we have only around 40fps.
When we reach the mushrooms where are almost 0 tiles we still got 40fps.
My questions now are:
- Do we read the map on the right way?
- Do we add it on the right way?
If u need the way how i toogle the visible state, here it is:
-(void) makeLayersVisible{
if(
activeCenterLayer != (int)((camCenter.position.x)/512.0f) ||
roundCenterLayer != (int)round((camCenter.position.x)/512.0f) ||
activeCenterVLayer != (int)((tilemap.mapSize.height*32-camCenter.position.y)/352.0f) ||
roundCenterVLayer != (int)round((tilemap.mapSize.height*32-camCenter.position.y)/352.0f)){
int i=activeCenterLayer+modX;
int a=activeCenterVLayer;
if((modX == -1 ? (i >= 0) : (i < maxX))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible = NO;
}
a=activeCenterVLayer+modY;
if((modX == -1 ? (i >= 0) : (i < maxX)) && (modY == -1 ? (a >= 0) : (a < maxY))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible = NO;
}
i=activeCenterLayer;
if((modY == -1 ? (a >= 0) : (a < maxY))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible = NO;
}
a=activeCenterVLayer;
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible = NO;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible = NO;
activeCenterLayer = (int)((camCenter.position.x)/512.0f);
activeCenterVLayer = (int)((tilemap.mapSize.height*32-camCenter.position.y)/352.0f);
roundCenterLayer = (int)round((camCenter.position.x)/512.0f);
roundCenterVLayer = (int)round((tilemap.mapSize.height*32-camCenter.position.y)/352.0f);
modX=(activeCenterLayer == roundCenterLayer ? -1 : 1);
modY=(activeCenterVLayer == roundCenterVLayer ? -1 : 1);
i=activeCenterLayer+modX;
a=activeCenterVLayer;
if((modX == -1 ? (i >= 0) : (i < maxX))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible |= YES;
}
a=activeCenterVLayer+modY;
if((modX == -1 ? (i >= 0) : (i < maxX)) && (modY == -1 ? (a >= 0) : (a < maxY))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible |= YES;
}
i=activeCenterLayer;
if((modY == -1 ? (a >= 0) : (a < maxY))){
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible |= YES;
}
a=activeCenterVLayer;
[tilemap layerNamed:[NSString stringWithFormat:@"E1P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E2P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E3P%i-%i",i,a]].visible |= YES;
[tilemap layerNamed:[NSString stringWithFormat:@"E4P%i-%i",i,a]].visible |= YES;
}
}
Any clues?
thx.