示例#1
0
 public PlayArea(int row, int col)
 {
     this.PlayAreaSize = new Matrix(row, col);
     // セルの存在する2次元配列
     // rows(縦列)はお邪魔が降って来て画面上範囲外にセルが存在するので、1.5倍にして、
     //        一番下はせり上がる列なので更に+1
     this._cellArray = new RectangleArray <CellInfo>((int)(row * 1.5) + 1, col);
     this._swapArray = new RectangleArray <Matrix?>(CellArray.Row, CellArray.Column);
     // カーソルは最上段に行けない
     this.CursorStatus = new CursorStatus(PlayAreaSize.Row - 1, PlayAreaSize.Column - 1);
     PlayAreaInit();
 }
 public TestPlayAreaServie()
 {
     // 固定値
     this._playAreaSize = new Matrix(12, 6);
     this.BorderLine    = 100;
     // 更新ごとに変動  簡単な値の変化
     this.ElapseFrame = 0;
     this.ScrollLine  = 0;
     this.ScrollPer   = 0;
     // 更新ごとに変動  大事な値
     this._cellArray             = new RectangleArray <CellInfo>(18, 6);
     this._cursorStatus          = new CursorStatus(PlayAreaSize.Row, PlayAreaSize.Column - 1);
     _cursorStatus.Matrix.Row    = 0;
     _cursorStatus.Matrix.Column = 0;
     this._swapArray             = new RectangleArray <Matrix?>(CellArray.Matrix);
     // セルの初期化
     _cellArray[0, 0] = RedCell;
 }
示例#3
0
        /// <summary>
        ///   <para>プレイエリアの状態を初期化する</para>
        /// </summary>
        private void PlayAreaInit()
        {
            // カーソル位置を初期化
            var cursor = CursorStatus;

            cursor.Matrix.Row    = 0;
            cursor.Matrix.Column = 0;
            CursorStatus         = cursor;
            // セルの配置を初期化する
            _cellArray = CellArray.CopyAndReset(CellInfo.Empty);
            for (int row = -1; row <= 5; row++)
            {
                for (int col = 0; col < PlayAreaSize.Column; col++)
                {
                    var cell = CellArray[row, col];
                    cell.CellType        = CellInfo.RandomCellType(n: -1);
                    _cellArray[row, col] = cell;
                }
            }
            //==============================Debug用
            //// 一番下(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;
            //}
            //==============================Debug用 ここまで

            //var ojama = new CellInfo {
            //    CellType = CellType.Ojama,
            //};

            // スクロール位置の初期化
            ScrollLine = 0;

            // スクロール速度の初期化
            // せり上がっている今の高さの初期化
            // (まだフィールドすら無いけど)お邪魔の初期化
        }
示例#4
0
        /// <summary>
        ///   繋がっているかを検査する
        /// </summary>
        /// <param name="res">結果</param>
        /// <param name="func">Row,Columnの値を増やすデリゲート</param>
        /// <param name="beforeType">1つ前に検査したセルの種類</param>
        /// <param name="chain">1つ前の連鎖数</param>
        /// <param name="now">今回調べる位置</param>
        /// <returns>3つ以上の繋がっているうちの1つだった</returns>
        bool Serch(ref RectangleArray <bool> res, Func <Matrix, Matrix> func, CellInfo beforeCell, int chain, Matrix now)
        {
            // 今回調べるセル
            var nowCell = CellArray[now];

            // 前回のセル or 今回のセルが消滅に使えない または 今回調べるセルと違うタイプ or
            if (!beforeCell.IsEliminatable || !nowCell.IsEliminatable || nowCell.CellType != beforeCell.CellType)
            {
                chain = 1;
            }
            else
            {
                chain++;
            }

            var next    = func(now);
            var isChain = false;

            if (next.Row < res.Row && next.Column < res.Column)
            {
                isChain = Serch(ref res, func, nowCell, chain, next);
            }
            else
            if (chain >= 3)
            {
                isChain = true;     // return res[now] = true; 確定
            }
            if (isChain || chain >= 3)
            {
                res[now] = isChain = true;
            }
            else
            {
                res[now] = res[now] || false;
            }
            return(chain > 1 && isChain);
        }
示例#5
0
        /* プレイエリアのセルの処理とか
         * 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++;
                }
            }
        }