/// <summary> /// パネル交換 /// </summary> public PPPanelBlock SwapPanel(PPPanelBlock block, PlayAreaBlock.Dir dir) { if (block != null && !block.IsLoced() && block.AttachedPanel != null && !block.AttachedPanel.IsDisturbance) { PPPanelBlock target = block.GetLink(dir) as PPPanelBlock; if (target != null && !target.IsLoced() && !target.GetIsUpperBlockFallWait() && (target.AttachedPanel == null || !target.AttachedPanel.IsDisturbance)) { // 対象ブロックを落下中のパネルが通過中ならキャンセル foreach (PPPanel panel in m_UsingPanels) { if (panel.IsFalling()) { if ((block.TestInsideY(panel.transform.position.y, BlockSize) && block.TestInsideX(panel.transform.position.x, BlockSize, false)) || (target.TestInsideY(panel.transform.position.y, BlockSize) && target.TestInsideX(panel.transform.position.x, BlockSize, false))) { return(null); } } } // 交換 PPPanel t = block.AttachedPanel; block.Attach(target.AttachedPanel); target.Attach(t); // スワップ開始 if (block.AttachedPanel != null) { block.AttachedPanel.BeginSwap(block); } if (target.AttachedPanel != null) { target.AttachedPanel.BeginSwap(target); } // 移動先の下が空ブロックなら連鎖無効 PPPanelBlock tempBlock = target.GetLink(PlayAreaBlock.Dir.Down) as PPPanelBlock; if (tempBlock != null && tempBlock.AttachedPanel == null) { target.AttachedPanel.IgnoreChainSource = true; } // 空ブロックとの交換なら移動元から上を連鎖無効 if (block.AttachedPanel == null) { tempBlock = block; while ((tempBlock = tempBlock.GetLink(PlayAreaBlock.Dir.Up) as PPPanelBlock) != null && tempBlock.AttachedPanel != null && !tempBlock.AttachedPanel.IsDisturbance) { tempBlock.AttachedPanel.IgnoreChainSource = true; } } return(target); } } return(null); }
/// <summary> /// 落下中止 /// </summary> private void StopFall(PPPanelBlock fallTarget) { if (m_State == State.Fall) { m_State = State.None; // 連結妨害パネルも落下中止 if (IsDisturbance) { for (int i = 0; i < m_DisturbLinks.Length; i++) { if (m_DisturbLinks[i] != null) { m_DisturbLinks[i].StopFall(fallTarget.GetLink((PlayAreaBlock.Dir)i) as PPPanelBlock); } } } // 落下地点にアタッチ fallTarget.Attach(this, true); // 下の落下待機パネルに連鎖ソースを伝搬 if (m_IsChainSource) { for (int i = 0; i < 2; i++) { PPPanelBlock vertBlock = fallTarget.GetLink(i == 0 ? PlayAreaBlock.Dir.Down : PlayAreaBlock.Dir.Up) as PPPanelBlock; if (vertBlock != null && vertBlock.AttachedPanel != null && vertBlock.AttachedPanel.CurrentState == State.FallReady) { vertBlock.AttachedPanel.m_IsChainSource = true; } } } StopCoroutine(m_PlayingCoroutine); m_PlayingCoroutine = null; } }
/// <summary> /// 落下開始 /// </summary> public void BeginFall(PPPanelBlock startBlock) { if (m_State == State.None) { m_State = State.Fall; // 最下段なら連結妨害パネルも落下 if (IsDisturbance && m_DisturbLinks[(int)PlayAreaBlock.Dir.Down] == null) { if (m_DisturbLinks[(int)PlayAreaBlock.Dir.Left] != null) { m_DisturbLinks[(int)PlayAreaBlock.Dir.Left].BeginFall(startBlock.GetLink(PlayAreaBlock.Dir.Left) as PPPanelBlock); } if (m_DisturbLinks[(int)PlayAreaBlock.Dir.Right] != null) { m_DisturbLinks[(int)PlayAreaBlock.Dir.Right].BeginFall(startBlock.GetLink(PlayAreaBlock.Dir.Right) as PPPanelBlock); } } StartCoroutine(m_PlayingCoroutine = Falling(startBlock)); // 1つ上のパネルも落下 PPPanelBlock upBlock = startBlock.GetLink(PlayAreaBlock.Dir.Up) as PPPanelBlock; if (upBlock != null && !upBlock.IsLoced() && upBlock.AttachedPanel != null && upBlock.AttachedPanel.IsValidFall()) { // 連鎖ソース if (!upBlock.AttachedPanel.IgnoreChainSource) { upBlock.AttachedPanel.m_IsChainSource = true; } upBlock.AttachedPanel.IgnoreChainSource = false; upBlock.AttachedPanel.BeginFall(upBlock); } } }
/// <summary> /// 指定方向に連続した同タイプのパネル数を取得 /// </summary> public int GetMatchPanelCountDir(Dir dir) { int count = 0; if (AttachedPanel != null) { count = 1; PPPanel.Type type = AttachedPanel.PanelType; PPPanelBlock block = this; while ((block = block.GetLink(dir) as PPPanelBlock) != null && block.AttachedPanel != null && block.AttachedPanel.PanelType == type) { ++count; } } return(count); }
/// <summary> /// 落下中 /// </summary> public IEnumerator Falling(PPPanelBlock startBlock) { // 開始地点からデタッチ startBlock.Detach(); PPPanelBlock curBlock = startBlock; PPPanelBlock fallTarget = startBlock; PPPanelBlock bottom = null; while (true) { // 移動 Vector3 move = -Vector3.up * GameManager.TimeStep * PPGame.Config.PanelFallSpeed; transform.position += move; // 移動先を超えたら移動先を再設定 if (transform.position.y <= fallTarget.Position.y) { curBlock = fallTarget; bottom = curBlock.GetLink(PlayAreaBlock.Dir.Down) as PPPanelBlock; if (bottom != null && bottom.AttachedPanel == null) { fallTarget = bottom; } else { transform.position = curBlock.Position; break; } } yield return(null); } StopFall(curBlock); }