openGLって今更やる必要があるのかって思った。

openTKでハマってしまったのを前に記事で書いたのですが、

本気でやるなら書籍を買うしかないと思って探しては見た物の、あまりピンとこないというか、アレだったので、

そんなときに見つけたのがこのページ。

細かい所は上のページを読んで貰うとして、

結論から言うと、

openGLの理論を学ぶとするのはいいけれど、

単に3Dアプリを作りたいと言うだけならば、既存のプラットフォームを使った方が早い。

例えばUnityとか。

openGLで悩むより、Unityの勉強を始めた方がいい。

そういえば、Unityの書籍を使った勉強、途中で止まっていたけど、

再開してみるかな。

【ダイエット支援】もっと具体的な設計をしなくちゃいけなくて

たぶん、前回の記事の内容だけではコーディングはまだできなくって、

もっと具体的に動作の仕組みを考えなくちゃいけないと思いまして。

UIの動き

  • 文字を入力すると、データベースから入力候補を取得し、表示する
  • 入力した内容が入力候補と一致すると、その栄養素値が自動で入力される
  • 入力を空にすると、入力候補も空にする

テキスト窓に入力したかどうかはVue.jsではv-on:changeで処理を起動することができるみたいなので、これを使用します。

データベース

基本的には入力済みの食品・栄養素の情報(テンプレート)からデータを抽出して候補がある物から選択するという形にしたいと思います。

ただ、そう言った食品や栄養素の情報を全部用意するのは大変なので、ユーザーが入力した情報を記憶しておいて(ヒストリ)、管理者が正式データとして登録する、という仕組みにしたいと思います。

なので、管理者画面が必要になりますね。

データベースはテンプレートとヒストリの二つ用意しておきたいと思います。

ここらへん、本当はもっと詰めなくちゃいけない所ですが、今回はあとでどうにでもできるように、リスクが少ない方法を選択したいと思います。

あとでデータベース構成を変えるとなるとコードの修正も大変なので。

なので、今後の作業はこんな感じです。

  • データベースの構築
  • テンプレートからデータを入力する処理
  • ユーザーが入力したデータをヒストリに保存する処理
  • 管理者がヒストリからテンプレートに移す処理

よし、これでいきましょう。

【COCOS2D-X】タッチ処理を使用する。

さて、今回はタッチ処理を試してみたいと思います。

タッチ処理はスマホ専用の処理なので、Windowsでは動かないので、スマホで動作確認します。

で、タッチした座標を画面に表示させたいと思います。

    auto listener1 = EventListenerTouchOneByOne::create();
    listener1->onTouchBegan = [this](Touch* touch, Event* event)->bool
    {
        auto str = String();
        str.appendWithFormat("Touch (%f %f)", touch->getLocation().x, touch->getLocation().y);
        label->setString(str.getCString());
        return true;
    };
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, this);

タッチ処理はイベントリスナーを使用するのですが、

EventListenerTouchOneByOneとEventListenerTouchAllAtOnceがあるのですが、前者はシングルタッチ、後者はマルチタッチのようです。

使用するハンドラ名が若干違うようです。

今回はシングルタッチを使用します。

で、今回初めてC++のラムダ式を使ったのですが、

[]はキャプチャといって、ラムダ式内に持っていく変数を指定するみたいなんですよね。

座標を表示するラベルなんですが、

ローカルにLabelオブジェクトを定義して[&label]って書いてもエラーで動かなかったので、

今回はサンプルコードに従って、labelはprivate変数に定義し、キャプチャには[this]とします。

こうすることでprivateのlabelオブジェクトを使用することができました。

あとは、引数touchからx,y座標をラベルに表示させる。

https://taki-lab.site/bocci/wp-content/uploads/2020/09/screen-20200929-084644.mp4

スマホだからか、画像のクリッピング処理がWindowsとは動きが違ってたんですよね。

ちょっとここは要調査ですわ。

もしかしたら、Windows用とスマホ用に画像を2種類用意しないといけないかもしれん。

イマイチ仕事する気が起きないのです。

まぁ、ちょっと前にも医者から仕事したらどうだとは言われたことがあるんですが。

仕事やめるまでは仕事一生懸命やっていたんですが、

次第に体調が悪化していって、

仕事を休むことが多くなって、

結果的に退職したのですが、

その後も加齢や老眼や肩こりとか首コリに悩まされて、

なんか、そのときに心がポッキリ折れてしまったような感じがして、

ちょうど同じ時期に借金も全額返済したし、

働かなくても障害年金もらえているし、

お金は欲しいけど、今は十分に暮らしていけるし、

養う家族もいないし、

まぁ、要するに、今頑張って仕事する理由が無い。

仕事をするためのモチベーションが無い。

そのままで良いのか、と言われると、良くはないのですが、

こればっかりは仕事したくなるのを待つしか無いのかな、

とか思ってみたり。

とりあえず今は趣味のプログラミングを続けてスキルを磨いておく。

ぐらいしかできないかなー

それとも時短のバイトでもやってみる?

クラウドソージングに登録してみたけど、案件見る限り、高スキルのものばっかりだし。

自分に見合った案件が無い。

そんな状況ですわ。

【北海道大戦】バトルシーンへパラメータを渡す。

前回までの状況はこちら。

バトルシーンを作成するために、バトルシーンで使用するパラメータを設定します。

シーンはその都度作成しなくちゃいけないので、コンストラクタで渡すのが一番良いでしょう。

        public enum Player
        {
            Attack,
            Deffence
        }

        public BattleScene(City attack, City deffence, Player player)
        {
            _attack = attack;
            _attackPower = attack.Population;
            _deffence = deffence;
            _deffencePower = deffence.Population;
            _player = player;
            _status = GameStatus.SelectDeffenceAction;
        }

playerというパラメータは、プレイヤーが攻撃側か防御側かを示すパラメータです。

あれこれ悩んだ結果、これが一番簡単だろうと。

これを画面に表示させます。

            var attackCityLabel = new asd.TextObject2D();
            attackCityLabel.Font = Singleton.LargeFont;
            attackCityLabel.Text = _attack.Name;
            attackCityLabel.Position = new asd.Vector2DF(450, 150);
            layer.AddObject(attackCityLabel);

            var deffenceCityLabel = new asd.TextObject2D();
            deffenceCityLabel.Font = Singleton.LargeFont;
            deffenceCityLabel.Text = _deffence.Name;
            deffenceCityLabel.Position = new asd.Vector2DF(450, 650);
            layer.AddObject(deffenceCityLabel);

            _attackParam = new asd.TextObject2D();
            _attackParam.Font = Singleton.LargeFont;
            _attackParam.Text = "戦闘力:" + _attack.Population;
            _attackParam.Position = new asd.Vector2DF(700, 650);
            layer.AddObject(_attackParam);

            _deffenceParam = new asd.TextObject2D();
            _deffenceParam.Font = Singleton.LargeFont;
            _deffenceParam.Text = "戦闘力:" + _deffence.Population;
            _deffenceParam.Position = new asd.Vector2DF(700, 150);
            layer.AddObject(_deffenceParam);

さらに、

このフローからバトルシーンの状態を抽出。

        enum GameStatus {
            SelectDeffenceAction,
            SelectAttackAction,
            ShowActionResult
        }

これを実装。

        protected override void OnUpdated()
        {
            switch (_status)
            {
                case GameStatus.SelectDeffenceAction:
                    break;
                case GameStatus.SelectAttackAction:
                    break;
                case GameStatus.ShowActionResult:
                    break;
            }
            if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
            {
                switch (_status)
                {
                    case GameStatus.SelectDeffenceAction:
                        break;
                    case GameStatus.SelectAttackAction:
                        break;
                    case GameStatus.ShowActionResult:
                        break;
                }
            }
        }

あとは、各状態について実装していけば良いのですな。

とりあえず今回はここまでにしておこう。

【クラフトピア】鉱石無限生産機構

やっぱりどの世界でも鉄は大量に必要。

なので、鉄無限生産機構です。

まずは平べったい鉱石がある場所を見つけます。

そこに掘削機を設置します。

そうすると、鉄鉱石を吐き出してくれるので、これをキャッチする感じでコンベアーを設置します。

吐き出す方向は常に同じみたい。

それを自動炉に流し込みます。

自動炉には操作できる箇所が二つあって、

一つは自動炉のチェスト、コンベアーで流し込まれたアイテムが入ります。

自分でアイテムを入れることもできます。

もう一つは生成するアイテムを設定するところ。

ここで設定したアイテムの材料がコンテナ内にあれば、アイテム(インゴット)を生成してくれます。

生成されたアイテムは後ろのコンベアーから流れてくるので、そこにコンテナを接続します。

これで鉄を自動的に掘削し、インゴットを精製してコンテナに入れてくれる装置が完成しました。

鉄無限生産機構の完成です。

この仕組みをもう一組作り、銀も無限生産機構化しました。

あとは、砂無限も欲しいな。

【ラズパイ】プログラムからカメラで動画撮影する。

今回はさらにxキーで動画撮影開始・停止を行います。

プログラムはこのようになりました。

from datetime import datetime
import cv2, os

cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')


def main():

  if cap == None:
    return False

  out = None
  capture = False

  while cap.isOpened():
    # カメラから映像を読み込む
    _, img = cap.read()

    cv2.imshow("preview", img)

    if capture:
      if out != None:
        out.write(img)

    key = cv2.waitKey(1)
    if key == ord('z'):
      cv2.imwrite("test.png", img)
    if key == ord('x'):
      if not capture:
        capture = True
        out = cv2.VideoWriter('test.avi',fourcc, 20.0, (640,480))
      else:
        capture = False
        out.release()
        out = None
    elif key < 255:
      break

  # 事後処理
  cap.release()
  if out != None:
    out.release()
  cv2.destroyAllWindows()

if __name__ == '__main__':
  main()
  

今回は新しくVideoWriter_fourcc()というのが出てきました。

引数の文字列は動画コーデックを示しているみたいです。

よく分からんけど。

まぁ、結局はこのコードをコピペして使うんだー

※ちなみに、プログラムをブログに書いたり、gitHubにあげているのは、就職して職場内に行ったとしてもコピペして使えるようにするためです。

VideoWriter()をつかって動画に保存するためのオブジェクトを作成します。

引数は、動画ファイル名、上のfourCC、フレームレート(fps)、解像度です。

オブジェクトを作成したら、フレームデータをこのオブジェクトにwrite()で書き込むだけです。

今回はxキーで録画開始・停止を行うので、xキーオンオフでオブジェクトを作成・解放を操作しています。

https://taki-lab.site/bocci/wp-content/uploads/2020/09/PXL_20200923_223708804_Trim.mp4
https://taki-lab.site/bocci/wp-content/uploads/2020/09/test.avi

次回はいよいよリモートやってみようかな

【クラフトピア】発電して電池を獲得。

夢中になって何時間でもプレイできる。

発電機を設置して、そこに捉えた動物を出現させると、車輪のなかを走って発電し、電池を獲得できます。

自分で走って発電もできるようになったみたいです。

電池とバイオメタノールは自動機構化するには絶対に必要になるアイテムなので、大量に生み出せる機構があれば良いんですけどね。

何か旨い方法は無いだろうか。

あ、ちなみにバイトメタノールは醸造所で小麦粉から作成できます。

なので、大量に小麦を作る必要があります。

まぁ、機構としては簡単ですが、麦農場とスプリンクラーがあれば、回収するだけで無限に小麦を獲得できます。

回転のこぎりがあれば自動回収もできるみたいですが。

ただ、回転のこぎりは別名殺戮マシーンとも呼ばれているので、ちょっと使うのにはためらいがあります。

アップデートのおかげなのか、無限繁殖機構、上に積み上がらなくなったのですが、増えすぎてゲームが重くなってしまいました。

増やすのは良いけれども適度に処理させる必要がありますね。

まぁ、余った肉などは売ってお金に換えれば良いので。

【バズレシピ】レンジでマーボーカレー

レシピはこちら。

今回はちゃんと大さじ小さじのスプーンを購入したので、きちんと分量計りました。

これはカレーだ。

うまい!

そしてめっちゃ辛い!

そりゃそうだ、カレーの辛さにプラスしてラー油と一味唐辛子が入っているから。

汗がドバッと噴き出ました。

でも旨い。

こんな旨いものをレンジで簡単にできちゃうから、本当にリュウジさんはすごい。

これはリピートありだね。

【ラズパイ】プログラムからカメラの画像を保存する

前回までの状況はこちら。

前回はカメラの画像を表示させていただけですが、

今回はこの画像をファイルに保存します。

例えば、zキーを押すことで画像をファイルに保存することにします。

プログラムはこうなります。

from datetime import datetime
import cv2, os

def main():

  cam = cv2.VideoCapture(0)
  if cam == None:
    return False

  while True:
    # カメラから映像を読み込む
    _, img = cam.read()

    cv2.imshow("preview", img)

    key = cv2.waitKey(1)
    if key == 122:
      cv2.imwrite("test.png", img)
    elif key < 255:
      break

  # 事後処理
  cam.release()
  cv2.destroyAllWindows()

if __name__ == '__main__':
  main()

cv2.waitKey(1)が122というのは、押したキーがzキーだったと言うことを示しています。

画像ファイルに保存する場合はimwrite()を使ってフレームデータとファイル名を渡すとカレントディレクトリに指定ファイル名で保存されます。