コード例 #1
0
ファイル: PlayArea.cs プロジェクト: mujurin1/PanelDePon_WPF
        /* プレイエリアのセルの処理とか
         * 1.ユーザーの操作
         * 2.スクロールする(しないときもある)
         *      ここでせり上がる時に一番上にセルがあればゲームオーバー
         * 3.左下から、右に、上に向かって、セルの状態変化(移動/変化)
         * 4.お邪魔セルの落下
         */
        /// <summary>
        ///   ゲームの状態を1フレーム更新する
        /// </summary>
        /// <param name="userOperation">ユーザーの操作</param>
        private void GameRule(UserOperation userOperation)
        {
            // 移動したセル配列の初期化
            _swapArray = SwapArray.CopyAndReset(null);

            //==============================スクロールする==============================
            // ScrollLine が BorderLine を超えているか?(1段上に上げるか?)
            PushedUp = ScrollLine >= BorderLine;
            // スクロール待機中なら、待機フレーム数を1減らしてスクロールしない
            if (_scrollWaitFrame > 0)
            {
                _scrollWaitFrame--;
            }
            else
            {
                // ゲームオーバーか?
                if (GameOverJudge())
                {
                    return;
                }
                // スクロールする
                ScrollLine += ScrollSpeed;
                if (PushedUp)
                {
                    ScrollLine = 0;
                    // セルを1段上に上げる
                    for (var row = PlayAreaSize.Row - 2; row >= -1; row--)
                    {
                        for (var col = 0; col < PlayAreaSize.Column; col++)
                        {
                            _cellArray[row + 1, col] = CellArray[row, col];
                        }
                    }
                    // カーソルを1段上に上げる
                    var cr = CursorStatus;
                    var mr = cr.Matrix;
                    mr.Row++;   // ホントはここがしたいだけ
                    cr.Matrix    = mr;
                    CursorStatus = cr;
                    // 一番下(Row-1)のセルをランダムに追加する
                    for (int col = 0; col < PlayAreaSize.Column; col++)
                    {
                        var cell = CellArray[-1, col];
                        cell.CellType       = CellInfo.RandomCellType(n: 0);
                        _cellArray[-1, col] = cell;
                    }
                }
            }
            //==============================ユーザーの操作==============================
            switch (userOperation)
            {
            case UserOperation.Swap:      // カーソルの位置のセルを入れ替える
                // カーソルの位置のセルを取得
                var cursorCellL = CellArray[CursorStatus.Matrix.Row, CursorStatus.Matrix.Column];
                var cursorCellR = CellArray[CursorStatus.Matrix.Row, CursorStatus.Matrix.Column + 1];

                // 両方Emptyなら入れ替える必要がないので入れ替えない
                if (cursorCellL.CellType is CellType.Empty && cursorCellR.CellType is CellType.Empty)
                {
                    break;
                }

                // カーソル位置のセルのどちらも移動可能(両方空なら上で弾かれる)
                if (!cursorCellL.CellType.IsOjama() && cursorCellL.Status is CellState.Free &&
                    !cursorCellR.CellType.IsOjama() && cursorCellR.Status is CellState.Free)
                {
                    SwapCell(CursorStatus.Matrix.Row, CursorStatus.Matrix.Column,
                             CursorStatus.Matrix.Row, CursorStatus.Matrix.Column + 1);
                }
                break;

            case UserOperation.ScrollSpeedUp:
                // TODO: スクロール速度が上昇する
                break;

            default:
                break;
            }
            // カーソルの状態を更新する
            CursorStatus = CursorStatus.Update(userOperation);


            //==============================セルの状態を更新する==============================

            /* ・更新順序
             * 1. セルの状態更新
             * 2. 今回のフレームで入れ替わる
             *    (入れ替え or 落下。入れ替わったセルは SwapArray の対応した場所にインデックスが入る)
             * 3. セルの消滅、変身
             *    * 消滅セルを検査する
             *    * 変身するお邪魔セルを検査する
             *    * 消滅、変身するセルの状態をセットする
             */
            //======================セルの状態更新
            //========全てのセルを更新
            for (int row = 0; row < CellArray.Row; row++)
            {
                for (int col = 0; col < CellArray.Column; col++)
                {
                    var cell = CellArray[row, col];
                    cell.Update();
                    _cellArray[row, col] = cell;
                }
            }
            //==========セルの落下
            for (int row = 1; row < CellArray.Row; row++)
            {
                for (int col = 0; col < CellArray.Column; col++)
                {
                    // TODO: お邪魔の落下

                    // 自分のセルが Not(種類:ノーマル or 状態:Free)
                    if (!CellArray[row, col].CellType.IsNomal() || CellArray[row, col].Status is not CellState.Free)
                    {
                        continue;
                    }

                    var bottomCell = CellArray[row - 1, col];
                    // 下のセルが 種類:空 かつ 状態:Free
                    if (bottomCell.CellType is CellType.Empty && bottomCell.Status is CellState.Free)
                    {
                        // 自分と下のセルを入れ替えて、落下を起こす
                        SwapCell(row, col, row - 1, col, isSwap: false);
                    }
                }
            }
            //==========================セルの消滅、変身
            var listD = new List <(int row, int col, CellInfo)>();   // お邪魔。変身するセルを格納する

            var searchAry = new RectangleArray <bool>(PlayAreaSize);
            // 横列走査
            var funcRow = new Func <Matrix, Matrix>(m => { m.Column++; return(m); });

            for (int row = 0; row < searchAry.Row; row++)
            {
                Serch(res: ref searchAry, func: funcRow, beforeCell: CellInfo.Empty, chain: 0, new Matrix(row, 0));
            }
            // 縦列走査
            var funcCol = new Func <Matrix, Matrix>(m => { m.Row++; return(m); });

            for (int col = 0; col < searchAry.Column; col++)
            {
                Serch(res: ref searchAry, func: funcCol, beforeCell: CellInfo.Empty, chain: 0, new Matrix(0, col));
            }


            // TODO: 変身するお邪魔セル走査


            //// 重複を取り除いて、row の降順 col の昇順に並び替え
            //listC = listC.Distinct().OrderByDescending(c => c.row).ThenBy(c => c.col).ToList();

            // 消滅するセルを、消滅するように仕向ける
            int cnt = 0;                        // 消滅セル数    (左上から順番にカウント)
            int sum = searchAry.Count(b => b);  // 消滅セル数合計

            for (int row = searchAry.Row - 1; row >= 0; row--)
            {
                for (int col = 0; col < searchAry.Column; col++)
                {
                    if (!searchAry[row, col])
                    {
                        continue;
                    }
                    var cell = CellArray[row, col];
                    // 状態遷移タイマーのセット
                    cell.StateTimer = (flashTime, cnt *momentTime + 2, (sum - cnt) * momentTime);
                    // セルの状態をフラッシュに
                    cell.Status          = CellState.Flash;
                    _cellArray[row, col] = cell;
                    cnt++;
                }
            }
        }
コード例 #2
0
        /// <summary>プレイエリアを1フレーム分更新する</summary>
        /// <param name="userOperation">ユーザーの操作</param>
        public void InputKey(UserOperation userOperation)
        {
            // 更新時の最初の処理  フレーム1増加
            ElapseFrame++;

            /* ゲームアップデートの順序
             * 1. ユーザーの操作
             *    * カーソル位置移動
             *    * セルの入れ替え
             * 2. スクロール
             *    * IF ちょうど1段上がったなら、
             *      * セルを全て1段上に上げる
             *      * Row:-1 の段にセルを生成する
             *      * カーソルの位置を1段上に上げる
             * 3. セルの状態の更新
             *    1. 全てのセルの状態を更新する
             *       * StateTimer のカウントを減らす
             *    2. セルの落下
             *    3. 消滅するセルの検査
             *       1. 消滅するセルは、StateTiemr をセットする
             *       2. お邪魔とかいろいろ…
             */
            // ユーザーの操作
            _cursorStatus = CursorStatus.Update(userOperation);
            // スクロール
            ScrollLine += 2;                         // スクロールする
            if (PushedUp = ScrollLine >= BorderLine) // ちょうど1段スクロールした
            {
                ScrollLine = 0;                      // スクロールラインを戻す
                s++;
                // 全てのセルを1段上げる
                for (var row = PlayAreaSize.Row - 2; row >= -1; row--)
                {
                    for (var col = 0; col < PlayAreaSize.Column; col++)
                    {
                        _cellArray[row + 1, col] = CellArray[row, col];
                    }
                }
                // カーソルを1段上げる
                // カーソルを1段上に上げる
                var cr = CursorStatus; var mr = cr.Matrix;
                mr.Row++;   // ホントはここがしたいだけ
                cr.Matrix = mr; _cursorStatus = cr;
            }
            ScrollPer        = ScrollLine / BorderLine; // 現在のスクロール割合
            _swapArray[s, 0] = null;
            _swapArray[s, 1] = null;
            // セルの状態更新
            if (B)  // 左から右
            {
                _cellArray[s, 0] = _cellArray[s, 0].Update();
                if (_cellArray[s, 0].StateTimer.Lock == 0)
                {
                    var cell = _cellArray[s, 0];
                    cell.StateTimer  = (0, 0, 10);
                    cell.Status      = CellState.Lock;
                    _cellArray[s, 1] = cell;
                    _swapArray[s, 0] = new(s, 1);
                    B = false;
                }
            }
            else    // 右から左
            {
                _cellArray[s, 1] = _cellArray[s, 1].Update();
                if (_cellArray[s, 1].StateTimer.Lock == 0)
                {
                    var cell = _cellArray[s, 1];
                    cell.StateTimer  = (0, 0, 10);
                    cell.Status      = CellState.Lock;
                    _cellArray[s, 0] = cell;
                    _swapArray[s, 1] = new(s, 0);
                    B = true;
                }
            }

            // 最後に、更新したよ~って言う
            Updated(this, EventArgs.Empty);
        }