/// <summary> /// 落下可能? /// </summary> public bool IsValidFall() { if (IsDisturbance && Block != null) { // 最下段の水平方向の連結妨害パネルブロックを取得 List <PPPanel> links; List <PPPanel> horizontal = new List <PPPanel>(); PPPanel mostUnderDisturb = GetEndDisturb(PlayAreaBlock.Dir.Down); horizontal.Add(mostUnderDisturb); mostUnderDisturb.GetDisturbLinks(out links, PlayAreaBlock.Dir.Left); horizontal.AddRange(links); mostUnderDisturb.GetDisturbLinks(out links, PlayAreaBlock.Dir.Right); horizontal.AddRange(links); // 最下段の連結妨害パネルの直下が空ブロックか調べる foreach (PPPanel disturb in horizontal) { if (disturb.Block != null) { PPPanelBlock underBlock = disturb.Block.GetLink(PlayAreaBlock.Dir.Down) as PPPanelBlock; if (underBlock != null && underBlock.AttachedPanel != null) { return(false); } } } } return(true); }
/// <summary> /// パネルをデタッチ /// </summary> public void Detach() { if (m_Panel != null) { m_Panel.Block = null; m_Panel = null; } }
/// <summary> /// 妨害パネル設定 /// </summary> public void SetDisturbance(PPPanel leftLink, PPPanel rightLink, PPPanel upLink, PPPanel downLink) { IsDisturbance = true; m_DisturbLinks[(int)PlayAreaBlock.Dir.Left] = leftLink; m_DisturbLinks[(int)PlayAreaBlock.Dir.Right] = rightLink; m_DisturbLinks[(int)PlayAreaBlock.Dir.Up] = upLink; m_DisturbLinks[(int)PlayAreaBlock.Dir.Down] = downLink; m_SpriteRenderer.color = Color.gray; }
/// <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> public void GetDisturbLinks(out List <PPPanel> links, PlayAreaBlock.Dir dir) { links = new List <PPPanel>(); PPPanel sidePanel = m_DisturbLinks[(int)dir]; // 隣のパネル while (sidePanel != null) { links.Add(sidePanel); sidePanel = sidePanel.m_DisturbLinks[(int)dir]; // 更に隣のパネル } }
/// <summary> /// パネルをアタッチ /// </summary> public void Attach(PPPanel panel, bool updatePanelPosition = false) { m_Panel = panel; if (m_Panel != null) { m_Panel.Block = this; if (updatePanelPosition) { m_Panel.transform.position = Position; } } }
/// <summary> /// 指定方向の終端の連結妨害パネル取得 /// </summary> private PPPanel GetEndDisturb(PlayAreaBlock.Dir dir) { PPPanel dest = null; if (IsDisturbance) { PPPanel t = this; while (t != null) { dest = t; t = t.m_DisturbLinks[(int)dir]; } } return(dest); }
/// <summary> /// パネルからブロックを取得 /// </summary> private PPPanelBlock GetBlock(PPPanel panel) { if (panel == null) { return(null); } foreach (PPPanelBlock[] line in m_Lines) { foreach (PPPanelBlock block in line) { if (block.AttachedPanel == panel) { return(block); } } } return(null); }
/// <summary> /// パネル除外リクエスト /// </summary> public void RequestRemovePanel(PPPanel panel) { m_PanelRemoveRequests.Add(panel); }
/// <summary> /// 妨害パネル分解 /// </summary> public int Dissolve(int dissolveCount = 0) { if (m_State == State.None && IsDisturbance) { PPPanel bottomRight = null; bottomRight = GetEndDisturb(PlayAreaBlock.Dir.Down); bottomRight = bottomRight.GetEndDisturb(PlayAreaBlock.Dir.Right); // 全連結妨害パネルを取得 List <PPPanel> disturbances = new List <PPPanel>(); List <PPPanelBlock> arounds = new List <PPPanelBlock>(); List <PPPanel> vertical = null; List <PPPanel> horizontal = null; // 右下から上端にかけてのパネル bottomRight.GetDisturbLinks(out vertical, PlayAreaBlock.Dir.Up); vertical.Insert(0, bottomRight); int line = 0; foreach (PPPanel vertPanel in vertical) { // 右端から左端にかけてのパネル vertPanel.GetDisturbLinks(out horizontal, PlayAreaBlock.Dir.Left); horizontal.Insert(0, vertPanel); foreach (PPPanel horizPanel in horizontal) { disturbances.Add(horizPanel); // 水平方向の周囲のブロックを保持 if (line == 0 && horizPanel.Block != null) { arounds.Add(horizPanel.Block.GetLink(PlayAreaBlock.Dir.Down) as PPPanelBlock); } if (line == vertical.Count - 1 && horizPanel.Block != null) { arounds.Add(horizPanel.Block.GetLink(PlayAreaBlock.Dir.Up) as PPPanelBlock); } } // 垂直方向の周囲のブロックを保持 if (horizontal.Count > 0) { if (horizontal[0].Block != null) { arounds.Add(horizontal[0].Block.GetLink(PlayAreaBlock.Dir.Right) as PPPanelBlock); } if (horizontal[horizontal.Count - 1].Block != null) { arounds.Add(horizontal[horizontal.Count - 1].Block.GetLink(PlayAreaBlock.Dir.Left) as PPPanelBlock); } } ++line; } // 全連結妨害パネルを分解準備 int currentCount = 0; foreach (PPPanel panel in disturbances) { if (panel.StandbyDissolve()) { ++currentCount; } } // 連結妨害パネルと接している別の妨害パネルも分解 foreach (PPPanelBlock block in arounds) { if (block != null && block.AttachedPanel != null && block.AttachedPanel.IsDisturbance) { currentCount += block.AttachedPanel.Dissolve(dissolveCount + currentCount); } } // 全連結妨害パネルを分解 float delay = dissolveCount * PPGame.Config.PanelDissolveDelay; float endTime = delay + currentCount * PPGame.Config.PanelDissolveDelay; foreach (PPPanel panel in disturbances) { panel.BeginDissolve(panel.m_DisturbLinks[(int)PlayAreaBlock.Dir.Down] == null, delay, endTime); delay += PPGame.Config.PanelDissolveDelay; } return(currentCount); } return(0); }