/// <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 PPPanelBlock[] AddNewLine(bool empty, bool insertHead, List <int> emptyRow = null) { // 現在の最上段/最下段の行を取得 PPPanelBlock[] sideLine = null; if (m_Lines.Count > 0) { sideLine = insertHead ? m_Lines[0] : m_Lines[m_Lines.Count - 1]; } PPPanelBlock[] line = new PPPanelBlock[Width]; PPPanel panel; PPPanelBlock block; Vector3 pos; List <PPPanel.Type> ignoreTypes = new List <PPPanel.Type>(); // パネル生成 for (int i = 0; i < line.Length; i++) { // ブロック生成 block = new PPPanelBlock(); block.BaseTransform = m_BlockParent.transform; // 座標登録 pos = Vector3.zero; pos.x = i * BlockSize - m_Size.x / 2f + BlockHalfSize; pos.y = sideLine != null ? sideLine[0].LocalPosition.y + (BlockSize * (insertHead ? 1 : -1)) : 0; block.LocalPosition = pos; // パネル作成 if (!empty && (emptyRow == null || !emptyRow.Contains(i))) { // 使わなくなったパネルを再利用 if (m_UnusedPanels.Count > 0) { panel = m_UnusedPanels[0]; m_UnusedPanels.RemoveAt(0); } // パネル生成 else { panel = Instantiate(PanelTemplate).GetComponent <PPPanel>(); panel.gameObject.transform.SetParent(m_BlockParent.transform, false); m_Panels.Add(panel); } // 無効タイプ設定のため左側だけ接続 if (i > 0) { block.SetLink(line[i - 1], PlayAreaBlock.Dir.Left); } // 無効タイプ設定 ignoreTypes.Clear(); if (i > 0 && line[i - 1].GetMatchPanelCountDir(PlayAreaBlock.Dir.Left) >= PPGame.Config.MinVanishMatchCount - 1) { ignoreTypes.Add(line[i - 1].AttachedPanel.PanelType); } if (!insertHead && sideLine != null && sideLine[i].GetMatchPanelCountDir(PlayAreaBlock.Dir.Up) >= PPGame.Config.MinVanishMatchCount - 1) { ignoreTypes.Add(sideLine[i].AttachedPanel.PanelType); } // パネル初期化 panel.Initialize(this, ignoreTypes); if (insertHead) { panel.Activate(); } block.Attach(panel, true); m_UsingPanels.Add(panel); } line[i] = block; } // 隣接するブロックを登録 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.Down : PlayAreaBlock.Dir.Up); if (sideLine[i] != null) { sideLine[i].SetLink(line[i], insertHead ? PlayAreaBlock.Dir.Up : PlayAreaBlock.Dir.Down); if (!insertHead && sideLine[i].AttachedPanel != null) { sideLine[i].AttachedPanel.Activate(); } } } } // 行を追加 if (insertHead) { m_Lines.Insert(0, line); } else { m_Lines.Add(line); } return(line); }