LoginSignup
3
3

More than 5 years have passed since last update.

tmlib-rpg マップの移動制限とかタイトルシーンとか作ってました。

Posted at

tmlib.js 0.1.8 の MapSheet クラスでは、移動制限がまだ無いぽいので実装してみました。
とりあえず、タイルセットでの移動制限

VX Ace では、ビット演算でしてたけど、なんとなく配列に

# 移動制限定数、移動できる方向が true
# 方向は [2,4,6,8] の位置パラメータ
# VXAce にならって乗り物も入れるか…?
MOVE_RESTRICTION = {
  ALLOK: [true,true,true,true]
  UPOK: [false,false,false,true]
  DOWNOK: [true,false,false,false]
  LEFTOK: [false,true,false,false]
  RIGHTOK: [false,false,true,false]
  ALLNG: [false,false,false,false]
  HORIZON: [false,true,true,false]
  VERTICAL: [true,false,false,true]
  CORNER1: [false,false,true,true]
  CORNER3: [false,true,false,true]
  CORNER7: [true,false,true,false]
  CORNER9: [true,true,false,false]
  UPNG: [true,true,true,false]
  DOWNNG: [false,true,true,true]
  LEFTNG: [true,false,true,true]
  RIGHTNG: [true,true,false,true]
}

もういろいろつらい^^
実際に、この値を使うのは内部なので、あまり気にしないかもだけど、名前が特につらい…感じ、通れるのを指定するのか通れないのを指定するのか…

たとえば HORIZON は、水平に通れるの?通れないの?とかとか(OKとかNGとかもつけてるけど…ごっちゃに…)

本来は、xml で MapSheet に設定されるんだけど、ここでは json でとりあえず。というかJavaScript の Object。
xml の場合は、tilesets のエレメントに image でタイルセットを指定するんだけど、さらに 移動制限として restriction を追加しました。
これは、タイルIDに対応した、移動可能方向を設定する。

  'sample.tileset': 'img/test_tileset.png'
  'sample.mapsheet':
    tilesets: [
    _type: 'tmx'
    width: 30
    height: 30
    tilewidth: 32
    tileheight: 32
    tilesets: [
      {
        image: 'sample.tileset'
        restriction: [
          MOVE_RESTRICTION.ALLOK
          MOVE_RESTRICTION.ALLNG
          MOVE_RESTRICTION.UPOK
          MOVE_RESTRICTION.DOWNOK
          MOVE_RESTRICTION.LEFTOK
          MOVE_RESTRICTION.RIGHTOK
          MOVE_RESTRICTION.HORIZON
          MOVE_RESTRICTION.VERTICAL
          MOVE_RESTRICTION.CORNER1
          MOVE_RESTRICTION.CORNER3
          MOVE_RESTRICTION.CORNER7
          MOVE_RESTRICTION.CORNER9
          MOVE_RESTRICTION.UPNG
          MOVE_RESTRICTION.DOWNNG
          MOVE_RESTRICTION.LEFTNG
          MOVE_RESTRICTION.RIGHTNG
        ]
      }
    ]

テスト用のタイルセット
test_tileset.png

あとは、まぁ~いろいろがんばってます。

Character.coffee
  # 移動可能判定
  # TODO: ななめどしよ
  isPassable: (x, y, d) ->
    # マップの取得
    map = rpg.system.scene.map
    # 向き指定が文字列の場合は、数値に
    d = CHARACTER_DIRECTION[d] if typeof d is 'string'
    # 向き設定インデックスの計算 2,4,6,8 と言うのを、0,1,2,3 に
    di = d / 2 - 1
    # 移動先座標の計算
    nx = x + X_ROUTE[di]
    ny = y + Y_ROUTE[di]
    # マップ範囲チェック
    return false if not map.isValid(nx,ny)
    # 移動可能チェック
    return false if not map.isPassable(x,y,d)
    # 向きを逆に
    rd = REVERSE_DIRECTION[di]
    return false if not map.isPassable(nx,ny,rd)
    true
Map.coffee
  # マップ範囲内かどうか
  isValid: (x, y) -> 0 <= x and x < @width and 0 <= y and y < @height

  # 移動可能判定
  isPassable: (x, y, d) ->
    r = @_restriction(x,y)
    r[d / 2 - 1]

  # 移動制限情報の取得
  _restriction: (x, y) ->
    # TODO: イベントから見つかったらそれを返す
    # TODO: マップ固有情報から見つかったらそれを返す
    # タイルセットから
    @_restrictionTileset(x, y)

  _restrictionTileset: (x, y) ->
    i = @mapSheet.layers.length - 1
    while i >= 0
      layer = @mapSheet.layers[i--]
      if layer.type == 'layer'
        tileid = layer.data[x + y * @width]
        if tileid >= 0
          return @mapSheet.tilesets[0].restriction[tileid]
    MOVE_RESTRICTION.PASS

今見て思ったけど、オートタイルの移動制限を考えてないや…(心覚え)

あとタイトルシーンとかも作ってます。

  'scene.title':
    _type: 'json'
    background:
      image: 'scene.title.background.image'
    menus: [{
        name:'Start'
        next:
          scene:'SceneMap'
      },{
        name:'Continue'
        next:
          scene:''
      },{
        name:'Exit'
        next:
          scene:''
      }
    ]

基本的にJavaScriptは書かずにRPGが作れるようになるんだけど、json の整理とかあらためてしてるところ…
Windowクラスも作り直したし、いろいろ大変。

Sample

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3