ダンジョン生成してみよう〜前回の続き〜

ayumegu(プログラマー)
よろしくお願いします。

こんにちは、あゆめぐです。
先週はは前回のダンジョン生成をさらにちょっと作り込んでみただけです。
あんまり進んでいないね;w;

ダンジョン生成

追加したこと

  • ダンジョン生成のアルゴリズム修正
  • キャラクターの動きをターンで動かすように
  • キャラクターの動きを斜め移動できるようにした
  • ミニマップの追加

ミニマップのしくみ

ミニマップ実装方法

ミニマップてきなものの実装方法は、私が思いつくだけでも下記パターン。

  • 今回のように別カメラで別のものを表示させる(ダンジョン系にぴったり)
  • 別のカメラで上からとる(そのままのものが移るだけ)
  • 別のカメラで上からとり、ミニマップに表示するものと本体を別のレイヤーにしてカメラに映るものを変える(MMOなどのミニマップみたくしたいなら)

他に、テクスチャにカメラの映像を描画する(RenderTextureはproのみ)こともできるので、カメラの形のままの四角いやでしたらこれを使えば丸くしたりできるのではないだろうか・・・。まだやったことないので時間があるときにやってみよう。

ミニマップ実装

ミニマップはキャラクターの位置から前後左右1マスを表示するようにしています。
また、部屋に入ったときは部屋をすべて一気に表示するようにしました。

ミニマップはカメラをもう一つ追加して表示させています。

ミニマップのGameObjectはすべてMiniMapというLayerにしています。
MiniMapCameraで必要な設定は、inspacterの

  • Depthをメインカメラよ前の数値に(MainCameraが-1なので0を指定)
  • Clear FlagsをDon’t Clearに設定
  • ProjectionをOrthgraphicに設定
  • Culling Mask MiniMapのみチェックする

MainCameraのinspectorの

  • Culling Mask からMiniMapのチェックを外す


MiniMapObject.js
現在のMiniMapの実装部分
実装途中のだから・・・察してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
var miniMapTileSize:float;
var miniMapObjList:Array;
var minMapWidth:int;
var minMapHeight:int;
var player:GameObject;
var playerShowSize:int;
private var _dungeon:Dungeon;

function Start () {
  miniMapTileSize = 0.195;
  miniMapObjList = new Array();
  playerShowSize = 1;
}

function Update () {

}

function SetData(dungeon:Dungeon){
  _dungeon = dungeon;
  minMapWidth  = dungeon.mapWidth;
  minMapHeight = dungeon.mapHeight;
  for(var y:int = 0; y < dungeon.mapHeight; y++){
      for(var x:int = 0; x < dungeon.mapWidth; x++){
          var tile:DungeonTileData = dungeon.GetTileData(x,y);
          var tileObj:GameObject = Instantiate(Resources.Load("Prefabs/MiniMap"));
          tileObj.transform.parent = this.gameObject.transform;
          tileObj.name = "Tile" + x + y;
          
          tileObj.transform.position.x = x * miniMapTileSize;
          tileObj.transform.position.y = y * miniMapTileSize;
          
          if(tile.isWall){
              tileObj.GetComponent(tk2dSprite).spriteId = 3;
          }else if(tile.isRoom){
              if(tile.isStepUp){
                  tileObj.GetComponent(tk2dSprite).spriteId = 4;
              }else if(tile.isStepDown){
                  tileObj.GetComponent(tk2dSprite).spriteId = 4;
              }else{
                  tileObj.GetComponent(tk2dSprite).spriteId = 2;
              }
          }else{
              tileObj.GetComponent(tk2dSprite).spriteId = 1;
          }
          tileObj.SetActive(false);
          miniMapObjList[x + y * dungeon.mapWidth] = tileObj;
      }
  }
  
  player = Instantiate(Resources.Load("Prefabs/MiniMap"));
  player.GetComponent(tk2dSprite).spriteId = 0;
  player.transform.parent = this.gameObject.transform;
  player.name = "player";
}

function GetTile(x:int, y:int):GameObject{
  if(x < 0 || y < 0 || x >= minMapWidth || y >= minMapHeight){
      return null;
  }
  return miniMapObjList[x + y * minMapWidth];
}

function SetPlayer(pos:Vector2){
  player.transform.position.x = pos.x * miniMapTileSize;
  player.transform.position.y = pos.y * miniMapTileSize;
  ShowMap(pos);
}

// playerの近くのマップを表示する
function ShowMap(pos:Vector2):void{
  
  var minMap:GameObject = GetTile(pos.x,pos.y);
  
  // 部屋に入った場合、部屋のマップを一気に表示する
  var tile:DungeonTileData = _dungeon.GetTileData(pos.x, pos.y);
  if(tile.isRoom){
      var roomNo:int = tile.roomNo;
      var rect:DungeonRect = _dungeon.tileRectList[roomNo];
      for(var y:int = rect.room_top - 1; y < rect.room_bottom + 1; y++){
          for(var x:int = rect.room_left - 1; x < rect.room_right + 1; x++){
              tile = _dungeon.GetTileData(x,y);
              if(tile != null){
                  minMap = GetTile(x,y);
                  minMap.SetActive(true);
              }
          }
      }
  }
  
  for(x = pos.x - playerShowSize; x < pos.x + playerShowSize + 1; x++){
      for(y = pos.y - playerShowSize; y < pos.y + playerShowSize + 1; y++){
          minMap = GetTile(x,y);
          if(minMap != null){
              minMap.SetActive(true);
          }
      }
  }
}

前回のダンジョンクラスからちょっとカスタマイズしてDungeonTileDataにroomNoを追加しました。
ここに区画のリストの番号をセットすることで部屋に入ったときにマップ全体をループしなくてもいいようにしました。
マップが大きくなると全部調べるのは時間かかっちゃいそうだしね。

ダンジョン生成まわり

ちょっと迷走中。 道がいまいち美しくない!
道をふやして、かつ道の作成ルールを変えてバリエーションを増やした。
そしたら道に2*2などの部屋みたくなってしまう場所ができてしまうように!!

そのままでもいいのだけれどちょっときになるから取り除きたいな〜と思っているところであります。
あとはこの作り方だと部屋の数が物足りないな〜っていう気もする

今回の感想

ちなみにキャプチャをとって記事を書く間に現在はこの状態になっている
ダンジョン生成

敵を置いてアイテムを置いただけ。敵はまだ動かないし、戦ったりもせずするーして通り過ぎていく。
トランジション?の追加とピンチイン、アウトの実装テストを組み込んでみた。ほかはおまけ。
いろいろ実装途中ですが・・・。

現在は、敵とプレイヤーも自動で動かしたいからちょっとファジー理論とかをかじってみようと思って本を読んでみているのですが、ぺらぺらみているだけでも後半の方の数式がヤバい!意味がわからないです。
こんなところでシグマ先輩に出会うとは!
私はそっと本を閉じた・・・。
世の中にシグマと微分積分理解している人ってどれくらいいるんだろう・・・。
私って落ちこぼれ!?

トランジションの所は新しいアセットを購入してしまったので次のときにでも記事にしてみようかなと思います。

それでは今回はこの辺で