2月5日 作業日誌 ゲーム制作

こんばんは。

とうとう一月は書かずに終わってましたね。

去年から作っていたゲームが完成したので、振り返ってみましょう。

 

ゲームはこちら

【さへの落とし】

https://polite-plant-0740bd700.2.azurestaticapps.net/

僕の顔を左右に動かして落として、人々に当ててみんなをさへのにしよう、というゲームです。
遊んだら #さへのへの でハイスコアとか呟いてくださると嬉しいです。

 

ではまず、できたことから。

・2D画像(sprite)の移動やアニメーション

・物理演算

・スタート、リスタート

・スコアやコンボや制限時間

・効果音やBGMを鳴らす

 

とりあえずこれくらいでしょうか。

ゲームとして成り立つ最低限はあると思います。

期間にしてUnity版(1から)が約3ヶ月、Phaser3版(すでに素材有り、ロジックなども設計済み)で約1週間でした。

結構かかってしまいましたが、何より完成して良かったです。

 

ここからが本題。

ボトルネックになったところについてです。

・グラフィックやサウンドの用意

・ゲーム性

 

他にも色々ありましたが、この二つが大きすぎますね。

まずグラフィックは、単純に技術がありません。

Vtuber(あるいはそれに類する方々)のゲームを作ろうとしている都合上、キャラクターはほぼ必ず自作するか依頼する必要があります。

今から絵の練習をしても何年かかるか……。

今回自分と誰でもない人をトレスして作成するだけでもかなりの時間を要しましたから、ものすごく大きな課題です。

逆にここさえなんとかなればなんとかなる気もします。

素材がすでにあったPhaser3への移行は1週間でしたし。

 

そしてゲーム性。

おそらく普通に考えると遊んでて楽しいゲームか、というようなことでしょうが少し拡大解釈して、面白さと題材にした方々のメリットになるかどうかも考慮することにします。

こちらは抽象的ゆえに難題ですね。

ゲームになって嬉しい、楽しいだけでなく良かったと思ってもらえるような感じでしょうか。

その方の魅力や世界観が深まるようなもの……入念な打ち合わせと研究が必要そうですね。

 

次に作るゲームはいくつか案があるので、そちらもお楽しみに。

 

以上です。

12月26日 作業日誌 DP

こんばんは。

したいこと無限大な年末です。

 

DP

今日はDPの勉強をしていました。

動的計画法といって、あるものを求めたいときにそれまでの過程を全て求めることで早く計算できる、みたいな感じのものです。

わかりやすい例としてはフィボナッチ数列の計算があります。

 

例1.普通に計算する場合

1番目:1

2番目:1

3番目:1+1=2

4番目:1+(1+1)=3

5番目:(1+1)+(1+(1+1))=5

こんな感じになりますが

 

例2.DPを使う場合

準備:計算結果を格納する配列を用意する

それぞれの計算後、毎回結果を格納することで、過去の結果を再利用できる

1番目:1

2番目:1

3番目:1番目+2番目=2

4番目:2番目+3番目=3

5番目:3番目+4番目=5

 

例1の括弧で括っていた場所が、過去の計算結果に置き換わった形になります。

これはどちらかというとメモ化再帰

まぁこんな感じなのですが、本題はここから。

 

ナップサック問題

容量と価値がそれぞれ設定されたn個の品物があります。それらの中から、ナップサックの容量wを超えないように品物を選ぶ時、最大の価値を求めよ。

という問題なのですが、これがなんとも難しいのです。

うまく言語化できないのでまだ自分の中で消化できていませんが、今日はこのナップサック問題の初級みたいなものを解説を見ながら勉強していました。

縦軸に品物、横軸に重さをとった表を埋めていくことで解けるのですが……。

 

これができるようになったら一段レベルアップする……かもしれませんね。

 

以上です。

12月25日 作業日誌 next.jsのチュートリアル

こんばんは。

メリークリスマス🎄

 

next.jsのチュートリアル

今日からnext.jsのチュートリアルを始めました。

バージョンが違ったりなんだりしていますがなんとかなっています。

一通り終わったらアルゴリズムのアニメーション(コードを追いながら見れる感じの)を見れるサイトを作ろうかなと思っています。

理由のひとつとしては「競技プログラミングやっててコードとアルゴリズムの対応がわからなかった」というのがあるのですが、実はもっと根源的な理由があったりします。

 

まぁそれはあまりにも私的なので今は書かないとして……。

私は一瞬だけwebサイトの制作でお金をいただいていたのですが、その頃はReact……?Node.jsとかよくわからないしjQueryでなんとかなるでしょ!みたいな感じでした。

実際のところは単純に理解できなかっただけですが。

あれから私も少しは成長できていそうですね。

頑張りましょう。

完成したら過程をまとめてQiitaかどこかに投稿しますね。

 

以上です。

12月21日 作業日誌 DFSとBFSその2

こんばんは。

したいことがひとつ片付くとふたつ追加されていくこの頃です。

 

DFSとBFSその2

前回基礎をほぼ答えを見ながら解いたので、今日は何も見ずに別の簡単な問題を解いてみました。

無事解けました。

ただ結構時間がかかりましたしミスもあったのでまだまだですね。

探索時、すでに見た頂点だけでなく他の条件(迷路だったら壁とか場外とか)も考慮しないといけませんね。

もっと問題を解いて慣れていきましょう。

 

以上です。

12月19日 作業日誌 DFSとBFS

こんばんは。

「チョットデキル」や「なんもわからん」は概ね「めちゃくちゃできる」「開発者本人です」と同義です。

本当になんもわからん時なんて言うかいつも困ります。

 

今日はアルゴリズムの勉強をしていました。

アルゴリズム頭の体操ですね。

頭の整理も兼ねてDFSとBFSについて書いておきます。

 

DFS

深さ優先探索です。

グラフ

このような構造(グラフ)があった時に、1→2→4→5→3→6の順に見ていくアルゴリズムです。

すでに通った道を記録することで、すべての頂点を一回ずつ見ることができます。

迷路とかを解けます。

実装は再帰関数でするのが良いと思います。

 

 

void dfs(vvi &g, vi &seen, int now){
    for(auto next : g.at(now - 1)){
        if(seen.at(next - 1) != -1){
            continue;
        }
        dfs(g,seen,next);
    }
}

int main() {
    int n;
    cin >> n;
    vvi g(n);
    rep(i,n){
        int tmp;
        cin >> tmp;
        int m;
        cin >> m;
        rep(j,m){
            int v;
            cin >> v;
            g.at(i).push_back(v);
        }
    }
    vi seen(n,-1);

    rep(i,n){
        if(seen.at(i) == -1){
            dfs(g,seen,i + 1);
        }
    }

    rep(i,n){
        cout << i + 1 << " " << seen.at(i) << endl;
    }
}

こんな感じです。

gが全ての頂点のつながり、seenがすでに通った頂点の記録です。

頂点を通った時間を記録するにはもう一つ変数を渡してdfs内のforの前後で記録します。

main関数の中でdfsをforで囲んでいるのは頂点が全て連結していない可能性を考慮しています。

 

参考(すごくわかりやすい):

qiita.com

再帰関数を使わないDFSもあるそうで、そっちの方が速いらしいのでいつかつよつよになったら見てみます。

 

BFS

幅優先探索です。

グラフ

このグラフだと1→2→3→4→5→6の順に見ていきます。

1に近い方から見ていくことになるので、各頂点への最短経路がわかります。

実装はwhile文が良いのだと思います。

キューを使うことで、

1.①をキューに入れる(①からの距離を記録する)

2.①をキューから出す

3.②と③をキューに入れる(①からの距離を記録する)

4.②をキューから出す

5.④と⑤をキューに入れる(①からの距離を記録する)

6.③をキューから出す

というように1に近い順で処理できます。

int main() {
    int n;
    cin >> n;
    vvi g(n);
    rep(i,n){
        int num;
        cin >> num;
        int m;
        cin >> m;
        rep(j,m){
            int tmp;
            cin >> tmp;
            g.at(i).push_back(tmp);
        }
    }
    vi dist(n,-1);
    queue<int> q;
    dist.at(0) = 0;
    q.push(1);
    while(!q.empty()){
        int v = q.front();
        q.pop();
        for(auto next : g.at(v - 1)){
            if(dist.at(next - 1) != -1){
                continue;
            }
            dist.at(next - 1) = dist.at(v - 1) + 1;
            q.push(next);
        }
    }
    rep(i,n){
        cout << i + 1 << " " << dist.at(i) << endl;
    }
}

こんな感じです。

distが①からの距離の記録です。

qがキューです。

 

参考(すごくわかりやすい):

qiita.com

 

けんちょんさんには大変お世話になっております。

 

競技プログラミングのCとDを安定して解けるよう、過去問を解いたり解説を見たりして頑張ります。

あと、解説記事を書いてる方々すごすぎますね……。

もっとわかりやすく解説できるようになったら、きっと心から理解できたと言えるのでしょう。

 

以上です。

12月12日 作業日誌 ゲーム制作

こんばんは。

手が冷たくてキーボードが上手く叩けません。

まあこれはスマホで書いてますが。

 

ゲーム制作

今日は制作中のゲームにスタートとゲームオーバー機能をつけました。

これで一通りゲームとしての最最最最低条件はできたのではないでしょうか。

次は何を実装しようか考えると無限に思いつきますけども。

とりあえず次はまたグラフィックですね。

僕の頭を落として人にぶつかる→被る→モニターが展開されてどこかへ消え去る

みたいな感じにしたいので、モニターと人の正面のグラフィックが必要ですかね。

年度内のリリース目指して頑張りましょう。

 

以上です。

12月4日 作業日誌 動画投稿とか

こんばんは。

半年越しのタスクを完了しました。

 

動画投稿

実は電子部品の紹介をする動画を投稿してたりします。

今日投稿した新作はこちらです。

【電子部品紹介】モーターを自由に運転!モータードライバーとは【電子部品の目次 #9】
https://youtu.be/fJiksx0I2iY

 

観てくださった方はありがとうございます。

なんと前回投稿したのは半年以上前でした。

あまりにも間隔空けすぎですね。

実は細かいところをいくつか変更しています。

作業量と視聴回数を見つつ、これからも変えていくと思います。

あとはまた月一ペースの投稿に戻したいです。

 

ゲーム制作

昨日までで描けた歩く人をゲームに組み込みました。

歩く歩く

無事歩かせられたわけですが、どうやったかよく覚えてません。

なので次同じことをしようとしたら大変ですね。

それはさておきまたシステムに戻ろうと思います。

差し当たってはゲームスタート、終了機能ですかね。

そうすれば形式上はゲームと呼べるのではないでしょうか。

なるべく早く公開したいですね。

 

以上です。