/// <summary> /// 空のラインを追加 /// </summary> private void AddEmptyLine(bool insertHead) { MDDropBlock[] line = new MDDropBlock[Width]; Vector3 pos = Vector3.zero; for (int i = 0; i < line.Length; i++) { // ブロック生成 line[i] = new MDDropBlock(); line[i].BaseTransform = m_BlockParent.transform; // 座標登録 pos = Vector3.zero; pos.x = i * BlockSize - (m_Size.x - BlockSize) / 2f; if (insertHead) { pos.y = m_Lines.Count > 0 ? m_Lines[0][0].LocalPosition.y - BlockSize : 0; } else { pos.y = m_Lines.Count > 0 ? m_Lines[m_Lines.Count - 1][0].LocalPosition.y + BlockSize : 0; } line[i].LocalPosition = pos; } // 現在の最上段/最下段の行を取得 PlayAreaBlock[] sideLine = null; if (m_Lines.Count > 0) { sideLine = insertHead ? m_Lines[0] : m_Lines[m_Lines.Count - 1]; } // 隣接するブロックを登録 for (int i = 0; i < line.Length; i++) { if (i < line.Length - 1) { line[i].SetLink(line[i + 1], PlayAreaBlock.Dir.Right); } if (i > 0) { line[i].SetLink(line[i - 1], PlayAreaBlock.Dir.Left); } if (sideLine != null) { line[i].SetLink(sideLine[i], insertHead ? PlayAreaBlock.Dir.Up : PlayAreaBlock.Dir.Down); if (sideLine[i] != null) { sideLine[i].SetLink(line[i], insertHead ? PlayAreaBlock.Dir.Down : PlayAreaBlock.Dir.Up); } } } // 行追加 m_Lines.Insert(insertHead ? 0 : m_Lines.Count, line); }
/// <summary> /// 最下段のドロップがあるブロックを取得 /// </summary> private MDDropBlock GetMostUnderFullBlock(int row, bool ignoreReserve = true) { MDDropBlock block = m_Lines[0][row]; while (block != null && block.AttachedDrop == null && (ignoreReserve || block.ReservedDrop == null)) { block = block.GetLink(PlayAreaBlock.Dir.Up) as MDDropBlock; } return(block); }
/// <summary> /// ラインの範囲外までドロップがある? /// </summary> public bool IsLineOver() { for (int row = 0; row < Width; row++) { MDDropBlock block = GetMostUnderFullBlock(row); if (block != null && !block.AttachedDrop.IsValidVanish && block.AttachedDrop.CurrentState != MDDrop.State.Vanish && block.Position.y <= MinBlockPositionY) { return(true); } } return(false); }
/// <summary> /// ドロップをプル /// </summary> public bool PullDrop(int row) { if (row < 0 || row >= Width || !IsValidPull(row)) { return(false); } int count = 0; // 最下段のドロップがあるブロックを取得 MDDropBlock block = GetMostUnderFullBlock(row, false); if (block != null) { MDDrop drop = null; while (block != null && block.IsAttachOrReserved) { bool reserveDrop = block.ReservedDrop != null; drop = reserveDrop ? block.ReservedDrop : block.AttachedDrop; if ((!drop.IsLocked() || reserveDrop) && (m_PulledDrop.Count == 0 || drop.DropType == m_PulledDrop[0].DropType)) { if (reserveDrop) { drop.CancelState(); block.CancelReserve(); } else { block.Detach(); } drop.BeginPull(Game.Player as MDPlayer); m_PulledDrop.Add(drop); block = block.GetLink(PlayAreaBlock.Dir.Up) as MDDropBlock; ++count; } else { break; } } } return(count > 0); }
/// <summary> /// ドロップを詰める /// </summary> public void CloseDrop() { MDDropBlock emptyBlock = null; MDDrop drop = null; // 奥からチェック for (int i = m_Lines.Count - 1; i >= 0; i--) { foreach (MDDropBlock block in m_Lines[i]) { if (block.ReservedDrop != null || (block.AttachedDrop != null && block.AttachedDrop.CurrentState != MDDrop.State.Vanish)) { // 上方向の空ブロック取得 emptyBlock = block.GetFarthestEmptyBlock(PlayAreaBlock.Dir.Up); // 空ブロックを予約 if (emptyBlock != null) { // アタッチされてたドロップ if (block.AttachedDrop != null) { drop = block.AttachedDrop; block.Detach(); emptyBlock.Reserve(drop); drop.IsValidVanish = true; // 上詰め開始 drop.BeginClose(); } // 予約されてたドロップ else { drop = block.ReservedDrop; block.CancelReserve(); emptyBlock.Reserve(drop); } } } } } }
/// <summary> /// ドロップをプッシュ /// </summary> public void PushDrop(int row) { if (row < 0 || row >= Width || !IsValidPush()) { return; } // 最下段のドロップがあるブロックの下のブロックを取得 MDDropBlock block = GetMostUnderFullBlock(row, false); block = block == null ? m_Lines[m_Lines.Count - 1][row] : block.GetLink(PlayAreaBlock.Dir.Down) as MDDropBlock; for (int i = 0; i < m_PulledDrop.Count; i++) { // ターゲットブロックが無ければ空のラインを追加 if (block == null) { AddEmptyLine(true); block = m_Lines[0][row]; } // 消滅可能 m_PulledDrop[i].IsValidVanish = true; // プッシュ登録 m_PulledDrop[i].IsPushed = true; // 即座に消えるプッシュ m_PulledDrop[i].IsMatchPushed = m_PulledDrop.Count >= MDGame.Config.MinVanishMatchCount; // 予約 block.Reserve(m_PulledDrop[i]); // プッシュ m_PushingDrops.Add(m_PulledDrop[i]); m_PulledDrop[i].BeginPush(Game.Player.transform.position + Vector3.down * i * BlockSize); block = block.GetLink(PlayAreaBlock.Dir.Down) as MDDropBlock; } m_PulledDrop.Clear(); }