// 레벨 생성 Kazuhisa Minato. public void generateLevel(int seed) { if(this.levelGenerator == null) { this.random_plant = PseudoRandom.get().createPlant("MapCreator", 100); // ---------------------------------------------------------------- // // 난수 설정을 생성자에서 한다. this.levelGenerator = new FieldGenerator (seed); // 필드 생성방법. // 필드의 w, h는 2이상. // 블록의 w, h는 5이상 그리고 홀수라는 제한이 있다.. // 홀수열의 그리드 폭은 제로로 해석할 필요가 있다. this.levelGenerator.SetSize (ROOM_ROWS_NUM, ROOM_COLUMNS_NUM, BLOCK_ROWS_NUM, BLOCK_COLUMNS_NUM); // 필드를 생성. // 각 요소가 블록인 2차원 배열을 생성한다. // 따라서 블록(i,j)에는 return_value[i,j]로 액세스 하고. // 블록(i,j)안의 요소(u,v)에는 return_value[i,j][u,v]로 액세스한다. var levelData = levelGenerator.CreateField(); // FieldGenerator 출력을 정렬한다. // ・[z, x] -> [x, z]. // ・위가 z = 0 -> 아래가 z = 0. this.level_data = new FieldGenerator.ChipType[ROOM_COLUMNS_NUM, ROOM_ROWS_NUM][,]; foreach(var ri in Map.RoomIndex.getRange(ROOM_COLUMNS_NUM, ROOM_ROWS_NUM)) { this.level_data[ri.x, ri.z] = new FieldGenerator.ChipType[BLOCK_COLUMNS_NUM, BLOCK_ROWS_NUM]; foreach(var bi in Map.BlockIndex.getRange(this.block_columns_num, this.block_rows_num)) { this.level_data[ri.x, ri.z][bi.x, bi.z] = levelData[ROOM_ROWS_NUM - 1 - ri.z, ri.x][BLOCK_ROWS_NUM - 1 - bi.z, bi.x]; } } // 시작, 목표. var ep = levelGenerator.GetEndPoints(levelData); this.start.room_index.x = ep[0].fieldWidth; this.start.room_index.z = ROOM_ROWS_NUM - 1 - ep[0].fieldHeight; this.start.block_index.x = (ep[0].blockWidth - 1)/2; this.start.block_index.z = this.block_grid_rows_num - 1 - (ep[0].blockHeight - 1)/2; this.goal.room_index.x = ep[1].fieldWidth; this.goal.room_index.z = ROOM_ROWS_NUM - 1 - ep[1].fieldHeight; this.goal.block_index.x = (ep[1].blockWidth - 1)/2; this.goal.block_index.z = this.block_grid_rows_num - 1 - (ep[1].blockHeight - 1)/2; // // ---------------------------------------------------------------- // // 방을 만든다. this.floor_root_go = new GameObject("Floor"); foreach(var room_index in Map.RoomIndex.getRange(ROOM_COLUMNS_NUM, ROOM_ROWS_NUM)) { this.createRoom(room_index); } // 더미인 방. // (플로어의 가장 아래 열). for(int i = 0;i < ROOM_COLUMNS_NUM;i++) { this.createVacancy(new Map.RoomIndex(i, -1)); } // 방 칸막이 생성. this.createRoomWall(); this.createOuterWalls(); // ---------------------------------------------------------------- // // 플로어 위에 둘 것(문, 아이템 등) 정보를 만들어 둔다. // 방 이동 문. this.block_infos = new MapCreator.BlockInfo[ROOM_COLUMNS_NUM, ROOM_ROWS_NUM][,]; foreach(var ri in Map.RoomIndex.getRange(ROOM_COLUMNS_NUM, ROOM_ROWS_NUM)) { this.block_infos[ri.x, ri.z] = new BlockInfo[this.block_grid_columns_num, this.block_grid_rows_num]; var block_info_room = this.block_infos[ri.x, ri.z]; var level_data_room = this.level_data[ri.x, ri.z]; foreach(var bi in Map.BlockIndex.getRange(this.block_grid_columns_num, this.block_grid_rows_num)) { block_info_room[bi.x, bi.z].chip = Map.CHIP.VACANT; if(level_data_room[bi.x*2 + 1 - 1, bi.z*2 + 1] == FieldGenerator.ChipType.Door) { block_info_room[bi.x, bi.z].chip = Map.CHIP.DOOR; block_info_room[bi.x, bi.z].option0 = (int)Map.EWSN.WEST; } else if(level_data_room[bi.x*2 + 1 + 1, bi.z*2 + 1] == FieldGenerator.ChipType.Door) { block_info_room[bi.x, bi.z].chip = Map.CHIP.DOOR; block_info_room[bi.x, bi.z].option0 = (int)Map.EWSN.EAST; } else if(level_data_room[bi.x*2 + 1, bi.z*2 + 1 - 1] == FieldGenerator.ChipType.Door) { block_info_room[bi.x, bi.z].chip = Map.CHIP.DOOR; block_info_room[bi.x, bi.z].option0 = (int)Map.EWSN.SOUTH; } else if(level_data_room[bi.x*2 + 1, bi.z*2 + 1 + 1] == FieldGenerator.ChipType.Door) { block_info_room[bi.x, bi.z].chip = Map.CHIP.DOOR; block_info_room[bi.x, bi.z].option0 = (int)Map.EWSN.NORTH; } } } // 플로어 이동 문. this.block_infos[this.start.room_index.x, this.start.room_index.z][this.start.block_index.x, this.start.block_index.z].chip = Map.CHIP.STAIRS; this.block_infos[this.start.room_index.x, this.start.room_index.z][this.start.block_index.x, this.start.block_index.z].option0 = 0; this.block_infos[this.goal.room_index.x, this.goal.room_index.z][this.goal.block_index.x, this.goal.block_index.z].chip = Map.CHIP.STAIRS; this.block_infos[this.goal.room_index.x, this.goal.room_index.z][this.goal.block_index.x, this.goal.block_index.z].option0 = 1; foreach(var ri in Map.RoomIndex.getRange(ROOM_COLUMNS_NUM, ROOM_ROWS_NUM)) { var info_room = this.block_infos[ri.x, ri.z]; RoomController room = this.get_room_root_go(ri); List<Map.BlockIndex> reserves = new List<Map.BlockIndex>(); // ジェネレーター. for(int i = 0;i < 3;i++) { var lair_places = this.allocateChipPlacesRoom(ri, Map.CHIP.LAIR, 1); if(lair_places.Count == 0) { break; } // 제네레이터가 이웃한 블록에 나오지 않게. // 주위 8블록을 예약해 둔다. Map.BlockIndex bi = lair_places[0]; foreach(var around in bi.getArounds8()) { if(this.allocateChipPlaceRoom(ri, around, Map.CHIP.LAIR)) { reserves.Add(around); } } } // 예약한 블록을 반환한다. foreach(var reserve in reserves) { this.putbackChipPlaceRoom(ri, reserve); } // 방 이동 열쇠. var key_places = this.allocateChipPlacesRoom(ri, Map.CHIP.KEY, room.getDoorCount()); for(int i = 0;i < key_places.Count;i++) { Map.BlockIndex place = key_places[i]; info_room[place.x, place.z].option0 = (int)room.getDoorByIndex(i).KeyType; } } // 플로어 이동 문의 열쇠. bool floor_key_created = false; for(int i = 0;i < ROOM_COLUMNS_NUM*ROOM_ROWS_NUM;i++) { Map.RoomIndex ri = new Map.RoomIndex(); ri.x = this.random_plant.getRandomInt(ROOM_COLUMNS_NUM); ri.z = this.random_plant.getRandomInt(ROOM_ROWS_NUM); var floor_key_places = this.allocateChipPlacesRoom(ri, Map.CHIP.KEY, 1); if(floor_key_places.Count == 0) { continue; } this.block_infos[ri.x, ri.z][floor_key_places[0].x, floor_key_places[0].z].option0 = (int)Item.KEY_COLOR.PURPLE; floor_key_created = true; break; } if(!floor_key_created) { Debug.LogError("can't create floor key."); } // ---------------------------------------------------------------- // } }