1

我很难理解JSTileMap如何与 SpriteKit 和 Tiled 一起使用。

该问题与像素和点有关,也与使用基于屏幕比例因子的 JSTileMap 加载适当的图块集有关。

项目中的文件结构

在我的项目中,有一些文件具有以下结构,这代表了我的低分辨率地图(1024x768px 和 32x32px 瓷砖):

  • 名为 SD 的文件夹
    • 级别 1.tmx
    • 文件夹 tmx-levels-sd.atlasc
      • tmx-levels-sd.1.png
      • tmx-levels-sd.plist

在这种情况下,当我在非视网膜模拟器上加载level-1.tmx时,一切都已正确定位。当我在视网膜模拟器上运行相同的配置时,一切都很好,但瓷砖被缩放了。因为质量受到影响。 那么,如何在需要的时候加载高分辨率的瓦片集呢?

另一种解决方案

我还尝试通过为每个级别使用两个版本的地图(低分辨率和高分辨率)来解决这个问题。这实际上是我试图避免但仍然可以接受的:

对于这种情况,我有这样的文件结构(地图是 2048x1536 和 64x64px 瓷砖):

  • 名为 SD 的文件夹
    • 级别 1.tmx
    • 文件夹 tmx-levels-sd.atlasc
      • tmx-levels-sd.1.png
      • tmx-levels-sd.plist
  • 名为 HD 的文件夹
    • 级别 1-hd.tmx
    • 文件夹 tmx-levels-hd.atlasc
      • tmx-levels-hd.1.png
      • tmx-levels-hd.plist

我猜那张大小为 2048x1536 且瓦片大小加倍的地图适合我的地图的高分辨率版本?同样如您所见,我的项目中根本没有@2x 瓦片集(我猜我们不能在Tiled 编辑器和JSTileMap 中使用@2x 后缀?)。

这种配置的问题是一切都被改变了(位置和瓷砖尺寸加倍)。JSTileMap 可能适用于点,平铺像素,最重要的是,有一个已知的与纹理图集相关的 iPad 模拟器错误,这让我很难理解导致高分辨率地图问题的原因。

有人可以澄清这些关于完全使用 JSTileMap、SpriteKit 和 Tiled 的事情吗?谢谢!

4

1 回答 1

4

我收到了你的消息。

首先,您需要@1x 和@2x 版本的图块(精灵)。因此,如果您有一个名为 myTiles 的图集,您将需要:myTiles.png 和 myTiles@2x.png。

我使用纹理打包器创建了我的精灵表。我添加了@2x 图像,然后在导出时创建了@1x 版本。

在 Tiled 中仅使用 @1x​​ 版本,因此您将使用 myTiles.png

如果您的地图是 32x32,您的 @1x 版本将是 32x32,而您的 @2x 版本将是 64x64

忘记 SD 和 HD 文件夹,只使用 1 个称为级别的文件夹

在这里你需要:

level-1.tmx, tmx-levels-sd.1.png, tmx-levels-sd.1@2x.png

您可以在主级别文件夹下拥有子文件夹。由您决定,但您必须同时拥有 png 的 @1x 版本和 @2x 版本,并且您不能只复制 @1x 或 @2x 版本。@1x 版本必须是基于 32x32 的图块,@2x 版本必须是其两倍 (64x64)。在 tmx 文件本身中,您不会加载 @2x 版本,因为这会弄乱您的关卡。

** 所以你的游戏将在一个 32x32 的图块集上。sprite kit 的作用是将视网膜显示器上的像素加倍,因此为此您需要提供@2x 版本,否则它将升级您的@1x 版本,并且图块看起来很大且像素化。所以尽量不要与整个像素点混淆。

代码示例:

GameViewController(加载场景):

- (void)viewDidLoad
{
[super viewDidLoad];

self.currentLevel = 1;

// Configure the view.
SKView * skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;

/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = YES;

// Create and configure the scene.
LevelScene *scene = [[LevelScene alloc]initWithSize:skView.bounds.size level:self.currentLevel];
scene.scaleMode = SKSceneScaleModeAspectFill;

// Present the scene.
[skView presentScene:scene];
}

LevelScene(加载 JSTileMap):

#import "LevelScene.h"
#import "SKTAudio.h"
#import "JSTileMap"
#import "Player.h"

@interface LevelScene()

@property (nonatomic, assign) NSUInteger currentLevel;
@property (nonatomic, strong) SKNode *gameNode;
@property (nonatomic, strong) JSTileMap *map;
@property (nonatomic, strong) Player *player;
@property (nonatomic, assign) NSTimeInterval previousUpdateTime;

@implementation LevelScene

-(id)initWithSize:(CGSize)size level:(NSUInteger)currentLevel {

if ((self = [super initWithSize:size])) {
    self.currentLevel = currentLevel;
self.gameNode = [SKNode node];
    [self addChild:self.gameNode];
NSString *levelName = [levelDict objectForKey:@"level"];
    self.map = [JSTileMap mapNamed:levelName];

    [self.gameNode addChild:self.map];
return self;
}
于 2015-01-18T19:01:38.020 回答