Global Game Jam 2015 Osaka チーム・スチューデンツ 作品

お疲れ様でした

Irigaru

クレジット

ななしさん(ADVパート制御)
藤井さん(敵制御)
くるくるさん(全体フォロー、レベルデザイン)
めだま(基本処理)
鈴木さん(絵・モデリング)

ゲーム説明

大切に育てている苺を魔物からイチゴを護る防衛型シューティングゲームです。イチゴを枯らそうと沢山の魔物がやってきます。女の子マリーアを操作してイチゴを護ってください。イチゴが沢山攻撃されると枯れてしまってゲームオーバーです。 プレイしているとおじいさんが現れて・・・この続きは是非プレイしてください(無事完成していればきっと結末が見れるはずです)

タイトル

スクリーンショット 2015-01-25 16.06.33

スクリーンショット 2015-01-25 16.16.52

ひとこと

去年の Global Game Jam の記事がたったの 5 つ前というね。なんというか、ブログ更新さぼりすぎな一年でした。
今年こそはいっぱい記事を投稿しなければ!

さてと、本題いきましょう。

今年も参加してきました

というわけで、今年も Global Game Jam 2015 参加してきました。会場は大阪梅田のグランフロント「ナレッジサロン」です。およそ 30 人のメンバーが集まり、何チームかにわかれて 48 時間以内にゲームを完成させ、GGJ 本家サイトに開発したゲームのページを作成して登録し、バイナリや動画をアップロードしないといけません。

それに、初めての人とチームを組まないといけないので、上手にコミュニケーションしながらプログラムをマージしたり連携しないといけないので超大変です。 ゲーム開発における自分のスキルや反省点が色々見えてきますし、ものすごく経験値が溜まるので・・・

と、そういうのも色々ありますが、やっぱ超楽しいイベントなので、こういうイベントが身近にあったら是非飛び込んでいきましょう。

今回のプログラムのポイント

今回は UniRx をチームメンバーに説明しながら使ってもらいました。Update() の中で書かれる処理が Start() の中で記述しちゃってる点でめっちゃ不思議がられましたが、なかなかの好感触っぽかったです。

変数で受け渡しせずに「やりたい事のみ」処理を記述できる点もわかりやすくて面白いですね。

移動処理

// 横移動イベント処理
Observable.EveryUpdate()
.Where(_ => rigidbody != null) // 制御するオブジェクトが null だったら何もしない(エラー対策)
.Where(_ => Input.GetButton("Horizontal")) // スティック倒したら次へ
.Select(_ => Input.GetAxis("Horizontal") * fXSpeed) // スティック値に係数をかけて返す
.Subscribe(x => rigidbody.velocity = UtilVector.SetX(rigidbody.velocity,x)); // 加速する

これ Update() に書くとこんな感じでしょうか。

if (rigidbody != null && Input.GetButton("Horizontal")) {
    rigidbody.verocity = UtilVector.SetX(rigidbody.velocity, Input.GetAxis("Horizontal") * fxspeed);
}

単純な処理ではまだ後者の方が良い気がしますが、これが一度ネットワークサービスを経由してその値を受け取って処理する場合、たいていはコルーチンやコールバックを別ファイルの別クラスの別メソッドに記述したりどこかグローバル変数クラスを用意して受け渡ししたりとカオスになりがちなソースがメソッドチェインだけで記述できてしまいます。

たとえば、サーバからリスト取得

ObservableWWW.Get("http://ほげほげリスト") // サーバAPIから何かのデータを受け取る
// オリジナルクラスで JSON を生成し、1 階層目の Dictionary<string,string> コレクションを 1 件づつ分解して通知に変換します
.SelectMany(x => new Mera.StringTool.KJson(x, false).parse2().dcString.ToObservable())
// 受け取った通知をワークに格納します
.Subscribe(x => dcVersion[x.Key] = x.Value);

これを普通に書くと、

    WWW w;
    enum Phase {
        Request,
        Wait,
        Success,
        Error
    }
    Phase phase = Phase.Request;

    public void Update() {

        switch (phase) {
            case Phase.Request:
                w = new WWW("ほげほげリスト");
                StartCoroutine(SetTextures(w));
                phase = Phase.Wait;
                break;
            case Phase.Wait:
                if (w.isDone) {
                    phase = (string.IsNullOrEmpty(w.error)) ? Phase.Success : Phase.Error;
                }
                break;
            case Phase.Success:
                foreach (var pair in Mera.StringTool.KJson(x, false).parse2().dcString) {
                    dcVersion[pair.Key] = pair.Value;
                }
                w.Dispose();
                w = null;
                break;
            case Phase.Error:
                w.Dispose();
                w = null;
                break;
        }

    }

    public IEnumerator SetTextures(WWW www) {
        yield return www;
    }

多分こんな感じになることでしょう。

おっと、いつの間にか話題が変わっていた。

今年はプログラム三昧で良い年でありますように。

ツイートツイート