有没有人成功地使用 JSTilemap 仅加载可见图块?我问的原因是因为我的地图太大而无法一次加载,我想单独加载段或只动态加载当前在屏幕上可见的图块。
我不想使用 KoboldKit。
编辑:令人兴奋的更新。Steffan 和 Marcus 正在 TilemapKit.com 上开发一个漂亮的工具包。迫不及待地想把钱扔给他们。
有没有人成功地使用 JSTilemap 仅加载可见图块?我问的原因是因为我的地图太大而无法一次加载,我想单独加载段或只动态加载当前在屏幕上可见的图块。
我不想使用 KoboldKit。
编辑:令人兴奋的更新。Steffan 和 Marcus 正在 TilemapKit.com 上开发一个漂亮的工具包。迫不及待地想把钱扔给他们。
我过去使用过分段地图方法。这适用于侧面滚动地图,您只需在侧面添加另一块。它也适用于需要侧面和底部或顶部的较大地图。
使用这种方法的另一个好处是,如果需要,可以在每次加载新地图时随机化地图部分。这消除了特定级别的“相同的旧地图”。
对于下面的代码示例,我使用相同大小的地图部分,宽度为 1280,并排放置。以下是涉及的步骤:
在 Tiled 应用程序中创建相同大小的地图部分。为每个地图部分指定一个以数字结尾的唯一名称。像这样的东西:MyMap-0、MyMap-1、MyMap-2 等等。
创建一个可变数组来保存您的地图部分。让我们称之为mapSectionsArray
。
创建一个名为的 float ivarmapOffsetX
并将其初始值设置为零。
如果您要创建包含 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];
}
}
}
以前已经这样做过。看看这里如何让 JSTileMap 做你所要求的。
https://github.com/fattjake/JSTileMap/commit/01b5bacc8c5ccc1099e020276d204ba439a6d06c
希望有帮助!
稍后更新:初步研究表明这可能不是要走的路,让 spriteKit 为您处理优化。看到这个小讨论: https ://github.com/slycrel/JSTileMap/issues/28