tmlib-rpg マップの作成

RPGには、マップは必須だけど、tmlib.js には、マップ関連のクラスが用意されています。
今のところ、それを、ほぼそのまま利用するだけで良さそうなのでとても楽。
レイヤーもいっぱい作れそうだし、イベントの配置もちゃんとできるぽい。

オートタイルが無いみたいだけど、これはまた別の方法を考えてるので、今のマップ関連クラスは、修正必要ないと思う。便利。

というわけで、今のところ出来てるのがこれ
[SceneMap](http://www4.big.or.jp/~fukuyama/tmlib-rpg/client/ "tmlib-rpg scene map")

jsdo.it でも良いのだけど、素材アップするのとか面倒だったので適当に…
（圧縮してアップするだけで良い環境があるのも、たまには便利）
まだロードシーンをちゃんと作ってないので読み込みに時間かかる。

```coffeescript:SceneMap.coffee
# マップシーン
tm.define 'SceneMap',

  superClass: rpg.SceneBase

  # 初期化
  init: (args='sample.scene.map') ->
    @superInit()

    args = tm.asset.AssetManager.get(args) if typeof args == 'string'
    {
      @mapSheet
    } = {}.$extendAll(ASSETS['sample.scene.map']).$extendAll(args)
    
    @pc = new rpg.Character()
    @map = rpg.SpriteMap(@pc, @mapSheet)
    @player = rpg.GamePlayer(@pc,@map)

    @addChild(@map)
    @map.addChild(rpg.SpriteCharacter(@pc))

    dummy = tm.app.CanvasElement()
    dummy.update = @map.updatePosition.bind(@map)
    @addChild(dummy)

  update: (app) ->
    @player.update()
```
@mapSheet は文字列で、指定して、Asset の .tmx でマップを変更。

ちょっと苦労したのは、マップのスプライトの更新を、update で自動でするのは、なんかうまくなかった。
具体的には、マップのスクロールをさせようと、キャラクターを移動させつつ、マップの表示位置を逆に移動させるのだけど、そのタイミングがずれちゃう。カクカクする。

たぶん、プレイヤーで使うキャラクターのスプライトを、マップの上（child）に配置するので
更新 update の順番が、map -> character の順になってる。
福山の実装では、character の update でキャラクターの位置を変更していて
map の update で、マップを逆に移動させるのが順番的に逆の方が都合が良い感じだから…

親子関係の更新順番を変更する方法がわからなかったので、とりあえず、dummy の CanvasElement を作成。
でもって、map の表示位置の更新を、map の update で行わず、updatePosition でして、それを dummy の update から呼ばせる。…って書いててわけわからん＾＾

とにかく、キャラクターの位置とマップの逆移動を、character -> map の順でする。
そうしないと、フレームをまたいでしまうのでカクカクする感じ？

```coffeescript:SpriteMap.coffee
# マップクラス
tm.define 'rpg.SpriteMap',

  superClass: tm.app.MapSprite

  # 初期化
  init: (@pc, @mapSheet='sample.mapsheet') ->
    cw = ch = rpg.system.map.chipSize
    @superInit(@mapSheet, cw, ch)
    
    @_screenCX = rpg.system.screen.width / 2 - rpg.system.map.chipSize / 2
    @_screenCY = rpg.system.screen.height / 2 - rpg.system.map.chipSize / 2
    @_screenMX = @width - @_screenCX - rpg.system.map.chipSize
    @_screenMY = @height - @_screenCY - rpg.system.map.chipSize

  updatePosition: () ->
    @x = @_screenCX - @pc.x if @_screenCX <= @pc.x and @pc.x <= @_screenMX
    @y = @_screenCY - @pc.y if @_screenCY <= @pc.y and @pc.y <= @_screenMY
    @
```
MapSprite は、スクロールの対応とかプレイヤーの対等とかが、まだ無いぽいので、SpriteMap を作って対応

```coffeescript:GamePlayer.coffee

# プレイヤークラス
tm.define 'rpg.GamePlayer',

  superClass: tm.app.Element

  # 初期化
  init: (@character,@map) ->
    @superInit()

    @eventHandler = rpg.EventHandler(active:true,repeatDelay:0)
    @eventHandler.setupHandler(@)

    @eventHandler.addRepeatHandler {
      up: @input_up.bind(@)
      down: @input_down.bind(@)
      left: @input_left.bind(@)
      right: @input_right.bind(@)
    }
    Object.defineProperty @, 'active',
      enumerable: true
      get: -> @eventHandler.active
      set: (b) -> @eventHandler.active = b if typeof b is 'boolean'
 
  # 更新
  update: ->
    @eventHandler.updateInput()

  # 上入力処理
  input_up: ->
    if not @character.isMove()
      @character.moveUp()

  # 下入力処理
  input_down: ->
    if not @character.isMove()
      @character.moveDown()

  # 左入力処理
  input_left: ->
    if not @character.isMove()
      @character.moveLeft()

  # 右入力処理
  input_right: ->
    if not @character.isMove()
      @character.moveRight()
```
一応、プレイヤークラス。キャラクターはいろいろ変更可能に。