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); }
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); }
// <---- 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); } }
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(); } }
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() ★★★ }
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() ★★★ }
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(); }
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() ★★★ }
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(); } } }
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() ★★★ }
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; }
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(); }
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); } }
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(); } }
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); } }
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(); // ★★★ マップをセーブする ★★★ }
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); }
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() ★★★ }