「RPGのようなマップを作りたい時」の編集履歴(バックアップ)一覧に戻る

RPGのようなマップを作りたい時 - (2011/09/19 (月) 13:40:53) のソース

*タイル用の画像を描く
ここではフリーで使えるGimp(http://www.gimp.org/downloads/)を用いるが何でも良い。
  
*タイルを一枚のシートにまとめる。
ここではTexturePacker(http://www.texturepacker.com/
)を用いるが何でも良い。
 
*マップを作成する。
マップエディタとしてTiled Map Editorをインストールする
http://www.mapeditor.org/
 
注 作ったデータはbase64,gzip等で保存する事。
 
**作ったファイルはXCodeに放り込む
データを作る際に用いた画像データ(さきほど作った一枚にまとめたシート)も放り込む。
 
*マップを読み込む
  CCTMXTiledMap *tileMap = [CCTMXTiledMap tiledMapWithTMXFile:@"map.tmx"];
で読み込める。
 
注 読み込まれないときは、tmxファイルの中の画像の場所の指定(<image source="simpleSheet.png" width="32" height="64"/>
)が間違っている可能性がある。
 
*画面に表示させる
 [self addChild:tileMap z:-1 tag:1]; 
すれば良い。
 
**マップの左下が表示されている?
それは、Mapの位置が原点(0,0)になっているからである。Mapの位置を知りたい場合、今はtagを1で登録しているので
 CCTMXTiledMap *tileMap = (CCTMXTiledMap*)[self getChildByTag:1];
で取り出して
 tileMap.position
を見てやれば良い。これでMapの位置を設定してやることもできる。

注意点 Mapの位置を指定することで、例えば(30,0)とすると、Mapが右へ30ずれることがわかる。

***なぜ、左上でなく左下なのか?
cocos2dの座標原点は左下を(0,0)とするからである。
 
 
*タップしてスクロール
**まず画面のタッチを検知する
 今のレイヤーに
  - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  {
     NSLog(@"poi");//処理
  }
と書く。注意 レイヤーのisTouchEnabledをYESにしておかないと反応しない。
**タッチした座標を取得する。
touchbeganの中身に以下を書く。
 UITouch *touch = [touches anyObject];
 CGPoint point = [touch locationInView:[touch view]];
 NSLog(@"touch %f,%f",point.x,point.y); 
 
実際、タッチした座標を調べてみると、タッチで得られる座標は原点が左上を(0,0)としていることがわかる。

よって、このタッチ位置を左下を原点にするように変更するには
 CGSize screensize = [[CCDirector sharedDirector] winSize];
 CGPoint touchPoint = CGPointMake(point.x, screensize.height - point.y);
とすれば良い。

**タッチした点はマップ上の座標とするとどこになるのか
マップ自身の位置(例(-10,0) 表示されたマップは右に10ずれている)とタッチした位置(例(0,0)画面の左下をタッチしたとする)から
タッチした画面の位置におけるマップ上の位置は
    CGPoint abPoint;
    abPoint.x =  -tileMap.position.x  + touchPoint.x;
    abPoint.y =  -tileMap.position.y  + touchPoint.y;
 
で求まる。
 
よってタイルで換算すると    
    int x = (int)(abPoint.x/tileMap.tileSize.width);
    int y = (int)(abPoint.y/tileMap.tileSize.height);
がタッチしたタイルの(タイルの数を単位とした)位置となる。
 
**タッチしたタイルを画面中央に持って行きたいとき
    CGSize screenSize = [[CCDirector sharedDirector] winSize];
    
    CGPoint newTilemapPoint;
    newTilemapPoint.x = -1*(abPoint.x - screenSize.width/2 );
    newTilemapPoint.y = -1*(abPoint.y - screenSize.height/2 );

    [tileMap setPosition:newTilemapPoint];

とすれば良い。
 
**スクロールさせたい場合

setPositionをActionにかえる。

   CCAction* move = [CCMoveTo actionWithDuration:0.2f position:newTilemapPoint];
    [tileMap stopAllActions];
    [tileMap runAction:move];



*付録
**マップの画像はどこで読み込まれている?
 -(id) initWithTilesetInfo:(CCTMXTilesetInfo*)tilesetInfo layerInfo:(CCTMXLayerInfo*)layerInfo mapInfo:(CCTMXMapInfo*)mapInfo

----
#amazon2(600x520)