Example #1
0
        public void Perform()
        {
            DDUtils.SetMouseDispMode(false);
            DDEngine.FreezeInput(10);

            double x     = DDConsts.Screen_W / 2;
            double y     = DDConsts.Screen_H / 2;
            double speed = SPEED_DEF;

            for (; ;)
            {
                DDMouse.UpdateMove();

                x += DDMouse.MoveX * speed;
                y += DDMouse.MoveY * speed;

                DDUtils.ToRange(ref x, 0, DDConsts.Screen_W - 1);
                DDUtils.ToRange(ref y, 0, DDConsts.Screen_H - 1);

                int ix = DoubleTools.ToInt(x);
                int iy = DoubleTools.ToInt(y);

                if (DDKey.IsPound(DX.KEY_INPUT_Z))
                {
                    speed += SPEED_CHANGE_STEP;
                }

                if (DDKey.IsPound(DX.KEY_INPUT_X))
                {
                    speed -= SPEED_CHANGE_STEP;
                }

                DDUtils.ToRange(ref speed, SPEED_MIN, SPEED_MAX);

                if (DDMouse.L.GetInput() == -1)
                {
                    break;
                }

                DDCurtain.DrawCurtain();

                DDPrint.SetPrint(0, 0, 24);
                DDPrint.PrintLine("★マウスカーソルを奪う");
                DDPrint.PrintLine("X=" + x.ToString("F3"));
                DDPrint.PrintLine("Y=" + y.ToString("F3"));
                DDPrint.PrintLine("Speed=" + speed);
                DDPrint.PrintLine("左クリックでメニューに戻る。");
                DDPrint.PrintLine("Zキー:速度上げ");
                DDPrint.PrintLine("Xキー:速度下げ");

                DDDraw.SetBright(new I3Color(255, 128, 0));
                DDDraw.DrawRect(DDGround.GeneralResource.WhiteBox, ix, iy - CROSS_WH / 2, 1, CROSS_WH);
                DDDraw.DrawRect(DDGround.GeneralResource.WhiteBox, ix - CROSS_WH / 2, iy, CROSS_WH, 1);
                DDDraw.Reset();

                DDEngine.EachFrame();
            }
            DDUtils.SetMouseDispMode(true);
        }
Example #2
0
        private void EditMode()
        {
            DDEngine.FreezeInput();
            DDUtils.SetMouseDispMode(true);

            for (; ;)
            {
                int lastMouseX = DDMouse.X;
                int lastMouseY = DDMouse.Y;

                DDMouse.UpdatePos();

                if (DDKey.GetInput(DX.KEY_INPUT_E) == 1)
                {
                    break;
                }

                if (1 <= DDKey.GetInput(DX.KEY_INPUT_LSHIFT) || 1 <= DDKey.GetInput(DX.KEY_INPUT_RSHIFT))                 // シフト押下 -> 移動モード
                {
                    if (1 <= DDMouse.L.GetInput())
                    {
                        DDGround.Camera.X -= DDMouse.X - lastMouseX;
                        DDGround.Camera.Y -= DDMouse.Y - lastMouseY;

                        DDUtils.ToRange(ref DDGround.Camera.X, 0.0, this.Map.W * MapTile.WH - DDConsts.Screen_W);
                        DDUtils.ToRange(ref DDGround.Camera.Y, 0.0, this.Map.H * MapTile.WH - DDConsts.Screen_H);

                        DDGround.ICamera.X = DoubleTools.ToInt(DDGround.Camera.X);
                        DDGround.ICamera.Y = DoubleTools.ToInt(DDGround.Camera.Y);
                    }
                }
                else                 // 編集モード
                {
                    GameEdit.EachFrame();
                }

                DrawWall();

                if (GameEdit.DisplayTileFlag)
                {
                    DrawMap();
                }

                GameEdit.Draw();

                DDEngine.EachFrame();
            }
            DDEngine.FreezeInput();
            DDUtils.SetMouseDispMode(false);
        }
Example #3
0
        // <---- prm

        /// <summary>
        /// コマンドを実行する。
        /// true を返すことによって、次のフレームに送る。(次のフレームまで待つ)
        /// false を返すことによって、現在のフレームにおいて次のコマンドが呼び出される。
        /// -- 連続する「最初に false を返す」コマンド列は1フレームで実行される。
        /// </summary>
        /// <returns>このコマンドを継続するか</returns>
        public IEnumerable <bool> Perform()
        {
            if (this.Tokens[0] == "P")             // PAUSE (入力待ち)
            {
                DDEngine.FreezeInput(5);           // HACK: 要調整

                for (; ;)
                {
                    if (1 <= DDKey.GetInput(DX.KEY_INPUT_LCONTROL))                     // ? 左コントロール_ホールド中
                    {
                        break;
                    }

                    if (1 <= DDInput.L.GetInput())                     // ? 会話スキップ_ホールド中
                    {
                        break;
                    }

                    if (DDInput.A.GetInput() == 1)                     // ? 決定_押下
                    {
                        break;
                    }

                    if (DDInput.B.GetInput() == 1)                     // ? キャンセル_押下
                    {
                        break;
                    }

                    yield return(true);                    // 次のフレームに送る。
                }
            }
            else if (this.Tokens[1] == "=")
            {
                string instanceName = this.Tokens[0];
                string typeName     = this.Tokens[2];

                Game.I.SurfaceManager.Add(SurfaceCreator.Create(typeName, instanceName));
            }
            else
            {
                string   name      = this.Tokens[0];
                string   command   = this.Tokens[1];
                string[] arguments = this.Tokens.Skip(2).ToArray();

                Game.I.SurfaceManager.GetSurface(name).Invoke(command, arguments);
            }
        }
Example #4
0
        public void Test01()
        {
            for (; ;)
            {
                DDCurtain.DrawCurtain();

                DDPrint.SetPrint(); DDPrint.Print("RETURN ==> " + DDKey.GetInput(DX.KEY_INPUT_RETURN));
                DDPrint.PrintRet(); DDPrint.Print("SPACE  ==> " + DDKey.GetInput(DX.KEY_INPUT_SPACE));
                DDPrint.PrintRet(); DDPrint.Print("Z      ==> " + DDKey.GetInput(DX.KEY_INPUT_Z));
                DDPrint.PrintRet(); DDPrint.Print("X      ==> " + DDKey.GetInput(DX.KEY_INPUT_X));
                DDPrint.PrintRet(); DDPrint.Print("DIR_4  ==> " + DDKey.GetInput(DX.KEY_INPUT_LEFT));
                DDPrint.PrintRet(); DDPrint.Print("DIR_6  ==> " + DDKey.GetInput(DX.KEY_INPUT_RIGHT));
                DDPrint.PrintRet(); DDPrint.Print("DIR_8  ==> " + DDKey.GetInput(DX.KEY_INPUT_UP));
                DDPrint.PrintRet(); DDPrint.Print("DIR_2  ==> " + DDKey.GetInput(DX.KEY_INPUT_DOWN));

                DDEngine.EachFrame();
            }
        }
Example #5
0
        public void Perform()
        {
            Func <bool> f_ゴミ回収 = SCommon.Supplier(this.E_ゴミ回収());

            this.Map = new Map(GameCommon.GetMapFile(this.World.GetCurrMapName()));
            this.ReloadEnemies();

            // デフォルトの「プレイヤーのスタート地点」
            // -- マップの中央
            this.Player.X = this.Map.W * GameConsts.TILE_W / 2.0;
            this.Player.Y = this.Map.H * GameConsts.TILE_H / 2.0;

            {
                Enemy enemy = this.Enemies.Iterate().FirstOrDefault(v => v is Enemy_スタート地点 && ((Enemy_スタート地点)v).Direction == this.Status.StartPointDirection);

                if (enemy != null)
                {
                    this.Player.X = enemy.X;
                    this.Player.Y = enemy.Y;
                }
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ入場時)
            // その他の反映箇所:
            // -- マップ退場時
            // -- セーブ時
            {
                this.Player.HP            = this.Status.StartHP;
                this.Player.FaceDirection = this.Status.StartFaceDirection;
                this.Player.選択武器          = this.Status.Start選択武器;
            }

            this.Wall = WallCreator.Create(this.Map.WallName);

            MusicCollection.Get(this.Map.MusicName).Play();

            DDGround.Camera.X = this.Player.X - DDConsts.Screen_W / 2.0;
            DDGround.Camera.Y = this.Player.Y - DDConsts.Screen_H / 2.0;

            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain(10);

            DDEngine.FreezeInput();

            // TODO: 音楽

            for (this.Frame = 0; ; this.Frame++)
            {
                if (!this.UserInputDisabled && DDInput.PAUSE.GetInput() == 1)
                {
                    this.Pause();

                    if (this.Pause_ReturnToTitleMenu)
                    {
                        this.Status.ExitDirection = 5;
                        break;
                    }
                }
                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1)
                {
                    this.DebugPause();
                }

                // 死亡時にカメラ移動を止める。
                //if (this.Player.DeadFrame == 0)
                //    this.カメラ位置調整(false);

                this.カメラ位置調整(false);

                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_E) == 1)                 // エディットモード(デバッグ用)
                {
                    this.Edit();
                    this.ReloadEnemies();
                    this.Frame = 0;
                }

                // プレイヤー入力・移動
                {
                    bool deadOrUID = 1 <= this.Player.DeadFrame || this.UserInputDisabled;
                    bool dir2      = !deadOrUID && 1 <= DDInput.DIR_2.GetInput() || this.PlayerHacker.DIR_2;
                    bool dir4      = !deadOrUID && 1 <= DDInput.DIR_4.GetInput() || this.PlayerHacker.DIR_4;
                    bool dir6      = !deadOrUID && 1 <= DDInput.DIR_6.GetInput() || this.PlayerHacker.DIR_6;
                    bool dir8      = !deadOrUID && 1 <= DDInput.DIR_8.GetInput() || this.PlayerHacker.DIR_8;
                    int  dir;                    // 1~9 == { 左下, 下, 右下, 左, 動かない, 右, 左上, 上, 右上 }

                    if (dir2 && dir4)
                    {
                        dir = 1;
                    }
                    else if (dir2 && dir6)
                    {
                        dir = 3;
                    }
                    else if (dir4 && dir8)
                    {
                        dir = 7;
                    }
                    else if (dir6 && dir8)
                    {
                        dir = 9;
                    }
                    else if (dir2)
                    {
                        dir = 2;
                    }
                    else if (dir4)
                    {
                        dir = 4;
                    }
                    else if (dir6)
                    {
                        dir = 6;
                    }
                    else if (dir8)
                    {
                        dir = 8;
                    }
                    else
                    {
                        dir = 5;
                    }

                    if (1 <= this.Player.DamageFrame)                     // ? プレイヤー・ダメージ中
                    {
                        dir = 5;
                    }

                    bool camSlide = !deadOrUID && 1 <= DDInput.L.GetInput();

                    if (camSlide)
                    {
                        dir = 5;
                    }

                    bool slow = !deadOrUID && 1 <= DDInput.A.GetInput() || this.PlayerHacker.Slow;
                    bool fast = !deadOrUID && 1 <= DDInput.R.GetInput() || this.PlayerHacker.Fast;

                    if (Ground.I.FastReverseMode)
                    {
                        fast = !fast;
                    }

                    double speed = 3.0;

                    if (slow)
                    {
                        speed -= 1.0;
                    }

                    if (fast)
                    {
                        speed += 2.0;
                    }

                    double nanameSpeed = speed / Consts.ROOT_OF_2;

                    switch (dir)
                    {
                    case 2:
                        this.Player.Y += speed;
                        break;

                    case 4:
                        this.Player.X -= speed;
                        break;

                    case 6:
                        this.Player.X += speed;
                        break;

                    case 8:
                        this.Player.Y -= speed;
                        break;

                    case 1:
                        this.Player.X -= nanameSpeed;
                        this.Player.Y += nanameSpeed;
                        break;

                    case 3:
                        this.Player.X += nanameSpeed;
                        this.Player.Y += nanameSpeed;
                        break;

                    case 7:
                        this.Player.X -= nanameSpeed;
                        this.Player.Y -= nanameSpeed;
                        break;

                    case 9:
                        this.Player.X += nanameSpeed;
                        this.Player.Y -= nanameSpeed;
                        break;

                    case 5:
                        break;

                    default:
                        throw null;                                 // never
                    }
                    if (dir != 5 && !slow)
                    {
                        this.Player.FaceDirection = dir;
                    }

                    if (dir != 5)
                    {
                        this.Player.MoveFrame++;
                    }
                    else
                    {
                        this.Player.MoveFrame = 0;
                    }

                    if (this.Player.MoveFrame == 0)                     // 立ち止まったら座標を整数に矯正
                    {
                        this.Player.X = SCommon.ToInt(this.Player.X);
                        this.Player.Y = SCommon.ToInt(this.Player.Y);
                    }
                    if (camSlide)
                    {
                        if (dir4)
                        {
                            this.CamSlideCount++;
                            this.CamSlideX--;
                        }
                        if (dir6)
                        {
                            this.CamSlideCount++;
                            this.CamSlideX++;
                        }
                        if (dir8)
                        {
                            this.CamSlideCount++;
                            this.CamSlideY--;
                        }
                        if (dir2)
                        {
                            this.CamSlideCount++;
                            this.CamSlideY++;
                        }
                        DDUtils.ToRange(ref this.CamSlideX, -1, 1);
                        DDUtils.ToRange(ref this.CamSlideY, -1, 1);
                    }
                    else
                    {
                        if (this.CamSlideMode && this.CamSlideCount == 0)
                        {
                            this.CamSlideX = 0;
                            this.CamSlideY = 0;
                        }
                        this.CamSlideCount = 0;
                    }
                    this.CamSlideMode = camSlide;

                    bool attack = !deadOrUID && 1 <= DDInput.B.GetInput() || this.PlayerHacker.Attack;

                    if (attack)
                    {
                        this.Player.AttackFrame++;
                    }
                    else
                    {
                        this.Player.AttackFrame = 0;
                    }

                    bool 武器切り替え = !deadOrUID && DDInput.C.GetInput() == 1;

                    if (武器切り替え)
                    {
                        this.Player.選択武器 = (Player.武器_e)(((int)this.Player.選択武器 + 1) % Player.武器_e_Length);
                    }
                }

                //startDead:
                if (1 <= this.Player.DeadFrame)                 // プレイヤー死亡中の処理
                {
                    int frame = this.Player.DeadFrame - 1;

                    if (GameConsts.PLAYER_DEAD_FRAME_MAX < frame)
                    {
                        this.Player.DeadFrame     = 0;
                        this.Status.ExitDirection = 5;
                        break;
                    }
                    this.Player.DeadFrame++;

                    // ----

                    const int HITBACK_FRAME_MAX = 30;

                    if (frame < HITBACK_FRAME_MAX)
                    {
                        double rate    = (double)frame / HITBACK_FRAME_MAX;
                        double invRate = 1.0 - rate;

                        D2Point speed = GameCommon.GetXYSpeed(this.Player.FaceDirection, 10.0 * invRate);

                        this.Player.X -= speed.X;
                        this.Player.Y -= speed.Y;
                    }
                }
                //endDead:

                //startDamage:
                if (1 <= this.Player.DamageFrame)                 // プレイヤー・ダメージ中の処理
                {
                    int frame = this.Player.DamageFrame - 1;

                    if (GameConsts.PLAYER_DAMAGE_FRAME_MAX < frame)
                    {
                        this.Player.DamageFrame     = 0;
                        this.Player.InvincibleFrame = 1;
                        goto endDamage;
                    }
                    this.Player.DamageFrame++;

                    // ----

                    {
                        D2Point speed = GameCommon.GetXYSpeed(this.Player.FaceDirection, 5.0);

                        for (int c = 0; c < 5; c++)
                        {
                            {
                                int x = SCommon.ToInt(this.Player.X) / GameConsts.TILE_W;
                                int y = SCommon.ToInt(this.Player.Y) / GameConsts.TILE_H;

                                if (this.Map.GetCell(x, y).Tile.GetKind() != Tile.Kind_e.SPACE)                                 // ? 歩行可能な場所ではない -> これ以上ヒットバックさせない。
                                {
                                    break;
                                }
                            }

                            this.Player.X -= speed.X;
                            this.Player.Y -= speed.Y;
                        }
                    }
                }
endDamage:

                //startInvincible:
                if (1 <= this.Player.InvincibleFrame)                 // プレイヤー無敵時間中の処理
                {
                    int frame = this.Player.InvincibleFrame - 1;

                    if (GameConsts.PLAYER_INVINCIBLE_FRAME_MAX < frame)
                    {
                        this.Player.InvincibleFrame = 0;
                        goto endInvincible;
                    }
                    this.Player.InvincibleFrame++;

                    // ----

                    // noop
                }
endInvincible:

                // プレイヤー位置矯正
                {
                    壁キャラ処理.Perform(ref this.Player.X, ref this.Player.Y, v => v.GetKind() != Tile.Kind_e.SPACE);
                }

                if (this.Player.X < 0.0)                 // ? マップの左側に出た。
                {
                    this.Status.ExitDirection = 4;
                    break;
                }
                if (this.Map.W * GameConsts.TILE_W < this.Player.X)                 // ? マップの右側に出た。
                {
                    this.Status.ExitDirection = 6;
                    break;
                }
                if (this.Player.Y < 0.0)                 // ? マップの上側に出た。
                {
                    this.Status.ExitDirection = 8;
                    break;
                }
                if (this.Map.H * GameConsts.TILE_H < this.Player.Y)                 // ? マップの下側に出た。
                {
                    this.Status.ExitDirection = 2;
                    break;
                }

                // 画面遷移時の微妙なカメラ位置ズレ解消
                // -- 必要無いかもしれないが、念の為実行しておく。
                if (this.Frame == 0)
                {
                    this.カメラ位置調整(true);
                }

                if (1 <= this.Player.AttackFrame)
                {
                    this.Player.Attack();
                }

                DDCrash plCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y));

                // ====
                // 描画ここから
                // ====

                this.DrawWall();
                this.DrawMap();
                this.Player.Draw();

                // memo: DeadFlag をチェックするのは「当たり判定」から

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    enemy.Crash = DDCrashUtils.None();                     // reset
                    enemy.Draw();
                }
                foreach (Shot shot in this.Shots.Iterate())
                {
                    shot.Crash = DDCrashUtils.None();                     // reset
                    shot.Draw();
                }

                if (this.当たり判定表示)
                {
                    // 最後に描画されるように DDGround.EL.Add() する。

                    DDGround.EL.Add(() =>
                    {
                        DDCurtain.DrawCurtain(-0.8);

                        const double A = 0.3;

                        DDCrashView.Draw(new DDCrash[] { plCrash }, new I3Color(255, 0, 0), 1.0);
                        DDCrashView.Draw(this.Enemies.Iterate().Select(v => v.Crash), new I3Color(255, 255, 255), A);
                        DDCrashView.Draw(this.Shots.Iterate().Select(v => v.Crash), new I3Color(0, 255, 255), A);

                        return(false);
                    });
                }

                // ====
                // 描画ここまで
                // ====

                // ====
                // 当たり判定ここから
                // ====

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    if (1 <= enemy.HP)                     // ? 敵:生存 && 無敵ではない
                    {
                        foreach (Shot shot in this.Shots.Iterate())
                        {
                            // 衝突判定:敵 x 自弾
                            if (
                                !shot.DeadFlag &&                                 // ? 自弾:生存
                                enemy.Crash.IsCrashed(shot.Crash)                 // ? 衝突
                                )
                            {
                                // ★ 敵_被弾ここから

                                if (!shot.敵を貫通する)
                                {
                                    shot.Kill();
                                }

                                enemy.HP -= shot.AttackPoint;

                                if (1 <= enemy.HP)                                 // ? まだ生存している。
                                {
                                    enemy.Damaged(shot);
                                }
                                else                                 // ? 撃破した。
                                {
                                    enemy.Kill(true);
                                    break;                                     // この敵は死亡したので、この敵について以降の当たり判定は不要
                                }

                                // ★ 敵_被弾ここまで
                            }
                        }
                    }

                    // 衝突判定:敵 x 自機
                    if (
                        this.Player.DeadFrame == 0 &&                // ? プレイヤー死亡中ではない。
                        this.Player.DamageFrame == 0 &&              // ? プレイヤー・ダメージ中ではない。
                        this.Player.InvincibleFrame == 0 &&          // ? プレイヤー無敵時間中ではない。
                        !enemy.DeadFlag &&                           // ? 敵:生存
                        DDCrashUtils.IsCrashed(enemy.Crash, plCrash) // ? 衝突
                        )
                    {
                        // ★ 自機_被弾ここから

                        if (enemy.自機に当たると消滅する)
                        {
                            enemy.Kill();
                        }

                        this.Player.HP -= enemy.AttackPoint;

                        if (1 <= this.Player.HP)                         // ? まだ生存している。
                        {
                            this.Player.DamageFrame = 1;
                        }
                        else                         // ? 死亡した。
                        {
                            this.Player.HP        = -1;
                            this.Player.DeadFrame = 1;
                        }

                        // ★ 自機_被弾ここまで
                    }
                }

                foreach (Shot shot in this.Shots.Iterate())
                {
                    // 壁への当たり判定は自弾の「中心座標のみ」であることに注意して下さい。

                    if (
                        !shot.DeadFlag &&                                                                            // ? 自弾:生存
                        !shot.壁をすり抜ける &&                                                                             // ? この自弾は壁に当たる。
                        this.Map.GetCell(GameCommon.ToTablePoint(shot.X, shot.Y)).Tile.GetKind() == Tile.Kind_e.WALL // ? 壁に当たった。
                        )
                    {
                        shot.Kill();
                    }
                }

                // ====
                // 当たり判定ここまで
                // ====

                f_ゴミ回収();

                this.Enemies.RemoveAll(v => v.DeadFlag);
                this.Shots.RemoveAll(v => v.DeadFlag);

                DDEngine.EachFrame();

                // ★★★ ゲームループの終わり ★★★
            }
            DDEngine.FreezeInput();

            if (this.Status.ExitDirection == 5)
            {
                DDMusicUtils.Fade();
                DDCurtain.SetCurtain(30, -1.0);

                foreach (DDScene scene in DDSceneUtils.Create(40))
                {
                    this.DrawWall();
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
            }
            else
            {
                double destSlide_X = 0.0;
                double destSlide_Y = 0.0;

                switch (this.Status.ExitDirection)
                {
                case 4:
                    destSlide_X = DDConsts.Screen_W;
                    break;

                case 6:
                    destSlide_X = -DDConsts.Screen_W;
                    break;

                case 8:
                    destSlide_Y = DDConsts.Screen_H;
                    break;

                case 2:
                    destSlide_Y = -DDConsts.Screen_H;
                    break;

                default:
                    throw null;                             // never
                }
                using (DDSubScreen wallMapScreen = new DDSubScreen(DDConsts.Screen_W, DDConsts.Screen_H))
                {
                    using (wallMapScreen.Section())
                    {
                        this.DrawWall();
                        this.DrawMap();
                    }
                    foreach (DDScene scene in DDSceneUtils.Create(30))
                    {
                        double slide_X = destSlide_X * scene.Rate;
                        double slide_Y = destSlide_Y * scene.Rate;

                        DDCurtain.DrawCurtain();
                        DDDraw.DrawSimple(wallMapScreen.ToPicture(), slide_X, slide_Y);

                        DDEngine.EachFrame();
                    }
                }
                DDCurtain.SetCurtain(0, -1.0);
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ退場時)
            // その他の反映箇所:
            // -- マップ入場時
            // -- セーブ時
            {
                this.Status.StartHP            = this.Player.HP;
                this.Status.StartFaceDirection = this.Player.FaceDirection;
                this.Status.Start選択武器          = this.Player.選択武器;
            }

            // ★★★ end of Perform() ★★★
        }
Example #6
0
        public void Perform()
        {
            Func <bool> f_ゴミ回収 = SCommon.Supplier(this.E_ゴミ回収());

            DDUtils.Random = new DDRandom(1u);             // 電源パターン確保のため

            this.Player.X = DDConsts.Screen_W / 4;
            this.Player.Y = DDConsts.Screen_H / 2;

            // ★★★★★
            // プレイヤー・ステータス反映(ステージ開始時)
            {
                // none
            }

            this.Player.RebornFrame = 1;

            Game.I.Walls.Add(new Wall_Dark());

            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain(20);

            DDEngine.FreezeInput();

            for (this.Frame = 0; ; this.Frame++)
            {
                if (!this.Script.EachFrame())
                {
                    break;
                }

                if (!this.UserInputDisabled && DDInput.PAUSE.GetInput() == 1)                 // ポーズ
                {
                    DDMusicUtils.Pause();
                    this.Pause();

                    if (this.Pause_ReturnToTitleMenu)
                    {
                        break;
                    }
                    DDMusicUtils.Resume();
                }
                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1)
                {
                    this.DebugPause();
                }

                // プレイヤー行動
                {
                    bool   deadOrRebornOrUID = 1 <= this.Player.DeadFrame || 1 <= this.Player.RebornFrame || this.UserInputDisabled;
                    bool   deadOrUID         = 1 <= this.Player.DeadFrame || this.UserInputDisabled;
                    double xa = 0.0;
                    double ya = 0.0;

                    if (!deadOrUID && 1 <= DDInput.DIR_4.GetInput())                     // 左移動
                    {
                        xa = -1.0;
                    }
                    if (!deadOrUID && 1 <= DDInput.DIR_6.GetInput())                     // 右移動
                    {
                        xa = 1.0;
                    }
                    if (!deadOrUID && 1 <= DDInput.DIR_8.GetInput())                     // 上移動
                    {
                        ya = -1.0;
                    }
                    if (!deadOrUID && 1 <= DDInput.DIR_2.GetInput())                     // 下移動
                    {
                        ya = 1.0;
                    }

                    double speed;

                    if (1 <= DDInput.A.GetInput())                     // 低速ボタン押下中
                    {
                        speed = (double)this.Player.SpeedLevel;
                    }
                    else
                    {
                        speed = (double)(this.Player.SpeedLevel * 2);
                    }

                    this.Player.X += xa * speed;
                    this.Player.Y += ya * speed;

                    DDUtils.ToRange(ref this.Player.X, 0.0, DDConsts.Screen_W);
                    DDUtils.ToRange(ref this.Player.Y, 0.0, DDConsts.Screen_H);

                    if (!deadOrRebornOrUID && 1 <= DDInput.B.GetInput())                     // 攻撃ボタン押下中
                    {
                        this.Player.Shoot();
                    }

                    if (DDInput.C.GetInput() == 1)
                    {
                        this.Player.SpeedLevel--;
                    }
                    if (DDInput.D.GetInput() == 1)
                    {
                        this.Player.SpeedLevel++;
                    }
                    DDUtils.ToRange(ref this.Player.SpeedLevel, Player.SPEED_LEVEL_MIN, Player.SPEED_LEVEL_MAX);
                }

                //startDead:
                if (1 <= this.Player.DeadFrame)                 // プレイヤー死亡中の処理
                {
                    int frame = this.Player.DeadFrame - 1;

                    if (GameConsts.PLAYER_DEAD_FRAME_MAX < frame)
                    {
                        this.Player.DeadFrame = 0;

                        if (this.Status.Zanki <= 0)                         // ? 残機不足
                        {
                            break;
                        }

                        this.システム的な敵クリア();

                        this.Status.Zanki--;
                        this.Player.AttackLevel = Math.Max(0, this.Player.AttackLevel - 1);
                        this.Player.RebornFrame = 1;
                        goto endDead;
                    }
                    this.Player.DeadFrame++;

                    // ----

                    if (frame == 0)                     // init
                    {
                        DDMain.KeepMainScreen();

                        foreach (DDScene scene in DDSceneUtils.Create(20))
                        {
                            DDDraw.DrawSimple(DDGround.KeptMainScreen.ToPicture(), 0, 0);

                            DDDraw.SetAlpha(0.3 + scene.Rate * 0.3);
                            DDDraw.SetBright(1.0, 0.0, 0.0);
                            DDDraw.DrawRect(Ground.I.Picture.WhiteBox, new D4Rect(0, 0, DDConsts.Screen_W, DDConsts.Screen_H));
                            DDDraw.Reset();

                            DDEngine.EachFrame();
                        }
                        DDGround.EL.Add(SCommon.Supplier(Effects.PlayerDead(this.Player.X, this.Player.Y)));
                    }
                }
endDead:

                //startReborn:
                if (1 <= this.Player.RebornFrame)                 // プレイヤー登場中の処理
                {
                    int frame = this.Player.RebornFrame - 1;

                    if (GameConsts.PLAYER_REBORN_FRAME_MAX < frame)
                    {
                        this.Player.RebornFrame     = 0;
                        this.Player.InvincibleFrame = 1;
                        goto endReborn;
                    }
                    this.Player.RebornFrame++;

                    // ----

                    double rate = (double)frame / GameConsts.PLAYER_REBORN_FRAME_MAX;

                    if (frame == 0)                     // init
                    {
                        this.Player.Reborn_X = -50.0;
                        this.Player.Reborn_Y = DDConsts.Screen_H / 2.0;
                    }
                    DDUtils.Approach(ref this.Player.Reborn_X, this.Player.X, 0.9 - 0.3 * rate);
                    DDUtils.Approach(ref this.Player.Reborn_Y, this.Player.Y, 0.9 - 0.3 * rate);
                }
endReborn:

                //startInvincible:
                if (1 <= this.Player.InvincibleFrame)                 // プレイヤー無敵時間中の処理
                {
                    int frame = this.Player.InvincibleFrame - 1;

                    if (GameConsts.PLAYER_INVINCIBLE_FRAME_MAX < frame)
                    {
                        this.Player.InvincibleFrame = 0;
                        goto endInvincible;
                    }
                    this.Player.InvincibleFrame++;

                    // ----

                    // noop
                }
endInvincible:

                DDCrash plCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y));

                // ====
                // 描画ここから
                // ====

                foreach (Wall wall in this.Walls.Iterate())
                {
                    wall.Draw();
                }

                this.Player.Draw();

                // memo: DeadFlag をチェックするのは「当たり判定」から

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    enemy.Crash = DDCrashUtils.None();                     // reset
                    enemy.Draw();
                }
                foreach (Shot shot in this.Shots.Iterate())
                {
                    shot.Crash = DDCrashUtils.None();                     // reset
                    shot.Draw();
                }

                if (DDConfig.LOG_ENABLED && 1 <= DDInput.R.GetInput())                 // 当たり判定表示(チート)
                {
                    DDCurtain.DrawCurtain(-0.7);

                    const double A = 0.7;

                    DDCrashView.Draw(new DDCrash[] { plCrash }, new I3Color(255, 0, 0), 1.0);
                    DDCrashView.Draw(this.Enemies.Iterate().Select(v => v.Crash), new I3Color(255, 255, 255), A);
                    DDCrashView.Draw(this.Shots.Iterate().Select(v => v.Crash), new I3Color(0, 255, 255), A);
                }

                // ====
                // 描画ここまで
                // ====

                // ====
                // 当たり判定ここから
                // ====

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    if (
                        1 <= enemy.HP &&                                      // ? 敵:生存 && 無敵ではない
                        !DDUtils.IsOutOfScreen(new D2Point(enemy.X, enemy.Y)) // ? 画面内の敵である。
                        )
                    {
                        foreach (Shot shot in this.Shots.Iterate())
                        {
                            // 衝突判定:敵 x 自弾
                            if (
                                !shot.DeadFlag &&                                 // ? 自弾:生存
                                DDCrashUtils.IsCrashed(enemy.Crash, shot.Crash)   // ? 衝突
                                )
                            {
                                // ★ 敵_被弾ここから

                                shot.Kill();

                                enemy.HP -= shot.AttackPoint;

                                if (1 <= enemy.HP)                                 // ? まだ生存している。
                                {
                                    enemy.Damaged();
                                }
                                else                                 // ? 撃破した。
                                {
                                    enemy.Kill(true);
                                    break;                                     // この敵は死亡したので、この敵について以降の当たり判定は不要
                                }

                                // ★ 敵_被弾ここまで
                            }
                        }
                    }

                    // 衝突判定:敵 x 自機
                    if (
                        this.Player.RebornFrame == 0 &&                          // ? プレイヤー登場中ではない。
                        this.Player.DeadFrame == 0 &&                            // ? プレイヤー死亡中ではない。
                        this.Player.InvincibleFrame == 0 &&                      // ? プレイヤー無敵時間中ではない。
                        !enemy.DeadFlag &&                                       // ? 敵:生存
                        !DDUtils.IsOutOfScreen(new D2Point(enemy.X, enemy.Y)) && // ? 画面内の敵である。
                        DDCrashUtils.IsCrashed(enemy.Crash, plCrash)             // ? 衝突
                        )
                    {
                        // ★ 自機_被弾ここから

                        this.Player.DeadFrame = 1;

                        // ★ 自機_被弾ここまで
                    }
                }

                // ====
                // 当たり判定ここまで
                // ====

                // 不要な壁の死亡フラグを立てる。
                // -- FilledFlag == true な Wall より下の Wall は見えないので破棄して良い。
                {
                    bool flag = false;

                    for (int index = this.Walls.Count - 1; 0 <= index; index--)
                    {
                        this.Walls[index].DeadFlag |= flag;
                        flag |= this.Walls[index].FilledFlag;
                    }
                }

                f_ゴミ回収();

                this.Walls.RemoveAll(v => v.DeadFlag);
                this.Enemies.RemoveAll(v => v.DeadFlag);
                this.Shots.RemoveAll(v => v.DeadFlag);

                DDEngine.EachFrame();

                // ★★★ ゲームループの終わり ★★★
            }

            DDMain.KeepMainScreen();

            DDMusicUtils.Fade();
            DDCurtain.SetCurtain(30, -1.0);

            foreach (DDScene scene in DDSceneUtils.Create(40))
            {
                DDDraw.DrawSimple(DDGround.KeptMainScreen.ToPicture(), 0, 0);
                DDEngine.EachFrame();
            }

            // ★★★★★
            // プレイヤー・ステータス反映(ステージ終了時)
            {
                // none
            }

            // ★★★ end of Perform() ★★★
        }
Example #7
0
        public void Perform()
        {
            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain();

            DDEngine.FreezeInput();

            Ground.I.Music.Title.Play();

            this.SimpleMenu = new DDSimpleMenu();

            this.SimpleMenu.BorderColor = new I3Color(0, 96, 192);
            this.SimpleMenu.WallDrawer  = this.DrawWall.Execute;

            for (; ;)
            {
                if (DDInput.DIR_8.IsPound())
                {
                    this.TopMenu.SelectIndex--;
                }

                if (DDInput.DIR_2.IsPound())
                {
                    this.TopMenu.SelectIndex++;
                }

                this.TopMenu.SelectIndex += TopMenuTask.ITEM_NUM;
                this.TopMenu.SelectIndex %= TopMenuTask.ITEM_NUM;

                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_Q) == 1)                 // (開発デバッグ用)ロック解除
                {
                    Ground.I.ReachedStageIndex = 10;
                }
                if (DDInput.A.GetInput() == 1)                 // ? 決定ボタン押下
                {
                    switch (this.TopMenu.SelectIndex)
                    {
                    case 0:
                        if (DDConfig.LOG_ENABLED && 1 <= DDInput.DIR_6.GetInput())
                        {
                            this.DrawWall.TopMenuLeaved = true;
                            this.CheatMainMenu();
                            this.DrawWall.TopMenuLeaved = false;
                        }
                        else
                        {
                            this.LeaveTitleMenu();

                            using (new GameProgressMaster())
                            {
                                GameProgressMaster.I.StartStageIndex = 1;
                                GameProgressMaster.I.Perform();
                            }
                            this.ReturnTitleMenu();
                        }
                        break;

                    case 1:
                        this.DrawWall.TopMenuLeaved = true;
                        this.SelectStage();
                        this.DrawWall.TopMenuLeaved = false;
                        break;

                    case 2:
                        this.DrawWall.TopMenuLeaved = true;
                        this.Setting();
                        this.DrawWall.TopMenuLeaved = false;
                        break;

                    case 3:
                        goto endMenu;

                    default:
                        throw new DDError();
                    }
                }
                if (DDInput.B.GetInput() == 1)                 // ? キャンセルボタン押下
                {
                    if (this.TopMenu.SelectIndex == TopMenuTask.ITEM_NUM - 1)
                    {
                        break;
                    }

                    this.TopMenu.SelectIndex = TopMenuTask.ITEM_NUM - 1;
                }

                this.DrawWall.Execute();
                this.TopMenu.Execute();

                DDEngine.EachFrame();
            }
endMenu:
            DDMusicUtils.Fade();
            DDCurtain.SetCurtain(30, -1.0);

            foreach (DDScene scene in DDSceneUtils.Create(40))
            {
                //this.SimpleMenu.DrawWall();
                this.DrawWall.Execute();

                DDEngine.EachFrame();
            }

            DDEngine.FreezeInput();
        }
Example #8
0
        public void Perform()
        {
            Func <bool> f_ゴミ回収 = SCommon.Supplier(this.E_ゴミ回収());

            this.Map = new Map(GameCommon.GetMapFile(this.World.GetCurrMapName()));
            this.ReloadEnemies();

            // デフォルトの「プレイヤーのスタート地点」
            // -- マップの中央
            this.Player.X = this.Map.W * GameConsts.TILE_W / 2.0;
            this.Player.Y = this.Map.H * GameConsts.TILE_H / 2.0;

            {
                Enemy enemy = this.Enemies.Iterate().FirstOrDefault(v => v is Enemy_スタート地点 && ((Enemy_スタート地点)v).Direction == this.Status.StartPointDirection);

                if (enemy != null)
                {
                    this.Player.X = enemy.X;
                    this.Player.Y = enemy.Y;
                }
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ入場時)
            // その他の反映箇所:
            // -- マップ退場時
            // -- セーブ時
            {
                this.Player.HP         = this.Status.StartHP;
                this.Player.FacingLeft = this.Status.StartFacingLeft;
                this.Player.武器         = this.Status.Start_武器;
            }

            this.Wall = WallCreator.Create(this.Map.WallName);

            MusicCollection.Get(this.Map.MusicName).Play();

            DDGround.Camera.X = this.Player.X - DDConsts.Screen_W / 2.0;
            DDGround.Camera.Y = this.Player.Y - DDConsts.Screen_H / 2.0;

            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain(10);

            DDEngine.FreezeInput();

            bool jumpLock = false;             // ? ジャンプ・ロック // ジャンプしたらボタンを離すまでロックする。

            for (this.Frame = 0; ; this.Frame++)
            {
                if (!this.UserInputDisabled && DDInput.PAUSE.GetInput() == 1)
                {
                    this.Pause();

                    if (this.Pause_ReturnToTitleMenu)
                    {
                        this.Status.ExitDirection = 5;
                        break;
                    }
                }
                if (this.RequestReturnToTitleMenu)
                {
                    this.Status.ExitDirection = 5;
                    break;
                }
                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1)
                {
                    this.DebugPause();
                }

                // 死亡時にカメラ移動を止める。
                //if (this.Player.DeadFrame == 0)
                //    this.カメラ位置調整(false);

                this.カメラ位置調整(false);

                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_E) == 1)                 // エディットモード(デバッグ用)
                {
                    this.Edit();
                    this.ReloadEnemies();
                    this.Frame = 0;
                }

                // プレイヤー入力
                {
                    bool deadOrDamageOrUID = 1 <= this.Player.DeadFrame || 1 <= this.Player.DamageFrame || this.UserInputDisabled;
                    bool move     = false;
                    bool slow     = false;
                    bool camSlide = false;
                    int  jump     = 0;
                    bool shagami  = false;
                    bool attack   = false;

                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_2.GetInput() || this.PlayerHacker.DIR_2)
                    {
                        shagami = true;
                    }

                    // 入力抑止中であるか否かに関わらず左右の入力は受け付ける様にする。
                    int freezeInputFrameBackup = DDEngine.FreezeInputFrame;
                    DDEngine.FreezeInputFrame = 0;

                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_4.GetInput() || this.PlayerHacker.DIR_4)
                    {
                        this.Player.FacingLeft = true;
                        move = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_6.GetInput() || this.PlayerHacker.DIR_6)
                    {
                        this.Player.FacingLeft = false;
                        move = true;
                    }

                    DDEngine.FreezeInputFrame = freezeInputFrameBackup;                     // restore

                    if (1 <= DDInput.L.GetInput())
                    {
                        move     = false;
                        shagami  = false;
                        camSlide = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.R.GetInput() || this.PlayerHacker.Slow)
                    {
                        slow = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.A.GetInput())
                    {
                        jump = DDInput.A.GetInput();
                    }
                    if (this.PlayerHacker.Jump != 0)
                    {
                        jump = this.PlayerHacker.Jump;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.B.GetInput() || this.PlayerHacker.Attack)
                    {
                        attack = true;
                    }

                    if (move)
                    {
                        this.Player.MoveFrame++;
                        shagami = false;
                    }
                    else
                    {
                        this.Player.MoveFrame = 0;
                    }

                    this.Player.MoveSlow = move && slow;

                    if (jump == 0)
                    {
                        jumpLock = false;
                    }

                    if (1 <= this.Player.JumpFrame)
                    {
                        const int JUMP_FRAME_MAX = 22;

                        if (1 <= jump && this.Player.JumpFrame < JUMP_FRAME_MAX)
                        {
                            this.Player.JumpFrame++;
                        }
                        else
                        {
                            this.Player.JumpFrame = 0;
                        }
                    }
                    else
                    {
                        // 事前入力 == 着地前の数フレーム間にジャンプボタンを押し始めてもジャンプできるようにする。
                        // 入力猶予 == 落下(地面から離れた)直後の数フレーム間にジャンプボタンを押し始めてもジャンプできるようにする。

                        const int 事前入力時間 = 5;
                        const int 入力猶予時間 = 5;

                        if (1 <= jump && jump < 事前入力時間 && this.Player.AirborneFrame < 入力猶予時間 && this.Player.JumpCount == 0 && !jumpLock)
                        {
                            this.Player.JumpCount = 1;
                            this.Player.JumpFrame = 1;
                            jumpLock = true;
                        }
                    }

                    if (this.Player.JumpFrame == 1)                     // ? ジャンプ開始
                    {
                        Ground.I.SE.PlayerJump.Play();
                    }

                    if (camSlide)
                    {
                        if (DDInput.DIR_4.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideX--;
                        }
                        if (DDInput.DIR_6.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideX++;
                        }
                        if (DDInput.DIR_8.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideY--;
                        }
                        if (DDInput.DIR_2.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideY++;
                        }
                        DDUtils.ToRange(ref this.CamSlideX, -1, 1);
                        DDUtils.ToRange(ref this.CamSlideY, -1, 1);
                    }
                    else
                    {
                        if (this.CamSlideMode && this.CamSlideCount == 0)
                        {
                            this.CamSlideX = 0;
                            this.CamSlideY = 0;
                        }
                        this.CamSlideCount = 0;
                    }
                    this.CamSlideMode = camSlide;

                    if (1 <= this.Player.AirborneFrame)
                    {
                        shagami = false;
                    }

                    if (shagami)
                    {
                        this.Player.ShagamiFrame++;
                    }
                    else
                    {
                        this.Player.ShagamiFrame = 0;
                    }

                    if (attack)
                    {
                        this.Player.AttackFrame++;
                    }
                    else
                    {
                        this.Player.AttackFrame = 0;
                    }
                }

                //startDead:
                if (1 <= this.Player.DeadFrame)                 // プレイヤー死亡中の処理
                {
                    if (GameConsts.PLAYER_DEAD_FRAME_MAX < ++this.Player.DeadFrame)
                    {
                        this.Player.DeadFrame     = 0;
                        this.Status.ExitDirection = 5;
                        break;
                    }
                    int    frame = this.Player.DeadFrame;                  // 値域 == 2 ~ GameConsts.PLAYER_DEAD_FRAME_MAX
                    double rate  = DDUtils.RateAToB(2, GameConsts.PLAYER_DEAD_FRAME_MAX, frame);

                    // ---- Dead

                    const int HIT_BACK_FRAME_MAX = 30;

                    if (frame < HIT_BACK_FRAME_MAX)
                    {
                        double hitBackRate = (double)frame / HIT_BACK_FRAME_MAX;

                        this.Player.X -= 10.0 * (1.0 - hitBackRate) * (this.Player.FacingLeft ? -1 : 1);
                    }
                }
                //endDead:

                //startDamage:
                if (1 <= this.Player.DamageFrame)                 // プレイヤー・ダメージ中の処理
                {
                    if (GameConsts.PLAYER_DAMAGE_FRAME_MAX < ++this.Player.DamageFrame)
                    {
                        this.Player.DamageFrame     = 0;
                        this.Player.InvincibleFrame = 1;
                        goto endDamage;
                    }
                    int    frame = this.Player.DamageFrame;                  // 値域 == 2 ~ GameConsts.PLAYER_DAMAGE_FRAME_MAX
                    double rate  = DDUtils.RateAToB(2, GameConsts.PLAYER_DAMAGE_FRAME_MAX, frame);

                    // ---- Damage

                    this.Player.X -= (9.0 - 6.0 * rate) * (this.Player.FacingLeft ? -1 : 1);
                }
endDamage:

                //startInvincible:
                if (1 <= this.Player.InvincibleFrame)                 // プレイヤー無敵時間中の処理
                {
                    if (GameConsts.PLAYER_INVINCIBLE_FRAME_MAX < ++this.Player.InvincibleFrame)
                    {
                        this.Player.InvincibleFrame = 0;
                        goto endInvincible;
                    }
                    int    frame = this.Player.InvincibleFrame;                  // 値域 == 2 ~ GameConsts.PLAYER_INVINCIBLE_FRAME_MAX
                    double rate  = DDUtils.RateAToB(2, GameConsts.PLAYER_INVINCIBLE_FRAME_MAX, frame);

                    // ---- Invincible

                    // noop
                }
endInvincible:

                // プレイヤー移動
                {
                    if (1 <= this.Player.MoveFrame)
                    {
                        double speed = 0.0;

                        if (this.Player.MoveSlow)
                        {
                            speed = this.Player.MoveFrame * 0.2;
                            DDUtils.Minim(ref speed, GameConsts.PLAYER_SLOW_SPEED);
                        }
                        else
                        {
                            speed = GameConsts.PLAYER_SPEED;
                        }

                        speed *= this.Player.FacingLeft ? -1 : 1;

                        this.Player.X += speed;
                    }
                    else
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X);
                    }

                    if (1 <= this.Player.JumpFrame)
                    {
                        this.Player.YSpeed = GameConsts.PLAYER_ジャンプによる上昇速度;
                    }
                    else
                    {
                        this.Player.YSpeed += GameConsts.PLAYER_GRAVITY;
                    }

                    DDUtils.Minim(ref this.Player.YSpeed, GameConsts.PLAYER_FALL_SPEED_MAX);

                    this.Player.Y += this.Player.YSpeed;                     // 自由落下
                }

                // プレイヤー位置矯正
                {
                    bool touchSide_L =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y - GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y + GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall();

                    bool touchSide_R =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y - GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y + GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall();

                    if (touchSide_L && touchSide_R)                     // -> 壁抜け防止のため再チェック
                    {
                        touchSide_L = this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall();
                        touchSide_R = this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall();
                    }

                    if (touchSide_L && touchSide_R)
                    {
                        // noop
                    }
                    else if (touchSide_L)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W + GameConsts.PLAYER_側面判定Pt_X;
                    }
                    else if (touchSide_R)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W - GameConsts.PLAYER_側面判定Pt_X;
                    }

                    bool touchCeiling_L =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_脳天判定Pt_X, this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y)).Tile.IsWall();

                    bool touchCeiling_R =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_脳天判定Pt_X, this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y)).Tile.IsWall();

                    if (touchCeiling_L && touchCeiling_R)
                    {
                        if (this.Player.YSpeed < 0.0)
                        {
                            double plY = ((int)((this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y) / GameConsts.TILE_H) + 1) * GameConsts.TILE_H + GameConsts.PLAYER_脳天判定Pt_Y;

                            this.Player.Y         = plY;
                            this.Player.YSpeed    = 0.0;
                            this.Player.JumpFrame = 0;
                        }
                    }
                    else if (touchCeiling_L)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W + GameConsts.PLAYER_脳天判定Pt_X;
                    }
                    else if (touchCeiling_R)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W - GameConsts.PLAYER_脳天判定Pt_X;
                    }

                    bool touchGround =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_接地判定Pt_X, this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_接地判定Pt_X, this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y)).Tile.IsWall();

                    if (touchGround)
                    {
                        if (0.0 < this.Player.YSpeed)
                        {
                            double plY = (int)((this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y) / GameConsts.TILE_H) * GameConsts.TILE_H - GameConsts.PLAYER_接地判定Pt_Y;

                            this.Player.Y      = plY;
                            this.Player.YSpeed = 0.0;
                        }
                    }

                    if (touchGround)
                    {
                        this.Player.JumpCount     = 0;
                        this.Player.AirborneFrame = 0;
                    }
                    else
                    {
                        this.Player.AirborneFrame++;
                    }
                }
                //endPlayer:

                if (this.Player.X < 0.0)                 // ? マップの左側に出た。
                {
                    this.Status.ExitDirection = 4;
                    break;
                }
                if (this.Map.W * GameConsts.TILE_W < this.Player.X)                 // ? マップの右側に出た。
                {
                    this.Status.ExitDirection = 6;
                    break;
                }
                if (this.Player.Y < 0.0)                 // ? マップの上側に出た。
                {
                    this.Status.ExitDirection = 8;
                    break;
                }
                if (this.Map.H * GameConsts.TILE_H < this.Player.Y)                 // ? マップの下側に出た。
                {
                    this.Status.ExitDirection = 2;
                    break;
                }

                // 画面遷移時の微妙なカメラ位置ズレ解消
                // -- スタート地点(入場地点)が地面と接していると、最初のフレームでプレイヤーは上に押し出されてカメラの初期位置とズレてしまう。
                if (this.Frame == 0 || this.次のカメラ位置調整を一瞬で)
                {
                    this.次のカメラ位置調整を一瞬で = false;
                    this.カメラ位置調整(true);
                }

                if (1 <= this.Player.AttackFrame)
                {
                    this.Player.Attack();
                }

                DDCrash plCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y + (1 <= this.Player.ShagamiFrame ? 16 : 0)));

                // ====
                // 描画ここから
                // ====

                this.DrawWall();
                this.DrawMap();
                this.Player.Draw();

                // memo: DeadFlag をチェックするのは「当たり判定」から

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    enemy.Crash = DDCrashUtils.None();                     // reset
                    enemy.Draw();
                }
                foreach (Shot shot in this.Shots.Iterate())
                {
                    shot.Crash = DDCrashUtils.None();                     // reset
                    shot.Draw();
                }

                if (this.当たり判定表示)
                {
                    // 最後に描画されるように DDGround.EL.Add() する。

                    DDGround.EL.Add(() =>
                    {
                        DDCurtain.DrawCurtain(-0.7);

                        const double A = 0.7;

                        DDCrashView.Draw(new DDCrash[] { plCrash }, new I3Color(255, 0, 0), 1.0);
                        DDCrashView.Draw(this.Enemies.Iterate().Select(v => v.Crash), new I3Color(255, 255, 255), A);
                        DDCrashView.Draw(this.Shots.Iterate().Select(v => v.Crash), new I3Color(0, 255, 255), A);

                        return(false);
                    });
                }

                // ====
                // 描画ここまで
                // ====

                // ====
                // 当たり判定ここから
                // ====

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    if (1 <= enemy.HP)                     // ? 敵:生存 && 無敵ではない
                    {
                        foreach (Shot shot in this.Shots.Iterate())
                        {
                            // 衝突判定:敵 x 自弾
                            if (
                                !shot.DeadFlag &&                                 // ? 自弾:生存
                                enemy.Crash.IsCrashed(shot.Crash)                 // ? 衝突
                                )
                            {
                                // ★ 敵_被弾ここから

                                enemy.HP -= shot.AttackPoint;

                                if (!shot.敵を貫通する)                                 // 自弾の攻撃力と敵のHPを相殺
                                {
                                    if (0 <= enemy.HP)                            // ? 丁度削りきった || 削りきれなかった -> 攻撃力を使い果たしたので、ショットは消滅
                                    {
                                        shot.Kill();
                                    }
                                    else
                                    {
                                        shot.AttackPoint = -enemy.HP;                                         // 過剰に削った分を残りの攻撃力として反映
                                    }
                                }

                                if (1 <= enemy.HP)                                 // ? まだ生存している。
                                {
                                    enemy.Damaged(shot);
                                }
                                else                                 // ? 撃破した。
                                {
                                    enemy.Kill(true);
                                    break;                                     // この敵は死亡したので、この敵について以降の当たり判定は不要
                                }

                                // ★ 敵_被弾ここまで
                            }
                        }
                    }

                    // 衝突判定:敵 x 自機
                    if (
                        this.Player.DeadFrame == 0 &&                // ? プレイヤー死亡中ではない。
                        this.Player.DamageFrame == 0 &&              // ? プレイヤー・ダメージ中ではない。
                        this.Player.InvincibleFrame == 0 &&          // ? プレイヤー無敵時間中ではない。
                        !enemy.DeadFlag &&                           // ? 敵:生存
                        DDCrashUtils.IsCrashed(enemy.Crash, plCrash) // ? 衝突
                        )
                    {
                        // ★ 自機_被弾ここから

                        if (enemy.自機に当たると消滅する)
                        {
                            enemy.Kill();
                        }

                        this.Player.HP -= enemy.AttackPoint;

                        if (1 <= this.Player.HP)                         // ? まだ生存している。
                        {
                            this.Player.DamageFrame = 1;
                        }
                        else                         // ? 死亡した。
                        {
                            this.Player.HP        = -1;
                            this.Player.DeadFrame = 1;
                        }

                        // ★ 自機_被弾ここまで
                    }
                }

                foreach (Shot shot in this.Shots.Iterate())
                {
                    // 壁への当たり判定は自弾の「中心座標のみ」であることに注意して下さい。

                    if (
                        !shot.DeadFlag &&                                                       // ? 自弾:生存
                        !shot.壁をすり抜ける &&                                                        // ? この自弾は壁に当たる。
                        this.Map.GetCell(GameCommon.ToTablePoint(shot.X, shot.Y)).Tile.IsWall() // ? 壁に当たった。
                        )
                    {
                        shot.Kill();
                    }
                }

                // ====
                // 当たり判定ここまで
                // ====

                f_ゴミ回収();

                this.Enemies.RemoveAll(v => v.DeadFlag);
                this.Shots.RemoveAll(v => v.DeadFlag);

                DDEngine.EachFrame();

                // ★★★ ゲームループの終わり ★★★
            }
            DDEngine.FreezeInput();

            if (this.Status.ExitDirection == 5)
            {
                DDMusicUtils.Fade();
                DDCurtain.SetCurtain(30, -1.0);

                foreach (DDScene scene in DDSceneUtils.Create(40))
                {
                    this.DrawWall();
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
            }
            else
            {
                double destSlide_X = 0.0;
                double destSlide_Y = 0.0;

                switch (this.Status.ExitDirection)
                {
                case 4:
                    destSlide_X = DDConsts.Screen_W;
                    break;

                case 6:
                    destSlide_X = -DDConsts.Screen_W;
                    break;

                case 8:
                    destSlide_Y = DDConsts.Screen_H;
                    break;

                case 2:
                    destSlide_Y = -DDConsts.Screen_H;
                    break;

                default:
                    throw null;                             // never
                }
                using (DDSubScreen wallMapScreen = new DDSubScreen(DDConsts.Screen_W, DDConsts.Screen_H))
                {
                    using (wallMapScreen.Section())
                    {
                        this.DrawWall();
                        this.DrawMap();
                    }
                    foreach (DDScene scene in DDSceneUtils.Create(30))
                    {
                        double slide_X = destSlide_X * scene.Rate;
                        double slide_Y = destSlide_Y * scene.Rate;

                        DDCurtain.DrawCurtain();
                        DDDraw.DrawSimple(wallMapScreen.ToPicture(), slide_X, slide_Y);

                        DDEngine.EachFrame();
                    }
                }
                DDCurtain.SetCurtain(0, -1.0);
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ退場時)
            // その他の反映箇所:
            // -- マップ入場時
            // -- セーブ時
            {
                this.Status.StartHP         = this.Player.HP;
                this.Status.StartFacingLeft = this.Player.FacingLeft;
                this.Status.Start_武器        = this.Player.武器;
            }

            // ★★★ end of Perform() ★★★
        }
Example #9
0
        private void CheckInputPadButtonKey(bool キー設定Flag, DDInput.Button targetButton)
        {
            DDInput.Button[] buttons = new DDInput.Button[]
            {
                DDInput.DIR_2,
                DDInput.DIR_4,
                DDInput.DIR_6,
                DDInput.DIR_8,
                DDInput.A,
                DDInput.B,
                DDInput.L,
            };

            if (キー設定Flag)
            {
                int pressKeyId = -1;

                foreach (int keyId in DDSimpleMenu.GetAllKeyId())
                {
                    if (DDKey.GetInput(keyId) == 1)
                    {
                        pressKeyId = keyId;
                    }
                }

                if (pressKeyId != -1)
                {
                    // 他ボタンとの重複回避
                    foreach (DDInput.Button button in buttons)
                    {
                        button.KeyIds = button.KeyIds.Where(keyId => keyId != pressKeyId).ToArray();
                    }

                    targetButton.KeyIds = targetButton.KeyIds.Concat(new int[] { pressKeyId }).ToArray();
                }
            }
            else
            {
                int pressBtnId = -1;

                for (int padId = 0; padId < DDPad.GetPadCount(); padId++)
                {
                    for (int btnId = 0; btnId < DDPad.PAD_BUTTON_MAX; btnId++)
                    {
                        if (DDPad.GetInput(padId, btnId) == 1)
                        {
                            pressBtnId = btnId;
                        }
                    }
                }

                if (pressBtnId != -1)
                {
                    // 他ボタンとの重複回避
                    foreach (DDInput.Button button in buttons)
                    {
                        button.BtnIds = button.BtnIds.Where(btnId => btnId != pressBtnId).ToArray();
                    }

                    targetButton.BtnIds = targetButton.BtnIds.Concat(new int[] { pressBtnId }).ToArray();
                }
            }
        }
Example #10
0
        public void Perform()
        {
            Func <bool> f_ゴミ回収 = SCommon.Supplier(this.E_ゴミ回収());

            this.Map = new Map(GameCommon.GetMapFile(this.World.GetCurrMapName()));
            this.ReloadEnemies();

            // デフォルトの「プレイヤーのスタート地点」
            // -- マップの中央
            this.Player.X = this.Map.W * GameConsts.TILE_W / 2.0;
            this.Player.Y = this.Map.H * GameConsts.TILE_H / 2.0;

            {
                Enemy enemy = this.Enemies.Iterate().FirstOrDefault(v => v is Enemy_スタート地点 && ((Enemy_スタート地点)v).Direction == this.Status.StartPointDirection);

                if (enemy != null)
                {
                    this.Player.X = enemy.X;
                    this.Player.Y = enemy.Y;
                }
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ入場時)
            // その他の反映箇所:
            // -- マップ退場時
            // -- セーブ時
            {
                this.Player.Chara      = this.Status.StartChara;
                this.Player.HP         = this.Status.StartHP;
                this.Player.FacingLeft = this.Status.StartFacingLeft;
            }

            this.Wall = WallCreator.Create(this.Map.WallName);

            MusicCollection.Get(this.Map.MusicName).Play();

            DDGround.Camera.X = this.Player.X - DDConsts.Screen_W / 2.0;
            DDGround.Camera.Y = this.Player.Y - DDConsts.Screen_H / 2.0;

            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain(10);

            DDEngine.FreezeInput();

            for (this.Frame = 0; ; this.Frame++)
            {
                // Attack_ほむらシールド 終了から Shot_ほむらシールド の PlayerTracer.Start 実行の間に
                // ポーズできるタイミングは無いはずだけど、曲芸的で気持ち悪い。

                if (
                    !this.UserInputDisabled &&
                    //Game.I.Player.Attack == null && // ? プレイヤーの攻撃モーション中ではない。// モーション中でも良いはず!
                    DDInput.PAUSE.GetInput() == 1
                    )
                {
                    this.Pause();

                    if (this.Pause_ReturnToTitleMenu)
                    {
                        this.Status.ExitDirection = 5;
                        break;
                    }
                }
                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1)
                {
                    this.DebugPause();
                }

                // 死亡時にカメラ移動を止める。
                //if (this.Player.DeadFrame == 0)
                //    this.カメラ位置調整(false);

                this.カメラ位置調整(false);

                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_E) == 1)                 // エディットモード(デバッグ用)
                {
                    this.Edit();
                    this.ReloadEnemies();
                    this.Frame = 0;
                }

                if (this.Player.Attack != null)                 // プレイヤー攻撃中
                {
                    if (this.Player.Attack.EachFrame())         // ? このプレイヤー攻撃を継続する。
                    {
                        goto endPlayer;
                    }

                    this.Player.Attack = null;                     // プレイヤー攻撃_終了
                }

                // プレイヤー入力
                {
                    bool deadOrDamageOrUID = 1 <= this.Player.DeadFrame || 1 <= this.Player.DamageFrame || this.UserInputDisabled;
                    bool move           = false;
                    bool slow           = false;
                    bool camSlide       = false;
                    int  jump           = 0;
                    bool shagami        = false;
                    int  attack         = 0;
                    int  extendedAttack = 0;

                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_2.GetInput())
                    {
                        shagami = true;
                    }

                    // 入力抑止中であるか否かに関わらず左右の入力は受け付ける様にする。
                    int freezeInputFrameBackup = DDEngine.FreezeInputFrame;
                    DDEngine.FreezeInputFrame = 0;

                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_4.GetInput())
                    {
                        this.Player.FacingLeft = true;
                        move = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.DIR_6.GetInput())
                    {
                        this.Player.FacingLeft = false;
                        move = true;
                    }

                    DDEngine.FreezeInputFrame = freezeInputFrameBackup;                     // restore

                    if (1 <= DDInput.L.GetInput())
                    {
                        move     = false;
                        camSlide = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.R.GetInput())
                    {
                        slow = true;
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.A.GetInput())
                    {
                        jump = DDInput.A.GetInput();
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.B.GetInput())
                    {
                        attack = DDInput.B.GetInput();
                    }
                    if (!deadOrDamageOrUID && 1 <= DDInput.C.GetInput())
                    {
                        extendedAttack = DDInput.C.GetInput();
                    }

                    if (move)
                    {
                        this.Player.MoveFrame++;
                        shagami = false;
                    }
                    else
                    {
                        this.Player.MoveFrame = 0;
                    }

                    this.Player.MoveSlow = move && slow;

                    if (1 <= this.Player.JumpFrame)
                    {
                        if (1 <= jump)
                        {
                            this.Player.JumpFrame++;
                        }
                        else
                        {
                            // ★ ジャンプを中断・終了した。

                            this.Player.JumpFrame = 0;

                            if (this.Player.YSpeed < 0.0)
                            {
                                this.Player.YSpeed /= 2.0;
                            }
                        }
                    }
                    else
                    {
                        // 事前入力 == 着地前の数フレーム間にジャンプボタンを押し始めてもジャンプできるようにする。
                        // 入力猶予 == 落下(地面から離れた)直後の数フレーム間にジャンプボタンを押し始めてもジャンプできるようにする。

                        const int 事前入力時間 = 5;
                        const int 入力猶予時間 = 10;

                        if (this.Player.AirborneFrame < 入力猶予時間)                         // ? 接地状態からのジャンプが可能な状態
                        {
                            if (1 <= jump && jump < 事前入力時間)
                            {
                                // ★ ジャンプを開始した。

                                this.Player.JumpFrame = 1;
                                this.Player.JumpCount = 1;

                                this.Player.YSpeed = GameConsts.PLAYER_ジャンプ初速度;
                            }
                            else
                            {
                                this.Player.JumpCount = 0;
                            }
                        }
                        else                         // ? 接地状態からのジャンプが「可能ではない」状態
                        {
                            // 滞空状態に入ったら「通常ジャンプの状態」にする。
                            if (this.Player.JumpCount < 1)
                            {
                                this.Player.JumpCount = 1;
                            }

                            if (1 <= jump && jump < 事前入力時間 && this.Player.JumpCount < GameConsts.JUMP_MAX)
                            {
                                // ★ 空中(n-段)ジャンプを開始した。

                                this.Player.JumpFrame = 1;
                                this.Player.JumpCount++;

                                this.Player.YSpeed = GameConsts.PLAYER_ジャンプ初速度;

                                DDGround.EL.Add(SCommon.Supplier(Effects.空中ジャンプの足場(this.Player.X, this.Player.Y + 48)));
                            }
                            else
                            {
                                // noop
                            }
                        }
                    }

                    if (camSlide)
                    {
                        if (DDInput.DIR_4.IsPound())
                        {
                            this.CamSlided = true;
                            this.CamSlideX--;
                        }
                        if (DDInput.DIR_6.IsPound())
                        {
                            this.CamSlided = true;
                            this.CamSlideX++;
                        }
                        if (DDInput.DIR_8.IsPound())
                        {
                            this.CamSlided = true;
                            this.CamSlideY--;
                        }
                        if (DDInput.DIR_2.IsPound())
                        {
                            this.CamSlided = true;
                            this.CamSlideY++;
                        }
                        DDUtils.ToRange(ref this.CamSlideX, -1, 1);
                        DDUtils.ToRange(ref this.CamSlideY, -1, 1);
                    }
                    else
                    {
                        if (this.CamSlideMode && !this.CamSlided)
                        {
                            this.CamSlideX = 0;
                            this.CamSlideY = 0;
                        }
                        this.CamSlided = false;
                    }
                    this.CamSlideMode = camSlide;

                    if (this.Player.AirborneFrame != 0)                     // ? 滞空状態
                    {
                        shagami = false;
                    }

                    if (shagami)
                    {
                        this.Player.ShagamiFrame++;
                    }
                    else
                    {
                        this.Player.ShagamiFrame = 0;
                    }

                    {
                        const int 事前入力時間 = 2;                         // 無効
                        //const int 事前入力時間 = 5;
                        //const int 事前入力時間 = 10; // HACK: ちょっと長すぎるかもしれない。無効でも良いかもしれない。// 暴発があるので事前入力は無効にする。

                        if (1 <= attack && attack < 事前入力時間)
                        {
                            switch (this.Player.Chara)
                            {
                            case Player.Chara_e.HOMURA:
                            {
                                if (this.Player.AirborneFrame == 0)
                                {
                                    this.Player.Attack = new Attack_ほむら接地攻撃();
                                }
                                else
                                {
                                    this.Player.Attack = new Attack_ほむら滞空攻撃();
                                }
                            }
                            break;

                            case Player.Chara_e.SAYAKA:
                            {
                                if (this.Player.AirborneFrame == 0)
                                {
                                    this.Player.Attack = new Attack_さやか接地攻撃();
                                }
                                else
                                {
                                    this.Player.Attack = new Attack_さやか滞空攻撃();
                                }
                            }
                            break;

                            default:
                                throw null;                                         // never
                            }
                        }
                        if (1 <= extendedAttack && extendedAttack < 事前入力時間)
                        {
                            switch (this.Player.Chara)
                            {
                            case Player.Chara_e.HOMURA:
                            {
                                if (this.Player.AirborneFrame == 0)
                                {
                                    this.Player.Attack = new Attack_ほむらシールド();
                                }
                            }
                            break;

                            case Player.Chara_e.SAYAKA:
                            {
                                this.Player.Attack = new Attack_さやか突き();
                            }
                            break;

                            default:
                                throw null;                                         // never
                            }
                        }
                    }
                }

startDead:
                if (1 <= this.Player.DeadFrame)                 // プレイヤー死亡中の処理
                {
                    int frame = this.Player.DeadFrame - 1;

                    if (GameConsts.PLAYER_DEAD_FRAME_MAX < frame)
                    {
                        this.Player.DeadFrame     = 0;
                        this.Status.ExitDirection = 5;
                        break;
                    }
                    this.Player.DeadFrame++;

                    // この時点でとりうる this.Player.DeadFrame の最大値は Consts.PLAYER_DEAD_FRAME_MAX + 2

                    // ----

                    // noop
                }
                //endDead:

                //startDamage:
                if (1 <= this.Player.DamageFrame)                 // プレイヤー・ダメージ中の処理
                {
                    int frame = this.Player.DamageFrame - 1;

                    if (GameConsts.PLAYER_DAMAGE_FRAME_MAX < frame)
                    {
                        this.Player.DamageFrame = 0;

                        if (1 <= this.Player.HP)
                        {
                            this.Player.InvincibleFrame = 1;
                            goto endDamage;
                        }
                        else
                        {
                            this.Player.DeadFrame = 1;
                            goto startDead;
                        }
                    }
                    this.Player.DamageFrame++;

                    // この時点でとりうる this.Player.DamageFrame の最大値は Consts.PLAYER_DAMAGE_FRAME_MAX + 2

                    // ----

                    {
                        double rate = (double)frame / GameConsts.PLAYER_DAMAGE_FRAME_MAX;

                        this.Player.X -= (9.0 - 6.0 * rate) * (this.Player.FacingLeft ? -1 : 1);
                    }
                }
endDamage:

                //startInvincible:
                if (1 <= this.Player.InvincibleFrame)                 // プレイヤー無敵時間中の処理
                {
                    int frame = this.Player.InvincibleFrame - 1;

                    if (GameConsts.PLAYER_INVINCIBLE_FRAME_MAX < frame)
                    {
                        this.Player.InvincibleFrame = 0;
                        goto endInvincible;
                    }
                    this.Player.InvincibleFrame++;

                    // この時点でとりうる this.Player.InvincibleFrame の最大値は Consts.PLAYER_INVINCIBLE_FRAME_MAX + 2

                    // ----

                    // noop
                }
endInvincible:

                // プレイヤー移動
                {
                    if (1 <= this.Player.MoveFrame)
                    {
                        double speed = 0.0;

                        if (this.Player.MoveSlow)
                        {
                            speed = this.Player.MoveFrame / 10.0;
                            DDUtils.Minim(ref speed, GameConsts.PLAYER_SLOW_SPEED);
                        }
                        else
                        {
                            speed = GameConsts.PLAYER_SPEED;
                        }

                        speed *= this.Player.FacingLeft ? -1 : 1;

                        this.Player.X += speed;
                    }
                    else
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X);
                    }

                    // 重力による加速
                    this.Player.YSpeed += GameConsts.PLAYER_GRAVITY;

                    // 自由落下の最高速度を超えないように矯正
                    DDUtils.Minim(ref this.Player.YSpeed, GameConsts.PLAYER_FALL_SPEED_MAX);

                    // 自由落下
                    this.Player.Y += this.Player.YSpeed;
                }

                // プレイヤー位置矯正
                {
                    bool touchSide_L =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y - GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y + GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall();

                    bool touchSide_R =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y - GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y + GameConsts.PLAYER_側面判定Pt_Y)).Tile.IsWall();

                    if (touchSide_L && touchSide_R)                     // -> 壁抜け防止のため再チェック
                    {
                        touchSide_L = this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall();
                        touchSide_R = this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_側面判定Pt_X, this.Player.Y)).Tile.IsWall();
                    }

                    if (touchSide_L && touchSide_R)
                    {
                        // noop
                    }
                    else if (touchSide_L)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W + GameConsts.PLAYER_側面判定Pt_X;
                    }
                    else if (touchSide_R)
                    {
                        this.Player.X = (double)SCommon.ToInt(this.Player.X / GameConsts.TILE_W) * GameConsts.TILE_W - GameConsts.PLAYER_側面判定Pt_X;
                    }

                    bool touchCeiling =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_脳天判定Pt_X, this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_脳天判定Pt_X, this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y)).Tile.IsWall();

                    if (touchCeiling)
                    {
                        if (this.Player.YSpeed < 0.0)
                        {
                            double plY = ((int)((this.Player.Y - GameConsts.PLAYER_脳天判定Pt_Y) / GameConsts.TILE_H) + 1) * GameConsts.TILE_H + GameConsts.PLAYER_脳天判定Pt_Y;

                            this.Player.Y      = plY;
                            this.Player.YSpeed = 0.0;
                        }
                    }

                    bool touchGround =
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X - GameConsts.PLAYER_接地判定Pt_X, this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y)).Tile.IsWall() ||
                        this.Map.GetCell(GameCommon.ToTablePoint(this.Player.X + GameConsts.PLAYER_接地判定Pt_X, this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y)).Tile.IsWall();

                    if (touchGround)
                    {
                        if (0.0 < this.Player.YSpeed)
                        {
                            double plY = (int)((this.Player.Y + GameConsts.PLAYER_接地判定Pt_Y) / GameConsts.TILE_H) * GameConsts.TILE_H - GameConsts.PLAYER_接地判定Pt_Y;

                            this.Player.Y      = plY;
                            this.Player.YSpeed = 0.0;
                        }
                    }

                    if (touchGround)
                    {
                        this.Player.AirborneFrame = 0;
                    }
                    else
                    {
                        this.Player.AirborneFrame++;
                    }
                }
endPlayer:

                if (this.Player.X < 0.0)                 // ? マップの左側に出た。
                {
                    this.Status.ExitDirection = 4;
                    break;
                }
                if (this.Map.W * GameConsts.TILE_W < this.Player.X)                 // ? マップの右側に出た。
                {
                    this.Status.ExitDirection = 6;
                    break;
                }
                if (this.Player.Y < 0.0)                 // ? マップの上側に出た。
                {
                    this.Status.ExitDirection = 8;
                    break;
                }
                if (this.Map.H * GameConsts.TILE_H < this.Player.Y)                 // ? マップの下側に出た。
                {
                    this.Status.ExitDirection = 2;
                    break;
                }

                // 画面遷移時の微妙なカメラ位置ズレ解消
                // -- スタート地点(入場地点)が地面と接していると、最初のフレームでプレイヤーは上に押し出されてカメラの初期位置とズレてしまう。
                if (this.Frame == 0)
                {
                    this.カメラ位置調整(true);
                }

                DDCrash plCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y));

                // ====
                // 描画ここから
                // ====

                this.DrawWall();
                this.DrawMap();
                this.Player.Draw();

                // memo: DeadFlag をチェックするのは「当たり判定」から

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    enemy.Crash = DDCrashUtils.None();                     // reset
                    enemy.Draw();
                }
                foreach (Shot shot in this.Shots.Iterate())
                {
                    shot.Crash = DDCrashUtils.None();                     // reset
                    shot.Draw();
                }

                if (this.当たり判定表示)
                {
                    // 最後に描画されるように DDGround.EL.Add() する。

                    DDGround.EL.Add(() =>
                    {
                        DDCurtain.DrawCurtain(-0.7);

                        const double A = 0.7;

                        DDCrashView.Draw(new DDCrash[] { plCrash }, new I3Color(255, 0, 0), 1.0);
                        DDCrashView.Draw(this.Enemies.Iterate().Select(v => v.Crash), new I3Color(255, 255, 255), A);
                        DDCrashView.Draw(this.Shots.Iterate().Select(v => v.Crash), new I3Color(0, 255, 255), A);

                        return(false);
                    });
                }

                // ====
                // 描画ここまで
                // ====

                // ====
                // 当たり判定ここから
                // ====

                // ? 無敵な攻撃中 -> 敵 x 自機 の衝突判定を行わない。
                bool attackInvincibleMode =
                    Game.I.Player.Attack != null &&
                    Game.I.Player.Attack.IsInvincibleMode();

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    if (1 <= enemy.HP)                     // ? 敵:生存 && 無敵ではない
                    {
                        foreach (Shot shot in this.Shots.Iterate())
                        {
                            // 衝突判定:敵 x 自弾
                            if (
                                !shot.DeadFlag &&                                 // ? 自弾:生存
                                enemy.Crash.IsCrashed(shot.Crash)                 // ? 衝突
                                )
                            {
                                // ★ 敵_被弾ここから

                                if (!shot.敵を貫通する)
                                {
                                    shot.Kill();
                                }

                                enemy.HP -= shot.AttackPoint;

                                if (1 <= enemy.HP)                                 // ? まだ生存している。
                                {
                                    enemy.Damaged(shot);
                                }
                                else                                 // ? 撃破した。
                                {
                                    enemy.Kill(true);
                                    break;                                     // この敵は死亡したので、この敵について以降の当たり判定は不要
                                }

                                // ★ 敵_被弾ここまで
                            }
                        }
                    }

                    // 衝突判定:敵 x 自機
                    if (
                        this.Player.DeadFrame == 0 &&                // ? プレイヤー死亡中ではない。
                        this.Player.DamageFrame == 0 &&              // ? プレイヤー・ダメージ中ではない。
                        this.Player.InvincibleFrame == 0 &&          // ? プレイヤー無敵時間中ではない。
                        !attackInvincibleMode &&                     // 無敵になる攻撃中ではない。
                        !enemy.DeadFlag &&                           // ? 敵:生存
                        DDCrashUtils.IsCrashed(enemy.Crash, plCrash) // ? 衝突
                        )
                    {
                        // ★ 自機_被弾ここから

                        if (enemy.自機に当たると消滅する)
                        {
                            enemy.Kill();
                        }

                        this.Player.HP -= enemy.AttackPoint;

                        if (1 <= this.Player.HP)                         // ? まだ生存している。
                        {
                            this.Player.DamageFrame = 1;
                        }
                        else                         // ? 死亡した。
                        {
                            this.Player.HP = -1;
                            //this.Player.DeadFrame = 1; // ヒットバックした後で死亡フレームを上げる。
                            this.Player.DamageFrame = 1;
                        }

                        // ★ 自機_被弾ここまで
                    }
                }

                foreach (Shot shot in this.Shots.Iterate())
                {
                    // 壁への当たり判定は自弾の「中心座標のみ」であることに注意して下さい。

                    if (
                        !shot.DeadFlag &&                                                       // ? 自弾:生存
                        !shot.壁をすり抜ける &&                                                        // ? この自弾は壁に当たる。
                        this.Map.GetCell(GameCommon.ToTablePoint(shot.X, shot.Y)).Tile.IsWall() // ? 壁に当たった。
                        )
                    {
                        shot.Kill();
                    }
                }

                // ====
                // 当たり判定ここまで
                // ====

                f_ゴミ回収();

                this.Enemies.RemoveAll(v => v.DeadFlag);
                this.Shots.RemoveAll(v => v.DeadFlag);

                DDEngine.EachFrame();

                // ★★★ ゲームループの終わり ★★★
            }

            DDEngine.FreezeInput();

            if (this.Status.ExitDirection == 5)
            {
                DDMusicUtils.Fade();
                DDCurtain.SetCurtain(30, -1.0);

                foreach (DDScene scene in DDSceneUtils.Create(40))
                {
                    this.DrawWall();
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
            }
            else
            {
                double destSlide_X = 0.0;
                double destSlide_Y = 0.0;

                switch (this.Status.ExitDirection)
                {
                case 4:
                    destSlide_X = DDConsts.Screen_W;
                    break;

                case 6:
                    destSlide_X = -DDConsts.Screen_W;
                    break;

                case 8:
                    destSlide_Y = DDConsts.Screen_H;
                    break;

                case 2:
                    destSlide_Y = -DDConsts.Screen_H;
                    break;

                default:
                    throw null;                             // never
                }
                using (DDSubScreen wallMapScreen = new DDSubScreen(DDConsts.Screen_W, DDConsts.Screen_H))
                {
                    using (wallMapScreen.Section())
                    {
                        this.DrawWall();
                        this.DrawMap();
                    }
                    foreach (DDScene scene in DDSceneUtils.Create(30))
                    {
                        double slide_X = destSlide_X * scene.Rate;
                        double slide_Y = destSlide_Y * scene.Rate;

                        DDCurtain.DrawCurtain();
                        DDDraw.DrawSimple(wallMapScreen.ToPicture(), slide_X, slide_Y);

                        DDEngine.EachFrame();
                    }
                }
                DDCurtain.SetCurtain(0, -1.0);
            }

            // ★★★★★
            // プレイヤー・ステータス反映(マップ退場時)
            // その他の反映箇所:
            // -- マップ入場時
            // -- セーブ時
            {
                this.Status.StartChara      = this.Player.Chara;
                this.Status.StartHP         = this.Player.HP;
                this.Status.StartFacingLeft = this.Player.FacingLeft;
            }

            // ★★★ end of Perform() ★★★
        }
Example #11
0
        public void Perform()
        {
            this.ReloadEnemies();

            // デフォルトのスタート位置
            this.Player.X = this.Map.W * MapTile.WH / 2.0;
            this.Player.Y = this.Map.H * MapTile.WH / 2.0;

            foreach (EnemyBox enemy in this.Enemies.Iterate())             // スタート位置
            {
                StartPoint sp = enemy.Value as StartPoint;

                if (sp != null)
                {
                    if (sp.Index == this.Status.StartPointIndex)
                    {
                        this.Player.X = sp.X;
                        this.Player.Y = sp.Y;
                        break;
                    }
                }
            }

            this.Player.HP         = this.Status.CurrHP;
            this.Player.FacingLeft = this.Status.FacingLeft;

            this.WallPicture = WallPictureManager.GetPicutre(this.Map.GetProperty("WALL", "09311.jpg"));

            {
                double w = DDConsts.Screen_W + (this.Map.W * MapTile.WH - DDConsts.Screen_W) * WallPicture_SlideRate;
                double h = DDConsts.Screen_H + (this.Map.H * MapTile.WH - DDConsts.Screen_H) * WallPicture_SlideRate;

                double zw = w / this.WallPicture.Get_W();
                double zh = h / this.WallPicture.Get_H();

                double z = Math.Max(zw, zh);

                z *= 1.01;                 // margin

                this.WallPicture_Zoom = z;
            }

            DDGround.Camera.X = this.Player.X - DDConsts.Screen_W / 2.0;
            DDGround.Camera.Y = this.Player.Y - DDConsts.Screen_H / 2.0;

            DDCurtain.SetCurtain(10);
            DDEngine.FreezeInput();

            // TODO music

            for (; ; this.Frame++)
            {
                {
                    double targCamX = this.Player.X - DDConsts.Screen_W / 2 + (this.CamSlideX * DDConsts.Screen_W / 3);
                    double targCamY = this.Player.Y - DDConsts.Screen_H / 2 + (this.CamSlideY * DDConsts.Screen_H / 3);

                    DDUtils.ToRange(ref targCamX, 0.0, this.Map.W * MapTile.WH - DDConsts.Screen_W);
                    DDUtils.ToRange(ref targCamY, 0.0, this.Map.H * MapTile.WH - DDConsts.Screen_H);

                    DDUtils.Approach(ref DDGround.Camera.X, targCamX, 0.8);
                    DDUtils.Approach(ref DDGround.Camera.Y, targCamY, 0.8);
                }

                DDUtils.ToRange(ref DDGround.Camera.X, 0.0, this.Map.W * MapTile.WH - DDConsts.Screen_W);
                DDUtils.ToRange(ref DDGround.Camera.Y, 0.0, this.Map.H * MapTile.WH - DDConsts.Screen_H);

                DDGround.ICamera.X = DoubleTools.ToInt(DDGround.Camera.X);
                DDGround.ICamera.Y = DoubleTools.ToInt(DDGround.Camera.Y);

                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_E) == 1)
                {
                    this.EditMode();
                    this.ReloadEnemies();
                    this.Frame = 0;
                }

                // プレイヤー入力
                {
                    bool deadOrDamage = this.Player.DeadScene.IsFlaming() || this.Player.DamageScene.IsFlaming();
                    bool move         = false;
                    bool slow         = false;
                    bool camSlide     = false;
                    int  jumpPress    = DDInput.A.GetInput();
                    bool jump         = false;
                    bool shagami      = false;
                    bool attack       = false;

                    if (!deadOrDamage && 1 <= DDInput.DIR_2.GetInput())
                    {
                        shagami = true;
                    }
                    if (!deadOrDamage && 1 <= DDInput.DIR_4.GetInput())
                    {
                        this.Player.FacingLeft = true;
                        move = true;
                    }
                    if (!deadOrDamage && 1 <= DDInput.DIR_6.GetInput())
                    {
                        this.Player.FacingLeft = false;
                        move = true;
                    }
                    if (1 <= DDInput.L.GetInput())
                    {
                        move     = false;
                        camSlide = true;
                    }
                    if (!deadOrDamage && 1 <= DDInput.R.GetInput())
                    {
                        slow = true;
                    }
                    if (!deadOrDamage && 1 <= jumpPress)
                    {
                        jump = true;
                    }
                    if (!deadOrDamage && 1 <= DDInput.B.GetInput())
                    {
                        attack = true;
                    }
                    if (DDKey.GetInput(DX.KEY_INPUT_Q) == 1)
                    {
                        break;
                    }

                    if (move)
                    {
                        this.Player.MoveFrame++;
                        shagami = false;
                    }
                    else
                    {
                        this.Player.MoveFrame = 0;
                    }

                    this.Player.MoveSlow = move && slow;

                    if (1 <= this.Player.JumpFrame)
                    {
                        if (jump && this.Player.JumpFrame < 22)
                        {
                            this.Player.JumpFrame++;
                        }
                        else
                        {
                            this.Player.JumpFrame = 0;
                        }
                    }
                    else
                    {
                        //if (jump && jumpPress < 5 && this.Player.TouchGround)
                        if (jump && jumpPress < 5 && this.Player.AirborneFrame < 5)
                        {
                            this.Player.JumpFrame = 1;
                        }
                    }

                    if (camSlide)
                    {
                        if (DDInput.DIR_4.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideX--;
                        }
                        if (DDInput.DIR_6.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideX++;
                        }
                        if (DDInput.DIR_8.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideY--;
                        }
                        if (DDInput.DIR_2.IsPound())
                        {
                            this.CamSlideCount++;
                            this.CamSlideY++;
                        }
                        DDUtils.ToRange(ref this.CamSlideX, -1, 1);
                        DDUtils.ToRange(ref this.CamSlideY, -1, 1);
                    }
                    else
                    {
                        if (this.CamSlideMode && this.CamSlideCount == 0)
                        {
                            this.CamSlideX = 0;
                            this.CamSlideY = 0;
                        }
                        this.CamSlideCount = 0;
                    }
                    this.CamSlideMode = camSlide;

                    if (this.Player.TouchGround == false)
                    {
                        shagami = false;
                    }

                    if (shagami)
                    {
                        this.Player.ShagamiFrame++;
                    }
                    else
                    {
                        this.Player.ShagamiFrame = 0;
                    }

                    if (attack)
                    {
                        this.Player.AttackFrame++;
                    }
                    else
                    {
                        this.Player.AttackFrame = 0;
                    }
                }

                {
                    DDScene scene = this.Player.DeadScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        if (scene.Numer < 30)
                        {
                            double rate = scene.Numer / 30.0;

                            this.Player.X -= 10.0 * (1.0 - rate) * (this.Player.FacingLeft ? -1 : 1);
                        }

                        if (scene.Remaining == 0)
                        {
                            break;
                        }
                    }
                }

                {
                    DDScene scene = this.Player.DamageScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        this.Player.X -= (9.0 - 6.0 * scene.Rate) * (this.Player.FacingLeft ? -1 : 1);

                        if (scene.Remaining == 0)
                        {
                            this.Player.MutekiScene.FireDelay();
                        }
                    }
                }

                {
                    DDScene scene = this.Player.MutekiScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        // noop
                    }
                }

                // プレイヤー移動
                {
                    if (1 <= this.Player.MoveFrame)
                    {
                        double speed = 0.0;

                        if (this.Player.MoveSlow)
                        {
                            speed = this.Player.MoveFrame * 0.2;
                            DDUtils.Minim(ref speed, 2.0);
                        }
                        else
                        {
                            speed = 6.0;
                        }

                        speed *= this.Player.FacingLeft ? -1 : 1;

                        this.Player.X += speed;
                    }
                    else
                    {
                        this.Player.X = (double)DoubleTools.ToInt(this.Player.X);
                    }

                    this.Player.YSpeed += 1.0;                     // += 重力加速度

                    if (1 <= this.Player.JumpFrame)
                    {
                        this.Player.YSpeed = -8.0;
                    }

                    DDUtils.Minim(ref this.Player.YSpeed, 8.0);                     // 落下する最高速度

                    this.Player.Y += this.Player.YSpeed;
                }

                if (this.Player.X < 0.0)                 // ? マップの左側に出た。
                {
                    this.ExitDir = 4;
                    break;
                }
                if (this.Map.W * MapTile.WH < this.Player.X)                 // ? マップの右側に出た。
                {
                    this.ExitDir = 6;
                    break;
                }
                if (this.Player.Y < 0.0)                 // ? マップの上側に出た。
                {
                    this.ExitDir = 8;
                    break;
                }
                if (this.Map.H * MapTile.WH < this.Player.Y)                 // ? マップの下側に出た。
                {
                    this.ExitDir = 2;
                    break;
                }

                // プレイヤー位置矯正
                {
                    bool touchSide_L =
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X - 10.0, this.Player.Y - MapTile.WH / 2)).Wall ||
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X - 10.0, this.Player.Y)).Wall ||
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X - 10.0, this.Player.Y + MapTile.WH / 2)).Wall;

                    bool touchSide_R =
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X + 10.0, this.Player.Y - MapTile.WH / 2)).Wall ||
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X + 10.0, this.Player.Y)).Wall ||
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X + 10.0, this.Player.Y + MapTile.WH / 2)).Wall;

                    if (touchSide_L && touchSide_R)
                    {
                        // noop
                    }
                    else if (touchSide_L)
                    {
                        this.Player.X = (double)DoubleTools.ToInt(this.Player.X / MapTile.WH) * MapTile.WH + 10.0;
                    }
                    else if (touchSide_R)
                    {
                        this.Player.X = (double)DoubleTools.ToInt(this.Player.X / MapTile.WH) * MapTile.WH - 10.0;
                    }

                    bool touchCeiling_L = this.Map.GetCell(Map.ToTablePoint(this.Player.X - 9.0, this.Player.Y - MapTile.WH)).Wall;
                    bool touchCeiling_R = this.Map.GetCell(Map.ToTablePoint(this.Player.X + 9.0, this.Player.Y - MapTile.WH)).Wall;
                    bool touchCeiling   = touchCeiling_L && touchCeiling_R;

                    if (touchCeiling_L && touchCeiling_R)
                    {
                        if (this.Player.YSpeed < 0.0)
                        {
                            this.Player.Y         = (int)(this.Player.Y / MapTile.WH + 1) * MapTile.WH;
                            this.Player.YSpeed    = 0.0;
                            this.Player.JumpFrame = 0;
                        }
                    }
                    else if (touchCeiling_L)
                    {
                        this.Player.X = (double)DoubleTools.ToInt(this.Player.X / MapTile.WH) * MapTile.WH + 9.0;
                    }
                    else if (touchCeiling_R)
                    {
                        this.Player.X = (double)DoubleTools.ToInt(this.Player.X / MapTile.WH) * MapTile.WH - 9.0;
                    }

                    this.Player.TouchGround =
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X - 9.0, this.Player.Y + MapTile.WH)).Wall ||
                        this.Map.GetCell(Map.ToTablePoint(this.Player.X + 9.0, this.Player.Y + MapTile.WH)).Wall;

                    if (this.Player.TouchGround)
                    {
                        DDUtils.Minim(ref this.Player.YSpeed, 0.0);

                        double plY = (int)(this.Player.Y / MapTile.WH) * MapTile.WH;

                        DDUtils.Minim(ref this.Player.Y, plY);
                    }

                    if (this.Player.TouchGround)
                    {
                        this.Player.AirborneFrame = 0;
                    }
                    else
                    {
                        this.Player.AirborneFrame++;
                    }
                }

                if (this.Frame == 0)                 // 画面遷移時の微妙なカメラ位置ズレ解消
                {
                    DDGround.Camera.X = this.Player.X - DDConsts.Screen_W / 2.0;
                    DDGround.Camera.Y = this.Player.Y - DDConsts.Screen_H / 2.0;

                    DDUtils.ToRange(ref DDGround.Camera.X, 0.0, this.Map.W * MapTile.WH - DDConsts.Screen_W);
                    DDUtils.ToRange(ref DDGround.Camera.Y, 0.0, this.Map.H * MapTile.WH - DDConsts.Screen_H);

                    DDGround.ICamera.X = DoubleTools.ToInt(DDGround.Camera.X);
                    DDGround.ICamera.Y = DoubleTools.ToInt(DDGround.Camera.Y);
                }

                if (1 <= this.Player.AttackFrame)
                {
                    this.Player.Attack();
                }

                this.EnemyEachFrame();
                this.WeaponEachFrame();

                // Crash
                {
                    DDCrash playerCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y));

                    foreach (WeaponBox weapon in this.Weapons.Iterate())
                    {
                        weapon.Crash = weapon.Value.GetCrash();
                    }

                    foreach (EnemyBox enemy in this.Enemies.Iterate())
                    {
                        DDCrash enemyCrash = enemy.Value.GetCrash();

                        foreach (WeaponBox weapon in this.Weapons.Iterate())
                        {
                            if (enemyCrash.IsCrashed(weapon.Crash))
                            {
                                if (enemy.Value.Crashed(weapon.Value) == false)                                 // ? 消滅
                                {
                                    enemy.Dead = true;
                                }

                                if (weapon.Value.Crashed(enemy.Value) == false)                                 // ? 消滅
                                {
                                    weapon.Dead = true;
                                }
                            }
                        }
                        this.Weapons.RemoveAll(weapon => weapon.Dead);

                        if (this.Player.DeadScene.IsFlaming() == false &&
                            this.Player.DamageScene.IsFlaming() == false &&
                            this.Player.MutekiScene.IsFlaming() == false && enemyCrash.IsCrashed(playerCrash))
                        {
                            if (enemy.Value.CrashedToPlayer() == false)                             // ? 消滅
                            {
                                enemy.Dead = true;
                            }

                            this.Player.Crashed(enemy.Value);
                        }
                    }
                    this.Enemies.RemoveAll(enemy => enemy.Dead);
                }

                // 描画ここから

                this.DrawWall();
                this.DrawMap();
                this.Player.Draw();
                this.DrawEnemies();
                this.DrawWeapons();

                DDPrint.SetPrint();
                DDPrint.Print(DDEngine.FrameProcessingMillis_Worst + " " + this.Player.HP);

                DDEngine.EachFrame();
            }
            DDEngine.FreezeInput();

            if (this.ExitDir == 5)
            {
                DDMusicUtils.Fade();
                DDCurtain.SetCurtain(30, -1.0);

                foreach (DDScene scene in DDSceneUtils.Create(40))
                {
                    this.DrawWall();
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
            }
            else
            {
                double destSlideX = 0.0;
                double destSlideY = 0.0;

                switch (this.ExitDir)
                {
                case 4:
                    destSlideX = DDConsts.Screen_W;
                    break;

                case 6:
                    destSlideX = -DDConsts.Screen_W;
                    break;

                case 8:
                    destSlideY = DDConsts.Screen_H;
                    break;

                case 2:
                    destSlideY = -DDConsts.Screen_H;
                    break;

                default:
                    throw null;                             // never
                }
#if true
                using (DDSubScreen wallScreen = new DDSubScreen(DDConsts.Screen_W, DDConsts.Screen_H))
                {
                    using (wallScreen.Section())
                    {
                        this.DrawWall();
                    }

                    foreach (DDScene scene in DDSceneUtils.Create(30))
                    {
                        this.DrawMap_SlideX = destSlideX * scene.Rate;
                        this.DrawMap_SlideY = destSlideY * scene.Rate;

                        DDCurtain.DrawCurtain();
                        DDDraw.DrawSimple(wallScreen.ToPicture(), this.DrawMap_SlideX, this.DrawMap_SlideY);
                        this.DrawMap();

                        DDEngine.EachFrame();
                    }
                }
#else // old
                foreach (DDScene scene in DDSceneUtils.Create(10))
                {
                    this.DrawWall();
                    DDCurtain.DrawCurtain(-scene.Rate);
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
                foreach (DDScene scene in DDSceneUtils.Create(20))
                {
                    this.DrawMap_SlideX = destSlideX * scene.Rate;
                    this.DrawMap_SlideY = destSlideY * scene.Rate;

                    DDCurtain.DrawCurtain(-1.0);
                    this.DrawMap();

                    DDEngine.EachFrame();
                }
#endif
                this.DrawMap_SlideX = 0.0;                 // 復元
                this.DrawMap_SlideY = 0.0;                 // 復元

                DDCurtain.SetCurtain(0, -1.0);
            }

            // ここでステータスに反映

            this.Status.CurrHP     = this.Player.HP;
            this.Status.FacingLeft = this.Player.FacingLeft;
        }
Example #12
0
        public void Perform()
        {
            DDCurtain.SetCurtain(0, -1.0);
            DDCurtain.SetCurtain();

restartCurrPage:
            this.CurrPage = this.Status.Scenario.Pages[this.Status.CurrPageIndex];

            foreach (ScenarioCommand command in this.CurrPage.Commands)
            {
                command.Invoke();
            }

            int  dispSubtitleCharCount = 0;
            int  dispCharCount         = 0;
            int  dispPageEndedCount    = 0;
            bool dispFastMode          = false;

            DDEngine.FreezeInput();

            for (; ;)
            {
                DDMouse.UpdatePos();

                // キー押下は 1 マウス押下は -1 で判定する。

                // 入力:シナリオを進める。
                if (
                    DDMouse.L.GetInput() == -1 ||
                    DDInput.A.GetInput() == 1 ||
                    DDKey.GetInput(DX.KEY_INPUT_SPACE) == 1 ||
                    DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1
                    )
                {
                    if (dispPageEndedCount < NEXT_PAGE_KEY_INTERVAL)                     // ? ページ表示_未完了 -> ページ表示_高速化
                    {
                        dispFastMode = true;
                    }
                    else                     // ? ページ表示_完了 -> 次ページ
                    {
                        this.Status.CurrPageIndex++;

                        if (this.Status.Scenario.Pages.Count <= this.Status.CurrPageIndex)
                        {
                            break;
                        }

                        goto restartCurrPage;
                    }
                }

                if (
                    this.CurrPage.Subtitle.Length < dispSubtitleCharCount &&
                    this.CurrPage.Text.Length < dispCharCount
                    )
                {
                    dispPageEndedCount++;
                }

                if (dispFastMode)
                {
                    dispSubtitleCharCount += 2;
                    dispCharCount         += 2;
                }
                else
                {
                    if (DDEngine.ProcFrame % 2 == 0)
                    {
                        dispSubtitleCharCount++;
                    }

                    if (DDEngine.ProcFrame % 3 == 0)
                    {
                        dispCharCount++;
                    }
                }
                DDUtils.ToRange(ref dispSubtitleCharCount, 0, IntTools.IMAX);
                DDUtils.ToRange(ref dispCharCount, 0, IntTools.IMAX);

                // ====
                // 描画ここから
                // ====

                this.DrawSurfaces();

                // メッセージ枠
                {
                    const int h = 136;

                    DDDraw.SetAlpha(0.9);
                    DDDraw.DrawRect(Ground.I.Picture.MessageFrame_Message, 0, DDConsts.Screen_H - h, DDConsts.Screen_W, h);
                    DDDraw.Reset();
                }

                // システムボタン
                {
                    const double BUTTON_L      = 530.5;                // 素材の幅が奇数なので n + 0.5
                    const double BUTTON_T      = 412.5;                // 素材の高さも奇数なので n + 0.5
                    const double BUTTON_X_STEP = 78.0;

                    DDPicture[] buttons = new DDPicture[]
                    {
                        Ground.I.Picture.MessageFrame_Save,
                        Ground.I.Picture.MessageFrame_Load,
                        Ground.I.Picture.MessageFrame_Skip,
                        Ground.I.Picture.MessageFrame_Auto,
                        Ground.I.Picture.MessageFrame_Log,
                        Ground.I.Picture.MessageFrame_Menu,
                        //Ground.I.Picture.MessageFrame_Close,
                        //Ground.I.Picture.MessageFrame_Config,
                        //Ground.I.Picture.MessageFrame_QLoad,
                        //Ground.I.Picture.MessageFrame_QSave,
                        //Ground.I.Picture.MessageFrame_Screen,
                        //Ground.I.Picture.MessageFrame_Title,
                    };

                    for (int index = 0; index < buttons.Length; index++)
                    {
                        DDDraw.DrawCenter(buttons[index], BUTTON_L + index * BUTTON_X_STEP, BUTTON_T);
                    }
                }

                // サブタイトル文字列
                {
                    int    dispSubtitleLength = Math.Min(dispCharCount, this.CurrPage.Subtitle.Length);
                    string dispSubtitle       = this.CurrPage.Subtitle.Substring(0, dispSubtitleLength);

                    DDFontUtils.DrawString(120, 320, dispSubtitle, DDFontUtils.GetFont("Kゴシック", 16));
                }

                // シナリオのテキスト文字列
                {
                    int      dispTextLength = Math.Min(dispCharCount, this.CurrPage.Text.Length);
                    string   dispText       = this.CurrPage.Text.Substring(0, dispTextLength);
                    string[] dispLines      = dispText.Split('\n');

                    for (int index = 0; index < dispLines.Length; index++)
                    {
                        DDFontUtils.DrawString(10, 450 + index * 30, dispLines[index], DDFontUtils.GetFont("Kゴシック", 16), false, new I3Color(110, 100, 90));
                    }
                }

                DDEngine.EachFrame();
            }

            DDCurtain.SetCurtain(30, -1.0);
            DDMusicUtils.Fade();

            foreach (DDScene scene in DDSceneUtils.Create(40))
            {
                this.DrawSurfaces();

                DDEngine.EachFrame();
            }

            DDEngine.FreezeInput();
        }
Example #13
0
        public override IEnumerable <bool> E_Draw()
        {
            Novel.I.SkipMode = false;

            for (; ;)
            {
                //Novel.I.CancelSkipAutoMode();

                if (
                    this.Options.Count < NovelConsts.SELECT_OPTION_MIN ||
                    this.Options.Count > NovelConsts.SELECT_OPTION_MAX
                    )
                {
                    throw new DDError("選択肢の個数に問題があります。");
                }

                // ---- 入力ここから

                if (!Novel.I.BacklogMode)
                {
                    int moving = 0;

                    if (
                        DDKey.IsPound(DX.KEY_INPUT_UP) ||
                        DDInput.DIR_8.IsPound()
                        )
                    {
                        moving = -1;
                    }

                    if (
                        DDKey.IsPound(DX.KEY_INPUT_DOWN) ||
                        DDInput.DIR_2.IsPound()
                        )
                    {
                        moving = 1;
                    }

                    if (moving != 0)
                    {
                        int optIndex = this.GetMouseFocusedIndex();

                        if (optIndex == -1)
                        {
                            optIndex = 0;
                        }
                        else
                        {
                            optIndex += this.Options.Count + moving;
                            optIndex %= this.Options.Count;
                        }

                        DDMouse.X =
                            NovelConsts.SELECT_FRAME_L +
                            Ground.I.Picture.MessageFrame_Button2.Get_W() -
                            10;
                        DDMouse.Y =
                            NovelConsts.SELECT_FRAME_T + NovelConsts.SELECT_FRAME_T_STEP * optIndex +
                            Ground.I.Picture.MessageFrame_Button2.Get_H() -
                            10;

                        DDMouse.PosChanged();
                    }
                }

                // ---- ここから描画

                if (!Hide)
                {
                    for (int index = 0; index < NovelConsts.SELECT_FRAME_NUM; index++)
                    {
                        DDPicture picture = Ground.I.Picture.MessageFrame_Button;

                        if (index < this.Options.Count)
                        {
                            picture = Ground.I.Picture.MessageFrame_Button2;

                            if (this.Options[index].MouseFocused)
                            {
                                picture = Ground.I.Picture.MessageFrame_Button3;
                            }
                        }

                        DDDraw.DrawBeginRect(
                            picture,
                            NovelConsts.SELECT_FRAME_L,
                            NovelConsts.SELECT_FRAME_T + NovelConsts.SELECT_FRAME_T_STEP * index,
                            picture.Get_W(),
                            picture.Get_H()
                            );
                        DDCrash drawedCrash = DDDraw.DrawGetCrash();
                        DDDraw.DrawEnd();

                        // フォーカスしている選択項目を再設定
                        {
                            if (index < this.Options.Count)
                            {
                                bool mouseIn = drawedCrash.IsCrashed(DDCrashUtils.Point(new D2Point(DDMouse.X, DDMouse.Y)));

                                this.Options[index].MouseFocused = mouseIn;
                            }
                        }
                    }
                    for (int index = 0; index < this.Options.Count; index++)
                    {
                        const int title_x = 80;
                        const int title_y = 28;

                        DDFontUtils.DrawString(
                            NovelConsts.SELECT_FRAME_L + title_x,
                            NovelConsts.SELECT_FRAME_T + NovelConsts.SELECT_FRAME_T_STEP * index + title_y,
                            this.Options[index].Title,
                            DDFontUtils.GetFont("Kゴシック", 16),
                            false,
                            new I3Color(110, 100, 90)
                            );
                    }
                }

                // 隠しているなら選択出来ない。
                if (Hide)
                {
                    foreach (OptionInfo option in this.Options)
                    {
                        option.MouseFocused = false;
                    }
                }

                yield return(true);
            }
        }
Example #14
0
        public void Perform()
        {
            this.Player.X = DDConsts.Screen_W / 4;
            this.Player.Y = DDConsts.Screen_H / 2;

            this.Player.BornScene.Fire();

            DDCurtain.SetCurtain(10);

            for (; ; this.Frame++)
            {
                // プレイヤー行動
                {
                    bool   bornOrDead = this.Player.BornScene.IsFlaming() || this.Player.DeadScene.IsFlaming();
                    bool   dead       = this.Player.DeadScene.IsFlaming();
                    double xa         = 0.0;
                    double ya         = 0.0;

                    if (!dead && 1 <= DDInput.DIR_4.GetInput())                     // 左移動
                    {
                        xa = -1.0;
                    }
                    if (!dead && 1 <= DDInput.DIR_6.GetInput())                     // 右移動
                    {
                        xa = 1.0;
                    }
                    if (!dead && 1 <= DDInput.DIR_8.GetInput())                     // 上移動
                    {
                        ya = -1.0;
                    }
                    if (!dead && 1 <= DDInput.DIR_2.GetInput())                     // 下移動
                    {
                        ya = 1.0;
                    }

                    double speed;

                    if (1 <= DDInput.A.GetInput())                     // 低速ボタン押下中
                    {
                        speed = (double)this.Player.SpeedLevel;
                    }
                    else
                    {
                        speed = (double)(this.Player.SpeedLevel * 2);
                    }

                    this.Player.X += xa * speed;
                    this.Player.Y += ya * speed;

                    DDUtils.ToRange(ref this.Player.X, 0.0, DDConsts.Screen_W);
                    DDUtils.ToRange(ref this.Player.Y, 0.0, DDConsts.Screen_H);

                    if (!bornOrDead && 1 <= DDInput.B.GetInput())                     // 攻撃ボタン押下中
                    {
                        this.Player.Shoot();
                    }

                    if (DDInput.L.GetInput() == 1)
                    {
                        this.Player.SpeedLevel--;
                    }
                    if (DDInput.R.GetInput() == 1)
                    {
                        this.Player.SpeedLevel++;
                    }
                    DDUtils.ToRange(ref this.Player.SpeedLevel, Player.SPEED_LEVEL_MIN, Player.SPEED_LEVEL_MAX);
                }

                {
                    DDScene scene = this.Player.BornScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        if (scene.Remaining == 0)
                        {
                            this.Player.MutekiScene.FireDelay();
                        }
                    }
                }

                {
                    DDScene scene = this.Player.DeadScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        if (scene.Remaining == 0)
                        {
                            if (this.Status.RemainingLiveCount <= 0)
                            {
                                break;
                            }

                            this.Status.RemainingLiveCount--;
                            this.Player.BornScene.FireDelay();
                        }
                    }
                }

                {
                    DDScene scene = this.Player.MutekiScene.GetScene();

                    if (scene.Numer != -1)
                    {
                        // noop
                    }
                }

                if (this.Scenario.EachFrame() == false)
                {
                    break;
                }

                this.EnemyEachFrame();
                this.WeaponEachFrame();

                DDCrashView cv = DDKey.GetInput(DX.KEY_INPUT_LSHIFT) == 0 ? null : new DDCrashView();

                // Crash
                {
                    DDCrash playerCrash = DDCrashUtils.Point(new D2Point(this.Player.X, this.Player.Y));

                    foreach (WeaponBox weapon in this.Weapons.Iterate())
                    {
                        weapon.Crash = weapon.Value.GetCrash();
                    }

                    foreach (EnemyBox enemy in this.Enemies.Iterate())
                    {
                        DDCrash enemyCrash = enemy.Value.GetCrash();

                        if (cv != null)
                        {
                            cv.Draw(enemyCrash);
                        }

                        foreach (WeaponBox weapon in this.Weapons.Iterate())
                        {
                            if (enemyCrash.IsCrashed(weapon.Crash))
                            {
                                if (enemy.Value.Crashed(weapon.Value) == false)                                 // ? 消滅
                                {
                                    enemy.Dead = true;
                                }

                                if (weapon.Value.Crashed(enemy.Value) == false)                                 // ? 消滅
                                {
                                    weapon.Dead = true;
                                }
                            }
                        }
                        this.Weapons.RemoveAll(weapon => weapon.Dead);

                        if (this.Player.BornScene.IsFlaming() == false &&
                            this.Player.DeadScene.IsFlaming() == false &&
                            this.Player.MutekiScene.IsFlaming() == false && enemyCrash.IsCrashed(playerCrash))
                        {
                            foreach (DDScene scene in DDSceneUtils.Create(30))                             // プレイヤ死亡効果
                            {
                                this.DrawWall();
                                this.Player.Draw();
                                this.DrawEnemies();

                                DDDraw.SetAlpha(0.3);
                                DDDraw.SetBright(1.0, 0.0, 0.0);
                                DDDraw.DrawRect(DDGround.GeneralResource.WhiteBox, 0, 0, DDConsts.Screen_W, DDConsts.Screen_H);
                                DDDraw.Reset();

                                {
                                    int ix = DoubleTools.ToInt(this.Player.X);
                                    int iy = DoubleTools.ToInt(this.Player.Y);

                                    DDDraw.SetBright(1.0, 1.0, 0.0);
                                    DDDraw.SetAlpha(scene.Rate);
                                    DDDraw.DrawRect_LTRB(DDGround.GeneralResource.WhiteBox, ix - 1, 0, ix + 1, DDConsts.Screen_H);
                                    DDDraw.SetAlpha(scene.RemainingRate);
                                    DDDraw.DrawRect_LTRB(DDGround.GeneralResource.WhiteBox, 0, iy - 1, DDConsts.Screen_W, iy + 1);
                                    DDDraw.Reset();
                                }

                                DDEngine.EachFrame();
                            }

                            this.Player.DeadScene.Fire();
                        }
                    }
                    this.Enemies.RemoveAll(enemy => enemy.Dead);
                }

                // ここから描画

                this.DrawWall();
                this.Player.Draw();
                this.DrawEnemies();
                this.DrawWeapons();

                if (cv != null)
                {
                    cv.DrawToScreen(0.8);
                    cv.Dispose();
                    cv = null;
                }

                DDPrint.SetPrint();
                DDPrint.Print(DDEngine.FrameProcessingMillis_Worst + " " + this.Enemies.Count + " SPEED=" + this.Player.SpeedLevel);

                DDEngine.EachFrame();
            }
        }
Example #15
0
        public static void EachFrame()
        {
            I2Point pt   = Map.ToTablePoint(DDMouse.X + DDGround.ICamera.X, DDMouse.Y + DDGround.ICamera.Y);
            MapCell cell = Game.I.Map.GetCell(pt, null);

            if (cell == null)
            {
                return;
            }

            if (DDUtils.IsOutOfScreen(new D2Point(DDMouse.X, DDMouse.Y)))
            {
                return;
            }

            HideMenu = 1 <= DDKey.GetInput(DX.KEY_INPUT_LCONTROL) || 1 <= DDKey.GetInput(DX.KEY_INPUT_RCONTROL);

            if (HideMenu || DDUtils.IsOut(new D2Point(DDMouse.X, DDMouse.Y), MenuRect))
            {
                if (1 <= DDMouse.L.GetInput())
                {
                    if (InputWallFlag)
                    {
                        cell.Wall = Wall;
                    }
                    if (InputTileFlag)
                    {
                        cell.Tile = MapTileManager.GetTile(MapTileManager.GetNames()[TileIndex]);
                    }
                    if (InputEnemyFlag)
                    {
                        cell.EnemyLoader = EnemyManager.GetEnemyLoader(EnemyManager.GetNames()[EnemyIndex]);
                    }
                }
                if (1 <= DDMouse.R.GetInput())
                {
                    cell.Wall        = false;
                    cell.Tile        = null;
                    cell.EnemyLoader = null;
                }
            }
            else
            {
                int cursorMenuItemIndex = DDMouse.Y / 16;

                bool l = 1 <= DDMouse.L.GetInput();
                bool r = 1 <= DDMouse.R.GetInput();

                if (l || r)
                {
                    bool flag = l;

                    switch (cursorMenuItemIndex)
                    {
                    case 0: InputWallFlag = flag; break;

                    case 1: InputTileFlag = flag; break;

                    case 2: InputEnemyFlag = flag; break;

                    case 3: DisplayWallFlag = flag; break;

                    case 4: DisplayTileFlag = flag; break;

                    case 5: DisplayEnemyFlag = flag; break;

                    case 6: Wall = flag; break;

                    case 7:
                    case 8:
                        IntoInputTileMode();
                        break;

                    case 9:
                    case 10:
                        IntoInputEnemyMode();
                        break;
                    }
                }

                Rot += DDMouse.Rot;

                if (DDMouse.Rot == 0)
                {
                    NoRotFrame++;
                }
                else
                {
                    NoRotFrame = 0;
                }

                if (90 < NoRotFrame)
                {
                    Rot = 0;
                }

                switch (cursorMenuItemIndex)
                {
                case 7:
                case 8:
                    if (MenuItemRot(ref TileIndex, MapTileManager.GetCount()))
                    {
                        IntoInputTileMode();
                    }
                    break;

                case 9:
                case 10:
                    if (MenuItemRot(ref EnemyIndex, EnemyManager.GetCount()))
                    {
                        IntoInputEnemyMode();
                    }
                    break;
                }
            }

            if (DDKey.GetInput(DX.KEY_INPUT_C) == 1)
            {
                if (InputWallFlag)
                {
                    Wall = cell.Wall;
                }
                if (InputTileFlag)
                {
                    TileIndex = cell.Tile == null ? 0 : MapTileManager.GetNames().IndexOf(cell.Tile.Name);
                }
                if (InputEnemyFlag)
                {
                    EnemyIndex = cell.EnemyLoader == null ? 0 : EnemyManager.GetNames().IndexOf(cell.EnemyLoader.Name);
                }

                if (TileIndex == -1)                 // 2bs
                {
                    TileIndex = 0;
                }

                if (EnemyIndex == -1)                 // 2bs
                {
                    EnemyIndex = 0;
                }
            }
            if (DDKey.GetInput(DX.KEY_INPUT_S) == 1)
            {
                MapLoader.SaveToLastLoadedFile(Game.I.Map);
            }
        }
Example #16
0
        private void Edit()
        {
            this.Map.Load();             // ゲーム中にマップを書き換える場合があるので、再ロードする。

            DDEngine.FreezeInput();
            DDUtils.SetMouseDispMode(true);
            LevelEditor.ShowDialog();

            int lastMouseX = DDMouse.X;
            int lastMouseY = DDMouse.Y;

            for (; ;)
            {
                if (LevelEditor.Dlg.XPressed)
                {
                    break;
                }

                // 廃止
                //if (DDKey.GetInput(DX.KEY_INPUT_E) == 1)
                //    break;

                I2Point cellPos = GameCommon.ToTablePoint(
                    DDGround.Camera.X + DDMouse.X,
                    DDGround.Camera.Y + DDMouse.Y
                    );

                MapCell cell = Game.I.Map.GetCell(cellPos);

                if (cell.IsDefault)
                {
                    // noop
                }
                else if (1 <= DDKey.GetInput(DX.KEY_INPUT_LSHIFT) && 1 <= DDKey.GetInput(DX.KEY_INPUT_LCONTROL)) // 左シフト・コントロール押下 -> 塗り潰し_L / 塗り潰し_R
                {
                    if (DDMouse.L.GetInput() == -1)                                                              // クリックを検出
                    {
                        this.Map.Save();                                                                         // 失敗を想定して、セーブしておく

                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                        {
                            string tileName = LevelEditor.Dlg.GetTile_L();

                            if (tileName != cell.TileName)
                            {
                                string targetTileName = cell.TileName;                                                 // cell.TileName は this.EditFill で変更される。

                                this.EditFill(
                                    cellPos,
                                    v => v.TileName == targetTileName,
                                    v =>
                                    {
                                        v.TileName = tileName;
                                        v.Tile     = TileCatalog.Create(tileName);
                                    }
                                    );
                            }
                        }
                        break;

                        case LevelEditor.Mode_e.ENEMY:
                        {
                            string enemyName = LevelEditor.Dlg.GetEnemy();

                            if (enemyName != cell.EnemyName)
                            {
                                string targetEnemyName = cell.EnemyName;                                                 // cell.EnemyName は this.EditFill で変更される。

                                this.EditFill(
                                    cellPos,
                                    v => v.EnemyName == targetEnemyName,
                                    v => v.EnemyName = enemyName
                                    );
                            }
                        }
                        break;

                        default:
                            throw null;                                     // never
                        }
                    }
                    else if (DDMouse.R.GetInput() == -1)         // クリックを検出
                    {
                        this.Map.Save();                         // 失敗を想定して、セーブしておく

                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                        {
                            string tileName = LevelEditor.Dlg.GetTile_R();

                            if (tileName != cell.TileName)
                            {
                                string targetTileName = cell.TileName;                                                 // cell.TileName は this.EditFill で変更される。

                                this.EditFill(
                                    cellPos,
                                    v => v.TileName == targetTileName,
                                    v =>
                                    {
                                        v.TileName = tileName;
                                        v.Tile     = TileCatalog.Create(tileName);
                                    }
                                    );
                            }
                        }
                        break;

                        case LevelEditor.Mode_e.ENEMY:
                            // none
                            break;

                        default:
                            throw null;                                     // never
                        }
                    }
                }
                else if (1 <= DDKey.GetInput(DX.KEY_INPUT_LSHIFT))                 // 左シフト押下 -> 移動 / none
                {
                    if (1 <= DDMouse.L.GetInput())
                    {
                        DDGround.Camera.X -= DDMouse.X - lastMouseX;
                        DDGround.Camera.Y -= DDMouse.Y - lastMouseY;

                        DDUtils.ToRange(ref DDGround.Camera.X, 0.0, this.Map.W * GameConsts.TILE_W - DDConsts.Screen_W);
                        DDUtils.ToRange(ref DDGround.Camera.Y, 0.0, this.Map.H * GameConsts.TILE_H - DDConsts.Screen_H);

                        DDGround.ICamera.X = SCommon.ToInt(DDGround.Camera.X);
                        DDGround.ICamera.Y = SCommon.ToInt(DDGround.Camera.Y);
                    }
                    else if (1 <= DDMouse.R.GetInput())
                    {
                        // none
                    }
                }
                else if (1 <= DDKey.GetInput(DX.KEY_INPUT_LCONTROL))                 // 左コントロール押下 -> スポイト_L / スポイト_R
                {
                    if (1 <= DDMouse.L.GetInput())
                    {
                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                            LevelEditor.Dlg.SetTile_L(cell.TileName);
                            break;

                        case LevelEditor.Mode_e.ENEMY:
                            LevelEditor.Dlg.SetEnemy(cell.EnemyName);
                            break;

                        default:
                            throw null;                                     // never
                        }
                    }
                    else if (1 <= DDMouse.R.GetInput())
                    {
                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                            LevelEditor.Dlg.SetTile_R(cell.TileName);
                            break;

                        case LevelEditor.Mode_e.ENEMY:
                            // none
                            break;

                        default:
                            throw null;                                     // never
                        }
                    }
                }
                else if (1 <= DDKey.GetInput(DX.KEY_INPUT_LALT))        // 左 ALT 押下 -> 自機ワープ / none
                {
                    if (DDMouse.L.GetInput() == -1)                     // クリックを検出
                    {
                        this.Player.X = cellPos.X * GameConsts.TILE_W + GameConsts.TILE_W / 2;
                        this.Player.Y = cellPos.Y * GameConsts.TILE_H + GameConsts.TILE_H / 2;

                        DDGround.EL.Add(SCommon.Supplier(Effects.中爆発(this.Player.X, this.Player.Y)));                         // アクションが分かるように
                    }
                    else if (1 <= DDMouse.R.GetInput())
                    {
                        // none
                    }
                }
                else                 // シフト系押下無し -> セット_L / セット_R (敵はクリア)
                {
                    if (1 <= DDMouse.L.GetInput())
                    {
                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                        {
                            string tileName = LevelEditor.Dlg.GetTile_L();

                            cell.TileName = tileName;
                            cell.Tile     = TileCatalog.Create(tileName);
                        }
                        break;

                        case LevelEditor.Mode_e.ENEMY:
                        {
                            string enemyName = LevelEditor.Dlg.GetEnemy();

                            cell.EnemyName = enemyName;
                        }
                        break;

                        default:
                            throw null;                                     // never
                        }
                    }
                    else if (1 <= DDMouse.R.GetInput())
                    {
                        switch (LevelEditor.Dlg.GetMode())
                        {
                        case LevelEditor.Mode_e.TILE:
                        {
                            string tileName = LevelEditor.Dlg.GetTile_R();

                            cell.TileName = tileName;
                            cell.Tile     = TileCatalog.Create(tileName);
                        }
                        break;

                        case LevelEditor.Mode_e.ENEMY:
                            cell.EnemyName = GameConsts.ENEMY_NONE;
                            break;

                        default:
                            throw null;                                     // never
                        }
                    }
                }

                if (DDKey.GetInput(DX.KEY_INPUT_S) == 1)                 // S キー --> Save
                {
                    this.Map.Save();

                    // 表示
                    {
                        int endFrame = DDEngine.ProcFrame + 60;

                        DDGround.EL.Add(() =>
                        {
                            DDPrint.SetPrint(0, 16);
                            DDPrint.SetBorder(new I3Color(0, 0, 0));
                            DDPrint.Print("セーブしました...");
                            DDPrint.Reset();

                            return(DDEngine.ProcFrame < endFrame);
                        });
                    }
                }
                if (DDKey.GetInput(DX.KEY_INPUT_L) == 1)                 // L キー --> Load
                {
                    this.Map.Load();

                    // 表示
                    {
                        int endFrame = DDEngine.ProcFrame + 60;

                        DDGround.EL.Add(() =>
                        {
                            DDPrint.SetPrint(0, 16);
                            DDPrint.SetBorder(new I3Color(0, 0, 0));
                            DDPrint.Print("ロードしました...");
                            DDPrint.Reset();

                            return(DDEngine.ProcFrame < endFrame);
                        });
                    }
                }

                DDCurtain.DrawCurtain();

                if (LevelEditor.Dlg.IsShowTile())
                {
                    this.DrawMap();
                }

                if (LevelEditor.Dlg.IsShowEnemy())
                {
                    LevelEditor.DrawEnemy();
                }

                lastMouseX = DDMouse.X;
                lastMouseY = DDMouse.Y;

                DDEngine.EachFrame();
            }
            DDEngine.FreezeInput();
            DDUtils.SetMouseDispMode(false);
            LevelEditor.CloseDialog();

            this.Map.Save();             // ★★★ マップをセーブする ★★★
        }
Example #17
0
        private bool CheckInputPadButtonKey(bool キー設定Flag, DDInput.Button targetButton)         // ret: 設定した。
        {
            DDInput.Button[] buttons = new DDInput.Button[]
            {
                DDInput.DIR_2,
                DDInput.DIR_4,
                DDInput.DIR_6,
                DDInput.DIR_8,
                DDInput.A,
                DDInput.B,
                DDInput.L,
            };

            if (キー設定Flag)
            {
                int pressKeyId = -1;

                foreach (int keyId in DDSimpleMenu.GetAllKeyId())
                {
                    if (DDKey.GetInput(keyId) == 1)
                    {
                        pressKeyId = keyId;
                    }
                }

                if (pressKeyId != -1)
                {
                    int[] keyIds;

                    switch (pressKeyId)
                    {
                    case DX.KEY_INPUT_LCONTROL:
                    case DX.KEY_INPUT_RCONTROL:
                        keyIds = new int[] { DX.KEY_INPUT_LCONTROL, DX.KEY_INPUT_RCONTROL };
                        break;

                    case DX.KEY_INPUT_LSHIFT:
                    case DX.KEY_INPUT_RSHIFT:
                        keyIds = new int[] { DX.KEY_INPUT_LSHIFT, DX.KEY_INPUT_RSHIFT };
                        break;

                    case DX.KEY_INPUT_LALT:
                    case DX.KEY_INPUT_RALT:
                        keyIds = new int[] { DX.KEY_INPUT_LALT, DX.KEY_INPUT_RALT };
                        break;

                    default:
                        keyIds = new int[] { pressKeyId };
                        break;
                    }

                    // 他ボタンとの重複回避
                    if (SCommon.Comp(targetButton.KeyIds, keyIds, SCommon.Comp) != 0)                     // ? 違う
                    {
                        foreach (DDInput.Button button in buttons)
                        {
                            if (SCommon.Comp(button.KeyIds, keyIds, SCommon.Comp) == 0)                             // ? 同じ
                            {
                                button.KeyIds = targetButton.KeyIds;
                            }
                        }
                    }

                    targetButton.KeyIds = keyIds;
                    return(true);
                }
            }
            else
            {
                int pressBtnId = -1;

                for (int padId = 0; padId < DDPad.GetPadCount(); padId++)
                {
                    for (int btnId = 0; btnId < DDPad.PAD_BUTTON_MAX; btnId++)
                    {
                        if (DDPad.GetInput(padId, btnId) == 1)
                        {
                            pressBtnId = btnId;
                        }
                    }
                }

                if (pressBtnId != -1)
                {
                    int[] btnIds = new int[] { pressBtnId };

                    // 他ボタンとの重複回避
                    if (SCommon.Comp(targetButton.BtnIds, btnIds, SCommon.Comp) != 0)                     // ? 違う
                    {
                        foreach (DDInput.Button button in buttons)
                        {
                            if (SCommon.Comp(button.BtnIds, btnIds, SCommon.Comp) == 0)                             // ? 同じ
                            {
                                button.BtnIds = targetButton.BtnIds;
                            }
                        }
                    }

                    targetButton.BtnIds = btnIds;
                    return(true);
                }
            }
            return(false);
        }
Example #18
0
        public bool PlayerWasDead = false;         // 死亡すると true にセットされる。

        public void Perform()
        {
            DDUtils.Random = new DDRandom(1u, 1u, 1u, 1u);             // 電源パターン確保のため

            DDCurtain.SetCurtain();
            DDEngine.FreezeInput();

            Func <bool> f_ゴミ回収 = SCommon.Supplier(this.E_ゴミ回収());

            // reset
            {
                RippleEffect.Clear();
                画面分割.Enabled = false;
            }

            this.Player.Reset(false);

            // ★★★★★ ステータス反映
            {
                this.Score        = this.Status.Score;
                this.Player.Power = this.Status.PlayerPower;
                this.Zanki        = this.Status.PlayerZanki;
                this.ZanBomb      = this.Status.PlayerZanBomb;
            }

            for (this.Frame = 0; ; this.Frame++)
            {
                if (!this.Script.EachFrame())                 // シナリオ進行
                {
                    break;
                }

                if (DDConfig.LOG_ENABLED)                 // チート機能
                {
                    if (DDKey.IsPound(DX.KEY_INPUT_PGUP))
                    {
                        this.Player.Power += GameConsts.PLAYER_POWER_PER_LEVEL;
                    }
                    if (DDKey.IsPound(DX.KEY_INPUT_PGDN))
                    {
                        this.Player.Power -= GameConsts.PLAYER_POWER_PER_LEVEL;
                    }
                    DDUtils.ToRange(ref this.Player.Power, 0, GameConsts.PLAYER_POWER_MAX);
                }

                if (DDInput.PAUSE.GetInput() == 1 && 10 < this.Frame)                 // ポーズ
                {
                    this.Pause();

                    if (this.Pause_RestartGame)
                    {
                        GameMaster.RestartFlag = true;
                        break;
                    }
                    if (this.Pause_ReturnToTitleMenu)
                    {
                        GameMaster.ReturnToTitleMenu = true;
                        break;
                    }
                }
                if (DDConfig.LOG_ENABLED && DDKey.GetInput(DX.KEY_INPUT_RETURN) == 1)
                {
                    this.DebugPause();
                }

                this.LastInput = this.Input;                 // 前回のプレイヤー入力を退避

                // プレイヤー入力
                {
                    this.Input.Dir2  = 1 <= DDInput.DIR_2.GetInput();
                    this.Input.Dir4  = 1 <= DDInput.DIR_4.GetInput();
                    this.Input.Dir6  = 1 <= DDInput.DIR_6.GetInput();
                    this.Input.Dir8  = 1 <= DDInput.DIR_8.GetInput();
                    this.Input.Slow  = 1 <= DDInput.A.GetInput();
                    this.Input.Shoot = 1 <= DDInput.B.GetInput();
                    this.Input.Bomb  = 1 <= DDInput.C.GetInput();
                }

                this.Player.LastX = this.Player.X;
                this.Player.LastY = this.Player.Y;

startBornPlayer:
                if (1 <= this.Player.BornFrame)                 // プレイヤー登場中の処理
                {
                    int frm = this.Player.BornFrame - 1;

                    if (GameConsts.PLAYER_BORN_FRAME_MAX < frm)
                    {
                        this.Player.BornFrame = 0;
                        goto endBornPlayer;
                    }
                    this.Player.BornFrame++;
                    double rate = (double)frm / GameConsts.PLAYER_BORN_FRAME_MAX;

                    if (frm == 0)                     // init
                    {
                        this.Player.BornFollowX = GameConsts.FIELD_W * 0.5;
                        this.Player.BornFollowY = GameConsts.FIELD_H * 1.2;
                    }

                    double approachingRate = 0.99 - 0.01 * frm;
                    DDUtils.ToRange(ref approachingRate, 0.0, 1.0);

                    DDUtils.Approach(ref this.Player.BornFollowX, this.Player.X, approachingRate);
                    DDUtils.Approach(ref this.Player.BornFollowY, this.Player.Y, approachingRate);
                }
endBornPlayer:

                //startDeadPlayer:
                if (1 <= this.Player.DeadFrame)                 // プレイヤー死亡中の処理
                {
                    int frm = this.Player.DeadFrame - 1;

                    if (GameConsts.PLAYER_DEAD_FRAME_MAX < frm)
                    {
                        if (this.Zanki <= 0)                         // 残機不足のため終了
                        {
                            GameMaster.ReturnToTitleMenu = true;
                            break;
                        }
                        this.Zanki--;
                        this.Player.Reset(true);
                        goto startBornPlayer;
                    }
                    this.Player.DeadFrame++;

                    if (frm == 0)                     // init
                    {
                        this.DeadPlayerMoment();
                        this.PlayerEffects.Add(SCommon.Supplier(Effects.PlayerDead(this.Player.X, this.Player.Y)));
                    }
                    goto endPlayerMove;
                }
                //endDeadPlayer:

                //startBombPlayer:
                if (1 <= this.Player.BombFrame)                 // ボム使用中の処理
                {
                    int frm = this.Player.BombFrame - 1;

                    if (GameConsts.PLAYER_BOMB_FRAME_MAX < frm)
                    {
                        this.Player.BombFrame = 0;
                        goto endBombPlayer;
                    }
                    this.Player.BombFrame++;

                    if (frm == 0)                     // init
                    {
                        this.Player.Bomb();
                    }
                }
endBombPlayer:

                //startPlayerMove:
                // プレイヤー移動
                {
                    bool d2 = this.Input.Dir2;
                    bool d4 = this.Input.Dir4;
                    bool d6 = this.Input.Dir6;
                    bool d8 = this.Input.Dir8;

                    double speed;

                    if (this.Input.Slow)
                    {
                        speed = 2.5;
                    }
                    else
                    {
                        speed = 5.0;
                    }

                    double nanameSpeed = speed / Math.Sqrt(2.0);

                    if (d2 && d4)                     // 左下
                    {
                        this.Player.X -= nanameSpeed;
                        this.Player.Y += nanameSpeed;
                    }
                    else if (d2 && d6)                     // 右下
                    {
                        this.Player.X += nanameSpeed;
                        this.Player.Y += nanameSpeed;
                    }
                    else if (d4 && d8)                     // 左上
                    {
                        this.Player.X -= nanameSpeed;
                        this.Player.Y -= nanameSpeed;
                    }
                    else if (d6 && d8)                     // 右上
                    {
                        this.Player.X += nanameSpeed;
                        this.Player.Y -= nanameSpeed;
                    }
                    else if (d2)                     // 下
                    {
                        this.Player.Y += speed;
                    }
                    else if (d4)                     // 左
                    {
                        this.Player.X -= speed;
                    }
                    else if (d6)                     // 右
                    {
                        this.Player.X += speed;
                    }
                    else if (d8)                     // 上
                    {
                        this.Player.Y -= speed;
                    }

                    DDUtils.ToRange(ref this.Player.X, 0.0, (double)GameConsts.FIELD_W);
                    DDUtils.ToRange(ref this.Player.Y, 0.0, (double)GameConsts.FIELD_H);

                    if (d4)                     // 左
                    {
                        DDUtils.Minim(ref this.Player.XMoveFrame, 0);
                        this.Player.XMoveFrame--;
                    }
                    else if (d6)                     // 右
                    {
                        DDUtils.Maxim(ref this.Player.XMoveFrame, 0);
                        this.Player.XMoveFrame++;
                    }
                    else
                    {
                        this.Player.XMoveFrame = 0;
                    }

                    if (d8)                     // 上
                    {
                        DDUtils.Minim(ref this.Player.YMoveFrame, 0);
                        this.Player.YMoveFrame--;
                    }
                    else if (d2)                     // 下
                    {
                        DDUtils.Maxim(ref this.Player.YMoveFrame, 0);
                        this.Player.YMoveFrame++;
                    }
                    else
                    {
                        this.Player.YMoveFrame = 0;
                    }

                    DDUtils.Approach(ref this.Player.XMoveRate, DDUtils.Sign(this.Player.XMoveFrame), 0.95);
                    DDUtils.Approach(ref this.Player.YMoveRate, DDUtils.Sign(this.Player.YMoveFrame), 0.95);
                }
endPlayerMove:

                if (this.Input.Slow)
                {
                    DDUtils.Maxim(ref this.Player.SlowFrame, 0);
                    this.Player.SlowFrame++;
                }
                else
                {
                    DDUtils.Minim(ref this.Player.SlowFrame, 0);
                    this.Player.SlowFrame--;
                }

                if (this.Input.Shoot)
                {
                    DDUtils.Maxim(ref this.Player.ShootFrame, 0);
                    this.Player.ShootFrame++;
                }
                else
                {
                    DDUtils.Minim(ref this.Player.ShootFrame, 0);
                    this.Player.ShootFrame--;
                }

                DDUtils.Approach(ref this.Player.SlowRate, this.Player.SlowFrame < 0 ? 0.0 : 1.0, 0.85);
                DDUtils.Approach(ref this.Player.ShootRate, this.Player.ShootFrame < 0 ? 0.0 : 1.0, 0.85);

                if (this.LastInput.Shoot && this.Input.Shoot && SCommon.IsRange(this.Player.SlowFrame, -1, 1))                 // ? ショット中に低速・高速を切り替えた。
                {
                    this.Player.ShootRate = 0.0;
                }

                // ----

                if (this.Input.Shoot && this.Player.DeadFrame == 0)                 // プレイヤー攻撃
                {
                    this.Player.Shoot();
                }
                if (this.Input.Bomb && this.Player.DeadFrame == 0 && this.Player.BombFrame == 0 && 1 <= this.ZanBomb)                 // ボム使用
                {
                    this.ZanBomb--;
                    this.Player.BombFrame = 1;
                }

                // 当たり判定 reset
                {
                    this.PlayerCrashes.Clear();
                    this.GrazeCrashes.Clear();
                    this.EnemyCrashes.Clear();
                    this.ShotCrashes.Clear();
                }

                this.Player.Put当たり判定();

                // ====
                // 描画ここから
                // ====

                // Swap
                {
                    DDSubScreen tmp = this.Field;
                    this.Field      = this.Field_Last;
                    this.Field_Last = tmp;
                }

                using (this.Field.Section())                 // フィールド描画
                {
                    // Walls
                    {
                        int filledIndex = -1;

                        for (int index = 0; index < this.Walls.Count; index++)
                        {
                            Wall wall = this.Walls[index];

                            if (!wall.Draw())
                            {
                                this.Walls[index] = null;
                            }
                            else if (wall.Filled)
                            {
                                filledIndex = index;
                            }
                        }
                        for (int index = 0; index < filledIndex; index++)
                        {
                            this.Walls[index] = null;
                        }

                        this.Walls.RemoveAll(v => v == null);
                    }

                    RippleEffect.EachFrame(this.Field);

                    this.EL_AfterDrawWalls.ExecuteAllTask();

                    // Shots
                    {
                        for (int index = 0; index < this.Shots.Count; index++)
                        {
                            Shot shot = this.Shots[index];

                            if (!shot.Draw())
                            {
                                this.Shots[index] = null;
                            }
                        }
                        this.Shots.RemoveAll(v => v == null);
                    }

                    this.EL_AfterDrawShots.ExecuteAllTask();

                    if (this.Player.DeadFrame == 0)
                    {
                        this.Player.Draw();
                    }

                    this.EL_AfterDrawPlayer.ExecuteAllTask();

                    // Enemies
                    {
                        foreach (Enemy.Kind_e kind in new Enemy.Kind_e[]
                        {
                            Enemy.Kind_e.ENEMY,
                            Enemy.Kind_e.TAMA,
                            Enemy.Kind_e.ITEM,
                        })
                        {
                            for (int index = 0; index < this.Enemies.Count; index++)
                            {
                                Enemy enemy = this.Enemies[index];

                                if (enemy != null && enemy.Kind == kind)
                                {
                                    if (!enemy.Draw())
                                    {
                                        this.Enemies[index] = null;
                                    }
                                }
                            }
                        }
                        this.Enemies.RemoveAll(v => v == null);
                    }

                    this.EnemyEffects.ExecuteAllTask();
                    this.PlayerEffects.ExecuteAllTask();

                    // 当たり判定表示
                    // -- デバッグ用だが、ボタン設定に割り当てがあるので、常に使えるようにする。
                    if (1 <= DDInput.R.GetInput())
                    {
                        this.Draw当たり判定();
                    }

                    画面分割.EachFrame(this.Field);
                }

                {
                    DDUtils.Approach(ref this.BackgroundSlideRate, this.Player.Y * 1.0 / GameConsts.FIELD_H, 0.99);                     // HACK

                    D4Rect rect = DDUtils.AdjustRectExterior(
                        new D2Size(GameConsts.FIELD_W, GameConsts.FIELD_H),
                        new D4Rect(0, 0, DDConsts.Screen_W, DDConsts.Screen_H),
                        this.BackgroundSlideRate
                        //this.Player.Y * 1.0 / GameConsts.FIELD_H
                        );

                    DDDraw.DrawRect(this.Field.ToPicture(), rect);
                }

                {
                    const int MARGIN = 5;

                    DDDraw.SetBright(0, 0, 0);
                    DDDraw.DrawRect(
                        Ground.I.Picture.WhiteBox,
                        GameConsts.FIELD_L - MARGIN,
                        GameConsts.FIELD_T - MARGIN,
                        GameConsts.FIELD_W + MARGIN * 2,
                        GameConsts.FIELD_H + MARGIN * 2
                        );
                    DDDraw.Reset();
                }

                DX.GraphFilter(
                    DDGround.MainScreen.GetHandle(),
                    DX.DX_GRAPH_FILTER_GAUSS,
                    16,
                    SCommon.ToInt(500.0)
                    );

                DDCurtain.DrawCurtain(-0.2);

                DDDraw.DrawSimple(this.Field.ToPicture(), GameConsts.FIELD_L, GameConsts.FIELD_T);
                this.DrawStatus();
                this.SurfaceManager.Draw();

                // ====
                // 描画ここまで
                // ====

                foreach (Enemy enemy in this.Enemies.Iterate())
                {
                    if (!DDUtils.IsOut(new D2Point(enemy.X, enemy.Y), new D4Rect(0, 0, GameConsts.FIELD_W, GameConsts.FIELD_H)))                     // ? フィールド内
                    {
                        DDUtils.CountDown(ref enemy.TransFrame);
                        enemy.OnFieldFrame++;
                    }
                }

                this.当たり判定();

                if (this.AH_Grazed)
                {
                    if (
                        1 <= this.Player.BornFrame ||
                        1 <= this.Player.DeadFrame
                        )
                    {
                        // 登場中・死亡中は何もしない。
                    }
                    else
                    {
                        Ground.I.SE.SE_KASURI.Play();
                        this.Score++;
                    }
                }
                if (this.AH_PlayerCrashedFlag)
                {
                    if (
                        1 <= this.Player.BornFrame ||
                        1 <= this.Player.DeadFrame ||
                        1 <= this.Player.BombFrame
                        )
                    {
                        // 登場中・死亡中・ボム使用中は何もしない。
                    }
                    else
                    {
                        this.Player.DeadFrame = 1;                         // プレイヤー死亡
                        this.PlayerWasDead    = true;
                    }
                }

                if (Ground.I.HiScore < this.Score)
                {
                    if (Ground.I.HiScore + 10L < this.Score)
                    {
                        Ground.I.HiScore -= this.Score;
                        Ground.I.HiScore /= 2L;
                        Ground.I.HiScore += this.Score;
                    }
                    else
                    {
                        Ground.I.HiScore++;
                    }
                }

                f_ゴミ回収();

                this.Enemies.RemoveAll(v => v.HP == -1);
                this.Shots.RemoveAll(v => v.Vanished);

                DDEngine.EachFrame();

                // ★★★ ゲームループの終わり ★★★
            }

            DDUtils.Maxim(ref Ground.I.HiScore, this.Score);             // 確実な同期

            // ★★★★★ ステータス反映
            {
                this.Status.Score         = this.Score;
                this.Status.PlayerPower   = this.Player.Power;
                this.Status.PlayerZanki   = this.Zanki;
                this.Status.PlayerZanBomb = this.ZanBomb;
            }

            DDMain.KeepMainScreen();

            DDMusicUtils.Fade();
            DDCurtain.SetCurtain(60, -1.0);

            foreach (DDScene scene in DDSceneUtils.Create(120))
            {
                DDDraw.DrawRect(DDGround.KeptMainScreen.ToPicture(), 0, 0, DDConsts.Screen_W, DDConsts.Screen_H);
                DDEngine.EachFrame();
            }

            // ★★★ end of Perform() ★★★
        }