[魔改造 Judg○] (3)ゲームっぽくなる

デモ画面とゲームプレイ画面を行ったり来たりできるようになりました!
ゲームをプレイすることも当然可能です。
また、少しだけ魔改造が始まっています。

魔改造、始まる

元のやつ
作ったやつ。左下の文字はデバッグ用

「わざわざ Q 出す必要なくない?」という声が聞こえてきそうです。
これは、ほかの種類の問題も作ることにしたため、調整しました。

数字の大小だけではなく「合ってたら殴る、間違ってたら逃げる」というゲームにする、ということです。
1プレイ10問~20問程度、問題もジャンルを選べたらどうか…と色々考えています。

問題の管理

問題はエクセルに記述したものを…。

Scriptable Object に変換し、ゲーム内で使います。
今のところ 311 問。1000問にしたい(作りすぎか)

Excell to ScriptableObject ツールを使って自動的にデータ生成されるので、エクセルが使えればデータ管理はとても便利になりました。
詳しくはこちら。

ゲーム本体については、これだけ単純なゲームだからこそ、気を遣うべき部分は気を遣って実装しています。

同時に殴る、という事

何も考えずに、こんなコードを作っても「ほとんどの場合」は問題なく動きます。

// 2人分処理する
for (int i = 0; i < 2; i++)
{
    Player jibun = player[i];
    Player aite = player[i == 0 ? 1 : 0];

    if (jibun.AttackKey == true)
    {
        jibun.Animation(殴る);
        if (jibun.正解 == true)
        {
            aite.Animation(殴られる);
            break;
        }
    }
}

ところがこのコード、例えば「どっちも正解で、同時攻撃する」と必ずプレイヤー1が勝ってしまいます。
プレイヤー2はプレイヤー1の攻撃によって「殴られる」シーケンスに入ってしまい、殴る機会を潰されてしまうからです。

「1フレームだけだし1P有利でいいでしょ」と言うのも解決策ではありますが、対戦格闘ゲームの場合など、当たり前に気を遣って作られる部分です。このゲームも対戦ゲームですしね。

同時攻撃問題を解決するならば、「まず2人の行動を確定し」、「その後で2人分の判定を一気に行う」という2段構えにする必要があります。

// 2人の行動を確定
for (int i = 0; i < 2; i++)
{
    Player jibun = player[i];
    if (jibun.AttackKey == true)
    {
        jibun.Animation(殴る);
        jibun.Attack = true; // 攻撃した事を記憶
    }
}

// 2人の判定によってアニメーション確定
for (int i = 0; i < 2; i++)
{
    Player jibun = player[i];
    if (jibun.Attack == true && jibun.正解 == true)
    {
        Player aite = player[i == 0 ? 1 : 0];
        aite.Animation(殴られる);
    }
}

また、この時「殴る」アニメーションと「殴られる」アニメーションは同時発生します。
そうしても問題ないようなアニメーションを作っておかないと、不自然な表現になってしまうかもしれません。

同時に殴り、そして避ける

こうなってくると、2段構えの判定から、さらにややこしい感じになります。
if (jibun.Attack == true && aite.Escape == false && jibun.正解 == true) のようにつらつらと条件式を追加するのも一つの方法ですが、今回は「攻撃した方が優先される」仕様にしました。
同じフレームで攻撃と回避が発生した場合、回避は成功せず殴られる、ということです。

攻撃する側を有利にしたのは理由があって、点数配分で、

殴りミス…2点失う、その後相手に殴られれば更に2点失う
避けミス…3点失う

間違って攻撃した場合、点を多く失うので、同着の場合は「攻撃」を優先することにしました。
(この辺は原作と異なるかもしれません)

間違って殴った相手を殴り返せる

間違えて殴った相手を殴り返せる、は原作でも存在しており、納得感の強い、いいゲームデザインだと思います。
ちょっとしたことですが、こういう「ちょっとしたこと」の積み重ねが面白さを支えている好例。
プログラムはややこしくなっていきますが…笑

お手付き

看板がオープンされ、その内容によって殴る・避けるを選ぶゲームですが、なかには「確率は 1/2」とばかりにオープンされる前から「殴る連打」をするプレイヤーもいるかもしれません。

そういったプレイヤーが「お手付き」になるよう、▼が表示されてからキー入力を受け付けるようにしています。お手付きは相手に 4 点と、被害も大きいです。

ゲームの面白さ

そんなわけで、殴りあう前、本番、殴った後の3回で別々のキー入力待ちや、それに対応したアニメーションが発生し、お世辞にも綺麗なコードにはなりませんでした。
「殴った後、殴られた方が逃げた」「看板をオープンする前に殴って(うっかりあってれば)点数が入る」などなど、色々と想定外の動作が起きて大変でした…。

まあ、綺麗なコードで済まそうとするあまり、「なんかプレイしてて物足りない」「意外性がない」なんてゲーム内容になる事もあります。
今回の規模ですらそういうギミックがあり、よく考えた上でこういうデザインなんだと気づかされます。

コードが汚くなるのはプログラミングスキルの問題かもしれません…が、ゲームは「プログラムが綺麗にまとまれば面白くなる」わけではないのが難しいですね。

「どこまでもいける」「プレイしきれない程イベントがあり、一つ一つが面白い」と絶賛されたオープンワールドも、いまや「結局ひたすらお使いゲー」と言われる昨今です。
予算がいくらあっても、開発人数が数百、数千人いても、必ず楽しいものが作れるわけではない。
その一方で、数人が手掛けたとても単純な仕掛けが、延々とプレイされることもあります。

規模が大きいプロジェクトほど、他人からは誇りを持って迎えられる、でも最初の予定をひっくり返してまで面白さを追求することは(予算の関係上)叶わず、原初的な「作ってて楽しい」は感じにくくなっていく…多くのゲーム製作者がそういう矛盾と向き合っていると思います。

自分は何が好きか、どんなゲームを(作ってて)楽しいと感じるか。
見失わないようにすることも、とても大切です。