// 섬 블록이 모두 모였는지 조사한다. private bool check_ready_to_leave(LeaveBlockControl block, List <LeaveBlockControl> blocks) { bool ready = true; do { if (blocks.Contains(block)) { break; } blocks.Add(block); foreach (Block.iPosition ipos in block.connected_block) { if (!ipos.isValid()) { continue; } LeaveBlockControl next_block = this.waiting_blocks.Find(x => x.i_pos.Equals(ipos)); if (next_block == null) { ready = false; break; } if (!this.check_ready_to_leave(next_block, blocks)) { ready = false; break; } } } while(false); return(ready); }
// 퇴장 연출용 블록을 만든다. public LeaveBlockControl createLeaveBlock(BlockControl block) { GameObject game_object = Instantiate(this.blockPrefab) as GameObject; LeaveBlockControl leave_block = game_object.GetComponent <LeaveBlockControl>(); // leave_block.leave_block_root = this; leave_block.i_pos = block.i_pos; leave_block.transform.position = block.transform.position; leave_block.getModelsRoot().transform.localScale = block.getModelsRoot().transform.localScale; leave_block.getModelsRoot().transform.localPosition = block.getModelsRoot().transform.localPosition; leave_block.getModelsRoot().transform.localRotation = block.getModelsRoot().transform.localRotation; leave_block.setColor(block.color); if (block.color == Block.COLOR.NECO) { leave_block.getNecoMotion()["00_Idle"].time = block.getNekoMotion()["00_Idle"].time; } for (int i = 0; i < (int)Block.DIR4.NUM; i++) { Block.DIR4 dir = (Block.DIR4)i; leave_block.setConnectedBlock(dir, block.getConnectedBlock(dir)); } // 하이어라키 뷰에서 위치를 확인하기 쉽게 블록 좌표를 이름에 붙여 둔다. leave_block.name = "leave_block(" + block.i_pos.x.ToString() + "," + block.i_pos.y.ToString() + ")"; // 섬(같은 색 블록이 서로 이웃한 덩어리) 블록이 // 전부 갖춰질 때까지 기다린다 . this.waiting_blocks.Add(leave_block); return(leave_block); }
// 매 프레임 실행. private void chain_execute() { // 선두 블록. this.chain.velocity += this.chain.move_direction * 4.0f * Time.deltaTime; this.chain.omega += 360.0f * Time.deltaTime; LeaveBlockControl trailer = this.blocks[0]; trailer.transform.Translate(this.chain.velocity * Time.deltaTime); if (trailer.color == Block.COLOR.NECO) { trailer.setNecoRotation(this.chain.velocity); } else { trailer.getModelsRoot().transform.Rotate(Vector3.up, this.chain.omega * Time.deltaTime); } // 2회째 이후의 블록. // 이전 블록에 끌어당겨지듯 이동한다. float omega = this.chain.omega * 0.75f; float prev_velocity = this.chain.velocity.magnitude; for (int i = 1; i < this.blocks.Count; i++) { LeaveBlockControl prev = this.blocks[i - 1]; LeaveBlockControl crnt = this.blocks[i]; // 위치 이동. Vector3 distance_vector = crnt.transform.position - prev.transform.position; float distance_limit = 1.0f; float distance = distance_vector.magnitude; if (distance > distance_limit) { float velocity = prev_velocity + (distance - distance_limit) * 0.1f; if (distance - velocity * Time.deltaTime < distance_limit) { velocity = (distance - distance_limit) / Time.deltaTime; } distance -= velocity * Time.deltaTime; distance_vector.Normalize(); distance_vector *= distance; crnt.transform.position = prev.transform.position + distance_vector; prev_velocity = velocity; } // 회전. if (trailer.color == Block.COLOR.NECO) { crnt.setNecoRotation(-distance_vector); } else { crnt.getModelsRoot().transform.Rotate(Vector3.up, omega * Time.deltaTime); } omega *= 0.75f; } }
// 블록이 퇴장하는 방향을 정한다. private Block.DIR4 select_move_dir(LeaveBlockControl[] children) { Block.DIR4 dir = Block.DIR4.RIGHT; float cx = 0.0f; foreach(LeaveBlockControl block in children) { cx += (float)block.i_pos.x; } cx /= (float)children.Length; if(cx < (float)Block.BLOCK_NUM_X/2) { dir = Block.DIR4.LEFT; } else { dir = Block.DIR4.RIGHT; } return(dir); }
// 섬 블록이 모두 모였는지 조사한다. private bool check_ready_to_leave(LeaveBlockControl block, List<LeaveBlockControl> blocks) { bool ready = true; do { if(blocks.Contains(block)) { break; } blocks.Add(block); foreach(Block.iPosition ipos in block.connected_block) { if(!ipos.isValid()) { continue; } LeaveBlockControl next_block = this.waiting_blocks.Find(x => x.i_pos.Equals(ipos)); if(next_block == null) { ready = false; break; } if(!this.check_ready_to_leave(next_block, blocks)) { ready = false; break; } } } while(false); return(ready); }