Dieses Dokuwiki verwendet ein von Anymorphic Webdesign erstelltes Thema.

타일맵

cocos2d에서 타일맵을 생성하는 두가지 방법이 있습니다.

  • TMX 타일맵 포멧 이용(신규, 유연함, 권장됨)
  • PGU 타일맵 포멧 이용(이전, 사양세)

TMX 타일맵 포멧

Tiled를 사용하여 타일맵을 생성할 수 있습니다.

Tiled는 두 가지 버전이 있습니다.:

  • TiledOS/X, 윈도우즈, 리눅스에서 돌아가는 자바 어플리케이션입니다.
  • A QT (native) application that supports almost all the features of the java version. As of this writing, the latest QT version is 0.4.0 and supports everything but hexagonal maps

Tiled를 사용하여 맵을 생성하는 방법이 여기에 설명되어 었습니다.:

cocos2d는 TMX 맵을 다음과 같이 지원합니다. :

  • 방위:
    • 정사각맵
    • 마름모맵(사각측면뷰)
    • 육각맵 (왼쪽-오른쪽 수직선. 위-아래 수평선은 지원하지 않음. Tiled에서 지원하지 않을 것으로 보임)
  • 타일:
    • 임베디드 타일은 지원하지 않습니다.(내장 이미지를 사용하는 타일셋)
    • embedded 타일셋만 지원됩니다.(타일셋은 내장되나 이미지는 안되는)
    • 한 레이어당 하나의 타일셋만 지원합니다.
  • 레이어:
    • 레이어 수 무제한
    • 각 레이어는 내부적으로 CCTMXLayer(CCSpriteSheet의 서브클래스)에 의해 표현됩니다.
    • 각 타일은 CCSprite(CCTMXLayer의 상위)으로 표현됩니다.
  • 오브젝트 그룹:
    • Tiled는 오브젝트 그룹을 지원합니다.

외부 이미지로 내장 타일셋을 생성하는 방법

cocos2d는 타일셋의 내장 이미지를 지원하지 않습니다.(그러나 맵 파일에 내장된 타일셋은 지원합니다.) 대신 sprite sheet 이미지(AKA:텍스쳐 아틀라스 (Texture Atlas))를 직접 생성하야여 합니다.

Tiled 정보 셋팅

내장 이미지를 타일셋에 정장하지 않도록 tiled를 사용하기

$ cd bin/tiled-0.7.2/
$ java -jar tiled

Tiled에서 다음을 따라하세요. :

  • Edit → Preferences → Saving
  • Layer Options:
    • Use binary encoding: ON (“텍스트” 인코딩은 cocos2d에서 지원되지 않습니다.)
    • Compress layer data: ON (비압축 데이터 또한 지원됩니다.)
  • Tileset Options:
    • Embed images (PNG): OFF (내장 이미지는 지원되지 않습니다.)

Tiled Preferences

새로운 맵을 생성할 때 주의점으로 Map Size는 수직/수평 타일들의 숫자와 관계가 있으며 맵의 픽셀수와는 관계가 없습니다. 이는 iPhone이 지원할 맵 사이즈에 제한을 받는다는 것입니다.(user comment : 44×44 픽셀 작업으로 100×100 픽셀을 본 적이 있으나 400×200은 동작하지 않았습니다.(타일들이 검정색이 되어 버렸습니다.))

내장된 타일셋으로 작업하기

맵에 사용할 타일셋은 반드시 맵 파일로 임베디드되어야 합니다. Tiled에서 이는 “Tileset Manager”에서 조정합니다.(Tilesets → Tileset Manager) 여러분은 컬럼에서 타일셋 리스트의 타일셋 이름 오른쪽에 ”(Embeded)” 라는 컬럼을 확인하는 것이 좋습니다. The tilesets for your map must be embedded into the map file. In Tiled this is controlled in the “Tileset Manager” (accessed via: Tilesets → Tileset Manager ). You should see ”(Embedded)” in the column to the right of the tileset name in the list of tilesets. 패스스트링을 확인하면, 여러분은 리스트에서 row를 선택하고, 내장 타일셋으로 변환할 오른쪽 Embed icon을 선택하면 됩니다.

만약 여러분이 다른 툴을 사용하고 있거나 파일을 열어서 확인하고 싶다면 *.xml 파일을 텍스트 또는 XML 에디터로 열어서 <tileset> 노드를 확인하세요. 파일 이름과 source 속성이 포함되어 있으면 여러분은 cocos2d-iphone에서 동작하지 않을 외부 타일셋을 쓰고 있는 것입니다.

스프라이트 시트 생성하기

유용한 이미지팩이 있습니다. :

  • mkatlas.pl a command line texture atlas creator (shipped with cocos2d) (free)
  • Packer a visual texture atlas creator (free)
  • Image Magic A command line utility (free)
  • zwoptex a visual texture atlas creator (free & commercial)
  • TexturePacker Graphical Userinterface + Command line (free & commercial)

이 툴들을 사용하면 개별 이미지에서 sprite sheets를 생성할 수 있습니다.

스프라이트 시트의 제한 :

  • 아이폰3GS의 최대 사이즈: 2048×2048 이며, 이전 아이폰의 최대 사이즈는 1024×1024
  • 각 타일은 모두 같은 사이즈이어야 합니다.

옵션:

  • 여백 (margin) : the space in pixels in the margins
  • 간격 (spacing) : the space in pixels between the tiles

margin은 2, spaceing은 2를 사용할 것을 권장합니다.

The spritesheet artifact fixer

If you experience lines flickering between the borders of your tiles when you move your map, this tool will fix that. Please note, these lines don't appear in the simulator, only on devices.

spritesheet-artifact-fixer는 스프라이트시트를 수정할 수 있는 cocos2d의 소형툴입니다.

이는 타일의 외곽선을 복사하고 간격/여백 픽셀을 조정합니다. 이론적으로 간격/여백 픽셀은 렌더링되지 않지만 가끔 예제에서는(특히 안티알리아스 텍스쳐와 3D 투영을 사용하면) 렌더링 됩니다.

툴 사용법 :

$ cd cocos2d/tools
$ python spritesheet-artifact-fixer.py -f spritesheet.png -x 32 -y 32 -m 2 -s 2

An alternative is using TexturePacker with the –extrude feature:

$ TexturePacker *.png --extrude 1 --plist test.plist --sheet test.png

좌표와 GIDS

좌표

Tiled에 사용된 64×32 맵의 좌표는 :

  • (0,0): 좌상단
  • (63,31): 우하단

GID

A tile's GID is the tile's Global IDentifier. It is an unsigned int that goes from 1 until the quantity of tiles.

If you have 5 different tiles then:

  • Tile 0 will have GID 1
  • Tile 1 will have GID 2
  • Tile 2 will have GID 3
  • and so on.

The GID 0 is used to represent to empty tile.

How to create a TMX node

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"hexa-test.tmx"];
[self addChild:map];

디폴트에서 모든 타일은 알리아스됩니다. 안티알리아스 타일을 생성하려면 다음을 따라야합니다. :

// create a TMX map
CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];
[self addChild:map];
 
// iterate over all the "layers" (atlas sprite managers)
// and set them as 'antialias' 
for( CCTMXLayer* child in [map children] ) {
    [[child texture] setAntiAliasTexParameters];
}

Full example:

How to get/add/delete/modify a tile

To obtain a tile (CCSprite) at a certain coordinate

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
CCSprite *tile = [layer tileAt:ccp(0,63)];
tile.anchorPoint = ccp(0.5f, 0.5f);

To obtain a tile's GID at a certain coordinate

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
unsigned int gid = [layer tileGIDAt:ccp(0,63)];

To set a new tile's GID's at a certain coordinate

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
[layer setTileGID:gid2 at:ccp(3,y)];

To remove a tile at a certain coordinate

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
[layer removeTileAt:ccp(15,15)];

To iterate a Layer

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
CGSize s = [layer layerSize];
for( int x=0; x<s.width;x++) {
	for( int y=0; y< s.height; y++ ) {
		unsigned int tmpgid = [layer tileGIDAt:ccp(x,y)];
		[layer setTileGID:tmpgid+1 at:ccp(x,y)];
	}
}

z order and depth buffer

Information valid on v0.99.1 or newer

Information valid both for Isometric and Orthogonal maps. NOT valid for Hexagonal maps

If your game needs to place the sprites behind/in front of certain tiles according to the sprites' Y position (a common scenario in isometric maps, and in some orthogonal maps too), then you have 2 options:

  • Use OpenGL ES depth buffer
  • Use multiple TMX Layers and z-order

Using Depth Buffer

This option uses the OpenGL ES depth buffer. So, the 1st thing that you must do, is to create a z-buffer and a 2D projection

// Place this code in your AppDelegate, before attaching the director to the window view.
// you can use a 24-bit buffer too with: kDepthBuffer24
[[CCDirector sharedDirector] setDepthBufferFormat:kDepthBuffer16];
 
// You can place this code anywhere you want. You can change the projection in runtime
[[CCDirector sharedDirector] setProjection:CCDirectorProjection2D];

It is also very important to create a map with 2 TMX Layers

  • A background layer. eg: grass
  • A foreground layer. eg: trees

The grass layer will be behind the sprites, so its vertexZ value should be the lowest possible value. eg:-1000. The trees layer should have different vertexZ values for the tiles. Tiles that are at the bottom should have higher vertexZ than the tiles that are at the top.

So, in order to achieve this, you should do:

  1. Open Tiled
  2. Select the background Layer (eg: grass)
  3. Tiled → Layer → Layer Properties
  4. Add: cc_vertexz = -1000
  5. Select the foreground Layer (eg: trees)
  6. Tiled → Layer → Layer Properties
  7. Add: cc_vertexz = automatic

The other important thing to do is to draw your sprites with GL_ALPHA_TEST enabled. Example:

//MySprite is a subclass of CCSprite.
// If you are drawing sprites using CCSpriteSheet, then you should subclass CCSpriteSheet and not CCSprite.
// You can also enable GL_ALPHA_TEST globally, but if you do so, you need to comment the the CCTMXLayer#draw method (see CCTMXLayer.m)
// There are other alternatives. This is just an example.
@implementation MySprite
-(void) draw
{
   glEnable(GL_ALPHA_TEST);
   glAlphaFunc( GL_GREATER, 0 );
   [super draw];
   glDisable(GL_ALPHA_TEST);
}
@end

Q: How does cc_vertexz work ?

A: cc_vertexz accepts either the word automatic or an integer number

  • If the value is a integer (negative or positive), then, that number will be used as the vertexZ value for all the tiles of that layer
  • If the value is automatic then the first row of tiles will have a vertexZ value of -1, the second row will have a vertexZ value of -2, an so on.

The only thing left to do is to modify your sprites' vertexZ value according to its Y position. Example:

-(void) repositionSprite:(ccTime)dt
{
	// tile height is 101x81
	CGPoint p = [sprite position];
	[sprite setVertexZ: -( (p.y+81) /81) ];
}

Please, see TileMapTest.m for a working sample.

Q: When should I use cc_alpha_func ?

A: The cc_alpha_func value will only be used when cc_vertexz=automatic. By default it will have a value of 0. This value will be used to draw the tiles using the GL_GREATER function. This is how CCTMXLayer draws the tiles:

// CCTMXLayer drawing function
-(void) draw
{
	if( useAutomaticVertexZ_ ) {
		glEnable(GL_ALPHA_TEST);
		glAlphaFunc(GL_GREATER, alphaFuncValue_);
	}
 
	[super draw];
 
	if( useAutomaticVertexZ_ )
		glDisable(GL_ALPHA_TEST);
}

Examples:

Isometric vertex Z example. It has 2 layers: “trees” and “grass”. Uses cc_vertex=automatic for the “trees” layer. And cc_vertexz=-1000 for the “grass” layer.
 Orthogonal vertex example. It has 2 layers: “trees” and “grass”. It uses cc_vertexz=automatic and cc_alpha_func=0.5 for the “trees” layer. and cc_vertexz=-1000 for the “grass” layer.

Using multiple TMX Layers and z-order

Each layer in the map is automatically assigned it's own zOrder value, so there is no need to add any layer attributes in your TMX editor. Adding your sprite as a child of the TMXMap allows you to dynamically place it within the layers of the map object.

CCTMXTiledMap map = [CCTMXTiledMap tiledMapWithTMXFile:@"Map.tmx"];
[self addChild:map];
 
CCSprite *character = [CCSprite spriteWithFile:@"Character.png"];
// Add the sprite as a child of the map, and set the z order to
// be the same as the layer you wish the sprite to appear
// immediately above.
[map addChild:character z:[map layerNamed:@"grass"] zOrder]];

See a working example here: TileMapTest.m

Screenshots

Orthogonal map, with 3D projection and anti-aliased tiles. The tiles were “fixed” using the spritesheet-fixer tool. No artifacts appears even with a 3D projection and anti-aliased tiles
Orthogonal map. map's tile size is smaller than the tiles
Isometric map, with 2D projection and aliased tiles
Hexagonal map, with 2D projection and aliased tiles. Edges are at the left-right. Bottom-top edges are not supported (yet)

PGU Tile Map Format

You can use the PGU Tile maps, too.

Since the format is not very flexible (is has limitations with it's sizes) and the editor seems to has some bugs, this format is deprecated. You will be able to continue using it with your old game, but it's usage is not recommended.

Instead, use the recommened TMX Tile Map.

Some articles about this format:

ko/prog_guide/tiled_maps.txt · Last modified: 2011/06/24 07:24 by o_o
Trace: 0_8_1 lesson_1._install_test hello_world hello_events hello_actions basic_concepts labels actions effects tiled_maps
Dieses Dokuwiki verwendet ein von Anymorphic Webdesign erstelltes Thema.
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0