我过去使用过分段地图方法。这适用于侧面滚动地图,您只需在侧面添加另一块。它也适用于需要侧面和底部或顶部部件的较大地图。
使用这种方法的另一个好处是,如果需要,可以在每次加载新地图时随机化地图部分。这消除了特定级别的“相同的旧地图”。
对于下面的代码示例,我使用相同大小的地图部分,宽度为 1280,并排放置。以下是涉及的步骤:
在 Tiled 应用中创建相同大小的地图部分。为每个地图部分指定一个以数字结尾的唯一名称。类似这样的东西:MyMap-0、MyMap-1、MyMap-2 等等。
创建一个可变数组来保存您的地图部分。我们就叫它mapSectionsArray吧。
创建一个名为 mapOffsetX 的浮点 ivar,并将其初始值设置为零。
如果您希望创建一个包含 10 个部分的静态地图,请使用以下代码:
for (int i = 0; i < 10; i++) {
NSString *myString = [NSString stringWithFormat:@"MyMap-%d.tmx",i];
JSTileMap *tiledMap = [JSTileMap mapNamed:myString];
tiledMap.position = CGPointMake(mapOffsetX, 0);
tiledMap.zPosition = 100;
[worldNode addChild:tiledMap];
[mapSectionsArray addObject:tiledMap];
mapOffsetX += 1280;
}
如果您要创建一个包含 10 个部分的随机地图,请使用以下代码:
// create an array with the total number of sections created.
// in this example I have created 30 sections in total
// I make sure not to load the same section twice
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", @"13", @"14",@"15", @"16", @"17", @"18", @"19", @"20", @"21", @"22", @"23", @"24", @"25", @"26", @"27", @"28", @"29", nil];
for (int i = 0; i < 10; i++) {
int r1 = arc4random() % [myArray count];
NSString *myString = [NSString stringWithFormat:@"MyMap-%@.tmx",[myArray objectAtIndex:r1]];
JSTileMap *tiledMap = [JSTileMap mapNamed:myString];
tiledMap.position = CGPointMake(mapOffsetX, 0);
tiledMap.zPosition = 100;
[worldNode addChild:tiledMap];
[mapSectionsArray addObject:tiledMap];
mapOffsetX += 1280;
[myArray removeObjectAtIndex:r1];
}
要在地图的对象层中加载项目,您可以这样做:
-(void)loadMapObjects {
float xOffset;
xOffset = 0;
for (int i = 0; i < [mapSectionsArray count]; i++) {
TMXObjectGroup *group = [[mapSectionsArray objectAtIndex:i] groupNamed:@"ObjectLayerName"];
NSArray *arrayObjects = [group objectsNamed:@"objectName"];
for (NSDictionary *dicObj in arrayObjects) {
SKNode *myNode = [SKNode node.....];
CGFloat x = [dicObj[@"x"] floatValue];
CGFloat y = [dicObj[@"y"] floatValue];
myNode.position = CGPointMake(x+xOffset, y);
[worldNode addChild:myNode];
}
xOffset += 1280;
}
在更新方法中,您可以根据玩家的位置添加或删除选定的地图部分,如下所示:
// the exact values are determined by your view's size
// and map section's width
left = player.position.x - 1500;
right = player.position.x + 1500;
up = player.position.y + 1000;
down = player.position.y - 1000;
for(JSTileMap *object in mapSectionsArray) {
if((object.position.x > left) && (object.position.x < right) && (object.position.y > down) && (object.position.y < up)) {
if(object.parent == nil) {
[worldNode addChild:object];
}
} else {
if(object.parent != nil) {
[object removeFromParent];
}
}
}
根据玩家的位置,地图部分被删除或添加到 worldNode 父级。
另一个优化是当它们不在视野中时,也可以(从父级)移除具有物理实体的对象。这可能可行,也可能不可行,具体取决于您游戏的设计和逻辑。
你可以在更新方法中处理这个:
left = player.position.x - 1500;
right = player.position.x + 1500;
up = player.position.y + 1000;
down = player.position.y - 1000;
for(SKSpriteNode *object in mapItemsArray) {
if((object.position.x > left) && (object.position.x < right) && (object.position.y > down) && (object.position.y < up)) {
if(object.parent == nil) {
[worldNode addChild:object];
}
} else {
if(object.parent != nil) {
[object removeFromParent];
}
}
}