Пример #1
0
    /// <summary>
    /// 最下段の空ブロックを取得
    /// </summary>
    public PPPanelBlock GetMostUnderEmptyBlock(ref int depth)
    {
        // 真下にブロックがある
        PPPanelBlock under = GetLink(Dir.Down) as PPPanelBlock;

        if (under != null)
        {
            // 真下が空なら更に下へ
            if (under.AttachedPanel == null)
            {
                ++depth;
                return((GetLink(Dir.Down) as PPPanelBlock).GetMostUnderEmptyBlock(ref depth));
            }
//			// 真下のパネルがロック中
//			else if (under.AttachedPanel.IsLoced())
//			{
//				return null;
//			}
            // 真下にパネルがある
            else
            {
                return(this);
            }
        }
        // 真下にブロックがない
        else
        {
            return(this);
        }
    }
Пример #2
0
    /// <summary>
    /// パネル落下時の通過ブロックを取得
    /// </summary>
    public bool GetFallPassBlock(ref List <PPPanelBlock> blocks)
    {
        // 真下にブロックがある
        PPPanelBlock under = GetLink(Dir.Down) as PPPanelBlock;

        if (under != null)
        {
            // 真下が空なら更に下へ
            if (under.AttachedPanel == null)
            {
                blocks.Add(under);
                return((GetLink(Dir.Down) as PPPanelBlock).GetFallPassBlock(ref blocks));
            }
            // 真下のパネルがロック中
            else if (under.AttachedPanel.IsLocked())
            {
                return(false);                // 落下不可
            }
            // 真下にパネルがある
            else
            {
                return(blocks.Count > 0);
            }
        }
        // 真下にブロックがない
        else
        {
            return(blocks.Count > 0);
        }
    }
Пример #3
0
    /// <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);
    }
Пример #4
0
    /// <summary>
    /// 初期化
    /// </summary>
    public void Initialize(PPPlayArea area, List <Type> ignoreTypes)
    {
        gameObject.SetActive(true);

        m_Area             = area;
        m_Block            = null;
        m_State            = State.None;
        m_Active           = false;
        m_IsChainSource    = false;
        IgnoreChainSource  = false;
        m_PlayingCoroutine = null;

        IsDisturbance = false;
        for (int i = 0; i < m_DisturbLinks.Length; i++)
        {
            m_DisturbLinks[i] = null;
        }

        List <Type> validTypes = new List <Type>();

        for (int i = (int)Type.ColorA; i <= (int)Type.ColorF; i++)
        {
            if (!ignoreTypes.Contains((Type)i))
            {
                validTypes.Add((Type)i);
            }
        }
        m_Type = validTypes[area.Game.Controller.SyncRand.Next(validTypes.Count)];

        m_SpriteRenderer.enabled = true;
        m_SpriteRenderer.sprite  = Resources.Load("PanelDePon/Panel_0" + ((int)m_Type - 1).ToString(), typeof(Sprite)) as Sprite;
        m_SpriteRenderer.color   = Color.gray;
    }
Пример #5
0
 /// <summary>
 /// 交換開始
 /// </summary>
 public void BeginSwap(PPPanelBlock target)
 {
     if (m_State == State.None)
     {
         m_State = State.Move;
         StartCoroutine(m_PlayingCoroutine = Swaping(target));
     }
 }
Пример #6
0
 /// <summary>
 /// 落下待機開始
 /// </summary>
 public void BeginFallReady(PPPanelBlock startBlock)
 {
     if (m_State == State.None)
     {
         m_State = State.FallReady;
         StartCoroutine(m_PlayingCoroutine = FallReady(startBlock));
     }
 }
Пример #7
0
    /// <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);
    }
Пример #8
0
    /// <summary>
    /// パネル入れ替え
    /// </summary>
    private void SwapPanel(PPPanelBlock block, PlayAreaBlock.Dir dir)
    {
        PlayerController.CommandData command = new PlayerController.CommandData();
        command.type   = (byte)PlayerController.CommandType.PP_Swap;
        command.values = new sbyte[2];
        Vector2i grid = (Game as PPGame).PlayArea.GetBlockGrid(block);

        command.values[0] = (sbyte)(grid.y * PPGame.Config.PlayAreaWidth + grid.x);
        command.values[1] = (sbyte)dir;
        SetNextCommand(command);
    }
Пример #9
0
    /// <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);
    }
Пример #10
0
    /// <summary>
    /// ブロックのグリッド座標を取得
    /// </summary>
    public Vector2i GetBlockGrid(PPPanelBlock block)
    {
        for (int y = 0; y < m_Lines.Count; y++)
        {
            for (int x = 0; x < m_Lines[y].Length; x++)
            {
                if (m_Lines[y][x] == block)
                {
                    return(new Vector2i(x, y));
                }
            }
        }

        Debug.LogWarning(block.ToString() + " is not found");
        return(Vector2i.zero);
    }
Пример #11
0
    /// <summary>
    /// 交換中
    /// </summary>
    public IEnumerator Swaping(PPPanelBlock target)
    {
        while (true)
        {
            Vector3 dir  = target.Position - transform.position;
            Vector3 move = dir.normalized * GameManager.TimeStep * PPGame.Config.PanelSwapSpeed;
            transform.position += move;

            if (dir.magnitude - move.magnitude < 0)
            {
                transform.position = target.Position;
                break;
            }

            yield return(null);
        }

        m_State            = State.None;
        m_PlayingCoroutine = null;
    }
Пример #12
0
    /// <summary>
    /// パネル落下
    /// </summary>
    public void FallPanel()
    {
        PPPanelBlock fallTarget = null;

        // 下から2行目から上をチェック
        for (int i = m_Lines.Count - 2; i >= 0; i--)
        {
            foreach (PPPanelBlock block in m_Lines[i])
            {
                if (!block.IsLoced() && block.AttachedPanel != null && block.AttachedPanel.IsValidFall())
                {
                    // 落下地点取得
                    if ((fallTarget = block.GetMostUnderEmptyBlock()) != null && fallTarget != block)
                    {
                        // 落下待機開始
                        block.AttachedPanel.BeginFallReady(block);
                    }
                }
            }
        }
    }
Пример #13
0
    /// <summary>
    /// 落下待機
    /// </summary>
    public IEnumerator FallReady(PPPanelBlock startBlock)
    {
        // 連鎖ソース
        if (!IgnoreChainSource)
        {
            m_IsChainSource = true;
        }
        IgnoreChainSource = false;

        float waitTime = PPGame.Config.PanelFallWaitTime;

        while (waitTime >= 0f)
        {
            waitTime -= GameManager.TimeStep;
            yield return(null);
        }

        m_State            = State.None;
        m_PlayingCoroutine = null;
        BeginFall(startBlock);
    }
Пример #14
0
    /// <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;
        }
    }
Пример #15
0
    /// <summary>
    /// コマンド実行
    /// </summary>
    public override void ExecuteCommand(PlayerController.CommandData command)
    {
        PPPlayArea playArea = (Game as PPGame).PlayArea;

        switch ((PlayerController.CommandType)command.type)
        {
        case PlayerController.CommandType.PP_Swap:
            if (command.values != null)
            {
                Vector2i     grid   = new Vector2i(command.values[0] % PPGame.Config.PlayAreaWidth, command.values[0] / PPGame.Config.PlayAreaWidth);
                PPPanelBlock result = playArea.SwapPanel(playArea.GetBlock(grid), (PlayAreaBlock.Dir)command.values[1]);
                if (result != null)
                {
                    m_TouchedBlock = result;
                }
            }
            break;

        case PlayerController.CommandType.PP_Add:
            playArea.ElevateValue       = PPGame.Config.ManualElevateSpeed;
            playArea.MaxElevateWaitTime = PPGame.Config.ManualElevateInterval;
            playArea.SkipElevateWait();
            break;
        }

        // ダメージ
        DamageTable.DamageData damage = GetDamageData((PlayerController.DamageType)command.damageType, command.damageValue);
        if (damage != null)
        {
            foreach (var disturbData in damage.PPDisturb)
            {
                for (int i = 0; i < disturbData.count; i++)
                {
                    (Game as PPGame).PlayArea.CreateDisturbPanel(disturbData.width, disturbData.height);
                }
            }
        }
    }
Пример #16
0
    /// <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);
    }
Пример #17
0
    /// <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);
            }
        }
    }
Пример #18
0
    /// <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);
    }
Пример #19
0
    /// <summary>
    /// 更新
    /// </summary>
    public override void Play()
    {
        base.Play();

        PPPlayArea playArea = (Game as PPGame).PlayArea;

        if (Input.GetKeyDown(KeyCode.D))
        {
            (Game as PPGame).PlayArea.CreateDisturbPanel(6, 2);
        }

        // タッチした瞬間
        if (InputManager.IsTouchDown())
        {
            // タッチブロック保持
            m_TouchedBlock = playArea.GetBlock(Camera.main.ScreenToWorldPoint(InputManager.GetTouchPosition()));
        }

        // タッチ中
        if (InputManager.IsTouch())
        {
            // せり上げ
            if (InputManager.IsTouchDouble())
            {
                Elevate();
            }
            // 入れ替え
            else if (m_TouchedBlock != null)
            {
                Vector3 worldTouchPos = Camera.main.ScreenToWorldPoint(InputManager.GetTouchPosition());

                // 移動先グリッド
                Vector2i target = playArea.ConvertWorldToGrid(worldTouchPos);
                // 移動元グリッド
                Vector2i current = playArea.GetBlockGrid(m_TouchedBlock);

                if (target != current)
                {
                    Vector2i          dif = target - current;
                    PlayAreaBlock.Dir dir;
                    if (dif.x < 0)
                    {
                        dir = PlayAreaBlock.Dir.Left;
                    }
                    else if (dif.x > 0)
                    {
                        dir = PlayAreaBlock.Dir.Right;
                    }
                    else if (dif.y > 0)
                    {
                        dir = PlayAreaBlock.Dir.Down;
                    }
                    else
                    {
                        dir = PlayAreaBlock.Dir.Up;
                    }

                    // 交換
                    PPPanelBlock targetBlock = playArea.GetBlock(target);
                    Vector3      distance    = targetBlock != null ? targetBlock.Position - worldTouchPos : Vector3.zero;
                    if (targetBlock == null ||
                        ((dir == PlayAreaBlock.Dir.Left || dir == PlayAreaBlock.Dir.Right) && Mathf.Abs(distance.x) < PPGame.Config.PanelSwapStartDistance) ||
                        ((dir == PlayAreaBlock.Dir.Up || dir == PlayAreaBlock.Dir.Down) && Mathf.Abs(distance.y) < PPGame.Config.PanelSwapStartDistance))
                    {
                        SwapPanel(m_TouchedBlock, dir);
                    }
                }
            }
        }
    }
Пример #20
0
    /// <summary>
    /// パネル消滅
    /// </summary>
    private void VanishPanel()
    {
        List <PPPanelBlock> blocks;

        if (GetAllMatchPanelBlocks(out blocks))
        {
            // ソート
            blocks.Sort((a, b) =>
            {
                int dif = (int)Mathf.Ceil(b.Position.y - a.Position.y);
                return(dif != 0 ? dif : (int)Mathf.Ceil(a.Position.x - b.Position.x));
            });

            // 消滅
            float delay            = PPGame.Config.PanelVanishDelay;
            float totalDelay       = delay * blocks.Count;
            bool  existChainSource = false;
            foreach (PPPanelBlock block in blocks)
            {
                if (block.AttachedPanel != null)
                {
                    block.VanishPanel(delay, totalDelay);
                    delay += PPGame.Config.PanelVanishDelay;

                    // 連鎖ソースチェック
                    if (block.AttachedPanel.IsChainSource && block.AttachedPanel.CurrentState != PPPanel.State.FallReady)
                    {
                        existChainSource = true;
                    }

                    // 妨害パネル解凍
                    for (int i = 0; i < block.AllLink.Length; i++)
                    {
                        PPPanelBlock side = block.AllLink[i] as PPPanelBlock;
                        if (side != null && side.AttachedPanel != null && side.AttachedPanel.IsDisturbance)
                        {
                            side.DissolveDisturbance();
                        }
                    }
                }
            }

            // 連鎖カウント
            if (existChainSource)
            {
                ++m_ChainCount;
            }
        }

        // 連鎖ソースフラグを折る
        foreach (PPPanelBlock[] line in m_Lines)
        {
            foreach (PPPanelBlock block in line)
            {
                if (block.AttachedPanel != null)
                {
                    block.AttachedPanel.IsChainSource = false;
                }
            }
        }

        // パネル消滅イベント
        (Game.Player as PPPlayer).OnVanishPanel(blocks.Count);
    }
Пример #21
0
    /// <summary>
    /// 上のパネルが落下待機中?
    /// </summary>
    public bool GetIsUpperBlockFallWait()
    {
        PPPanelBlock upper = GetLink(Dir.Up) as PPPanelBlock;

        return(upper != null && upper.AttachedPanel != null && upper.AttachedPanel.CurrentState == PPPanel.State.FallReady);
    }