【Cocos2d-x】ラベルでディスプレイ情報などを表示する。

前回の記事でシーンの内容は大体分かった。

ちょっと気になるのはvisibleSizeとoriginの値。

じゃあ、visibleSizeとoriginの値をラベルに表示させちゃおう。

    auto str = String();
    str.appendWithFormat("visible (%f %f)", visibleSize.width, visibleSize.height);
    auto label = Label::createWithTTF(str.getCString(), "fonts/msgothic.ttc", 24);
    if (label == nullptr)
    {
        problemLoading("'fonts/msgothic.ttc'");
    }
    else
    {
        // position the label on the center of the screen
        label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - label->getContentSize().height));

        // add the label as a child to this layer
        this->addChild(label, 1);
    }

    auto str2 = String();
    str2.appendWithFormat("origin (%f %f)", origin.x, origin.y);
    auto label2 = Label::createWithTTF(str2.getCString(), "fonts/msgothic.ttc", 24);
    if (label2 == nullptr)
    {
        problemLoading("'fonts/msgothic.ttc'");
    }
    else
    {
        // position the label on the center of the screen
        label2->setPosition(Vec2(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - label->getContentSize().height * 2));

        // add the label as a child to this layer
        this->addChild(label2, 2);
    }

フォントについて

フォントはResource/fontsフォルダに拡張子ttfファイルが置いてあると思いますが、

Label::createWithTTF()をコールするときにフォントファイルを指定します。

Windowsだったらフォントはc:\windows\fontsがあるので、ここにあるttf/ttcファイルをここに置けば使用することができます。

文字列について

文字列はcocos2dx::Stringというクラスが存在するらしい。

これを使った方がいろいろと便利なので、これを使用する。

addChild()の第二パラメータ

これはzIndexとあったので、重ねて表示する場合、上に表示する順番を示すパラメータですね。

数字が大きい方が上に表示されるみたいです。

Windowsでの表示結果。

visibleは画面のサイズ、originは原点の座標のようです。

Windowsはこれでいいのですが、Android(pixel4a)の場合はこうなりました。

Pixel4aはちょっと横長なので、heightが少し小さいようです。

アスペクト比が異なり、アスペクト比は長辺が基準なので、その分heightが小さいのですね。

あと、左下にピンホールカメラがあるので、その分だけ、originのy座標が少し上になっていますね。

特殊ディスプレイ、嫌い。

まぁ、この点はどうするか後で考えよう。

古いディスプレイには御引退いただこう。

以前話していたVDT症候群のような症状。

もしかしたらと思いまして、

古いディスプレイの電源を切って使用しないようにしていたところ、

だいぶ症状は改善してきました。

まだ耳鳴りするけど、そんなに気になるほどじゃないです。

というのも、この古いディスプレイ、

ノングレアディスプレイじゃないのです。

グレアというのは、室内の光りがディスプレイに反射して映る現象で、

これが目にあまり良くない。

最近のディスプレイはこういった現象を起きないようにするノングレア対応されています。

今使用している二枚のディスプレイは、いずれもノングレアディスプレイです。

まぁ、今回のは飛び抜けて一番古いディスプレイだったからねぇ。

仕方が無いけど、引退していただこう。

新しいディスプレイ買わなきゃ。

【クラフトピア】2つ目のダンジョン攻略。

さらに強い敵を求めて、新たな大陸のダンジョンを攻略していきます。

1回攻略したダンジョンはアイテムは復活しないのですね。

ダンジョンはタルが沢山あるので、それを破壊すると調味料が手に入るし、

ダンジョン内の敵モブを倒すと作物の種が手に入ったりします。

ボスは光っているコアが弱点なので、ジャンプアタックを繰り返すと倒せます。

この種とは別のボスはいるのですか?

腰の所に立ててしまえます。

こうなればコア攻撃し放題。

最後のここを空けると、アヌビスに渡せるアイテムが手に入ります。

と言うことは、たくさんダンジョンを攻略すれば良いのですね。

拠点もかなり充実してきました。

まだ自動化は難しいですけどね。

【モラタメ】スチーミー 豚チャーシュー用

なんか大量に届いた(6枚)

これを使用すると豚チャーシューが電子レンジで作れてしまうらしい。

ということで。

豚バラブロック500グラム。

スチーミー1枚当たり、250グラムらしいので。

4等分。

フォークで表面に穴を空けて、

1枚当たり2ブロックをスチーミーに入れます。

ああ、チャックを空けると、かなりニンニクの匂いが効いてるね。

これを、向きに注意して電子レンジでチンする。

うちの電子レンジは500Wなので、1枚ずつ9分30秒チンし、そのあと5分放置。

出来上がった物はこちら。

見た目はかなり良い感じです。

ちなみに、パックの中はかなり脂でギットギトです。

この残ったタレ、後で使おうと思ったけど遠慮しておきます。

切り分けるとこんな感じ。

はしっこの方を食べてみると、表面は少しカリッとしていて、良い感じに脂が抜けております。

これは丼にして食べよう。

さすがに全部一気に食べると確実に太るので、タッパーに取ってあります。

これらは後でラーメンを食べるときに焼いてトッピングにしましょう。

しかし、電子レンジで15分足らずでこんなに美味しいチャーシューが食べられるとは、

予想外でした。

スチーミーの構造的に蒸気で圧力がかかっている状態なので、圧力鍋で調理している感じらしい。

短時間で調理できるので、ガス代もかからないのでかなり便利です。

これ、チャーシュー以外に使えないかな?

【クラフトピア】アヌビス神に会いに行く。

最初の島の上の方に、浮いている島があるんですよ。

かまどの上昇気流で行けるかなと思ったんですが、

どうも無理っぽい。

よくよく右上のクエストの内容を見たら、建築で登るって会ったので、

建築で昇りました。

ダンジョン攻略時にもらえるアイテムで能力をアップさせることが出来るみたいです。

ダンジョン周回すれば良いのかな?

とにもかくにも、素材を取り尽くしてしまったので、違う島に行ってみたいと思います。

この門からアイテムを消費することで、隣の島が開放されます。

より強い敵と戦うことが出来ます。

【北海道大戦】バトルシーンの画面を作成する

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

最新ソースはこちら(gitHub)。

https://github.com/takishita2nd/HokkaidoWar

バトルシーンの画面を作成していきます。

とは言っても部品を配置しているだけですが。

    class BattleScene : asd.Scene
    {
        private asd.TextObject2D _label = null;
        private asd.TextObject2D _attackCity = null;
        private asd.TextObject2D _deffenceCity = null;
        private asd.TextureObject2D _image_gu_attack = null;
        private asd.TextureObject2D _image_choki_attack = null;
        private asd.TextureObject2D _image_par_attack = null;
        private asd.TextureObject2D _image_gu_deffence = null;
        private asd.TextureObject2D _image_choki_deffence = null;
        private asd.TextureObject2D _image_par_deffence = null;
        private asd.TextObject2D _attackParam = null;
        private asd.TextObject2D _deffenceParam = null;

        public BattleScene()
        {

        }

        protected override void OnRegistered()
        {
            var layer = new asd.Layer2D();
            AddLayer(layer);

            // 下地
            var background = new asd.GeometryObject2D();
            layer.AddObject(background);
            var bgRect = new asd.RectangleShape();
            bgRect.DrawingArea = new asd.RectF(0, 0, 1800, 1000);
            background.Shape = bgRect;

            _label = new asd.TextObject2D();
            _label.Font = Singleton.GetLargeFont();
            _label.Text = "VS";
            _label.Position = new asd.Vector2DF(470, 400);
            layer.AddObject(_label);

            _attackCity = new asd.TextObject2D();
            _attackCity.Font = Singleton.GetLargeFont();
            _attackCity.Text = "札幌";
            _attackCity.Position = new asd.Vector2DF(450, 150);
            layer.AddObject(_attackCity);

            _deffenceCity = new asd.TextObject2D();
            _deffenceCity.Font = Singleton.GetLargeFont();
            _deffenceCity.Text = "小樽";
            _deffenceCity.Position = new asd.Vector2DF(450, 650);
            layer.AddObject(_deffenceCity);

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

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

            _image_gu_attack = new asd.TextureObject2D();
            _image_gu_attack.Texture = Singleton.GetImageGu();
            _image_gu_attack.Position = new asd.Vector2DF(300, 500);
            layer.AddObject(_image_gu_attack);

            _image_choki_attack = new asd.TextureObject2D();
            _image_choki_attack.Texture = Singleton.GetImageChoki();
            _image_choki_attack.Position = new asd.Vector2DF(450, 500);
            layer.AddObject(_image_choki_attack);

            _image_par_attack = new asd.TextureObject2D();
            _image_par_attack.Texture = Singleton.GetImagePar();
            _image_par_attack.Position = new asd.Vector2DF(600, 500);
            layer.AddObject(_image_par_attack);

            _image_gu_deffence = new asd.TextureObject2D();
            _image_gu_deffence.Texture = Singleton.GetImageGu();
            _image_gu_deffence.Position = new asd.Vector2DF(300, 250);
            layer.AddObject(_image_gu_deffence);

            _image_choki_deffence = new asd.TextureObject2D();
            _image_choki_deffence.Texture = Singleton.GetImageChoki();
            _image_choki_deffence.Position = new asd.Vector2DF(450, 250);
            layer.AddObject(_image_choki_deffence);

            _image_par_deffence = new asd.TextureObject2D();
            _image_par_deffence.Texture = Singleton.GetImagePar();
            _image_par_deffence.Position = new asd.Vector2DF(600, 250);
            layer.AddObject(_image_par_deffence);
        }

        protected override void OnUpdated()
        {

        }
    }

シンプルだけどまぁいいでしょう。

グー・チョキ・パーは絵文字が使えないっぽいので、絵文字を拡大してスクリーンショットで画像を作成しています。

次回は実際にシーンの切り替えをやってみます。

パソコンを使用していると気持悪くなる。それ、VDT症候群かも。

例えば、長時間パソコン作業をしていると、耳鳴りがしたり、頭のあたりが押さえつけられるような感じがしたり、気分が悪くなったりすることはないだろうか?

まさしく自分がそうで。

特に最近症状がひどい。

また老眼が進んでしまったのかと。

いや、老眼とも関係してくるんですけど。

調べてみると、VDT症候群という病気がありまして、

https://fastdoctor.jp/vdt症候群の特徴・症状と治療法について【医師監/

直接の原因は眼精疲労。

治療法も予防策しかなくて、

  • パソコン作業を1時間毎に10分程度休憩する。
  • ブルーライトカットのフィルターなどを使用する。
  • ディスプレイの明るさを暗くする。
  • 肩こり、首こりをほぐす。
  • 姿勢を正しくする。

今、スマホのタイマーを、1時間のタイマーと10分のタイマーをセットしてまして、

1時間のタイマーでパソコン使用後に、10分のタイマーで休憩する、というやり方を試しています。

休憩中はパソコンの画面を一切見ない。

さらに言うと、目を休ませる方法としては、

  • 目を温める。
  • 遠くを見つめる。
  • 目を動かす(ストレッチ)

やっぱり、パソコン作業ができないと、オイラ、何もできないので、

きついっす。

でも、老化はどうやっても回復することはできないので、

今後はこの老化とどうやって付き合っていくかを考えなくちゃ行けません。

今、最善の方法を模索中です。

マジきついっす。

【ラズパイ】カメラモジュールを使ってみる。

カメラモジュール買いました。

装着。

今回は足つきで固定できるタイプの物を買いました。

フラットケーブルで接続したので、ラズパイの設定でカメラを有効にすれば使用できるはずです。

カメラで静止画を撮影するには以下のコマンドを入力します。

$ raspistill -o image.jpg

モニターにプレビューが表示され、それが閉じるのと同時に、カレントディレクトリにimage.jpgが保存されます。

動画を撮影するときは以下のコマンドを入力します。

$ raspivid -t 5000 -o test.h264

プレビューのみの時は以下です。

$ raspivid --demo 5000

ただこれだけできても面白くない。

次回はプログラムから画像データを扱ってみたいと思います。

老眼の進行が止まらない模様。

前回はメガネを新調した!と書きましたが、

あれからまた老眼が進行したみたいで、

新しいメガネを使用していると再び耳鳴りがするようになってしまいました。

まだ1ヶ月もたってねーよ!

今はお金が無いので、来月、障害年金が入ったら眼科を受診しようと思っているけど、

また短期間に体に異常が出てきたら、もうメガネ諦めようかななんて思ってみたり。

メガネがないと何が困るかというと、

パソコン作業しているとき姿勢が悪くなるし、

ガルパの譜面を見えないし(ここ重要!)

老眼はなってしまうと回復することはないので、

辛い。

身体的にも、お財布的にも。

【ダイエット支援】【食事管理】目標カロリーを計算する

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

最新ソースはこちら(gitHub)。

https://github.com/takishita2nd/diet-mng

やっぱり、前回書いたとおり、きちんと目標となるカロリーを計算しないと、正しいグラフ書けない、ということで、ダイアログを追加します。

<template>
    <div>
        <div id="overlay" v-show="show">
            <div id="content">
                <p v-if="error_flg == true" class="error">
                    <ui>
                        <li v-for="error in errors">{{ error }}</li>
                    </ui>
                </p>
                <table class="edit">
                    <tbody>
                        <tr>
                            <td>身長</td>
                            <td><input type="number" v-model="inputParameter.height" /></td>
                        </tr>
                        <tr>
                            <td>体重</td>
                            <td><input type="number" v-model="inputParameter.weight" /></td>
                        </tr>
                        <tr>
                            <td>年齢</td>
                            <td><input type="number" v-model="inputParameter.age" /></td>
                        </tr>
                        <tr>
                            <td>アクティブ度</td>
                            <td>
                                <select name="active" v-model="inputParameter.active">
                                    <option value="1" selected>低</option>
                                    <option value="2">中</option>
                                    <option value="3">高</option>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <td>目的</td>
                            <td>
                                <select name="target" v-model="inputParameter.target">
                                    <option value="1" selected>維持</option>
                                    <option value="2">減量</option>
                                    <option value="3">増量</option>
                                </select>
                            </td>
                        </tr>
                    </tbody>
                </table>
                <p />
                <table class="edit">
                    <tbody>
                        <tr>
                            <td>目標カロリー</td>
                            <td>{{calorie}} cal</td>
                        </tr>
                        <tr>
                            <td>タンパク質</td>
                            <td>{{protein}} g</td>
                        </tr>
                        <tr>
                            <td>脂質</td>
                            <td>{{liquid}} g</td>
                        </tr>
                        <tr>
                            <td>炭水化物</td>
                            <td>{{carbo}} g</td>
                        </tr>
                    </tbody>
                </table>
                <p id="command">
                    <button @click="clickAdd">入力</button>
                    <button @click="closeModal">閉じる</button>
                </p>
            </div>
        </div>
    </div>
</template>
<script>
export default {
    props: ['show'],
    data() {
        return {
            errors: [],
            error_flg: [],
            param: {},
            inputParameter: {
                height: 0,
                weight: 0,
                age: 0,
                active: 1,
                target: 1,
            },
            contents: {
                calorie: 0,
                protein: 0,
                liquid: 0,
                carbo: 0,
            },
        };
    },
    created: function() {
        this.clear();
    },
    methods: {
        clickAdd: function() {
            var self = this;
            this.param.contents = this.contents;
            axios.post('/api/eating/settarget', this.param).then(function(response){
            }).catch(function(error){
                self.error_flg = true;
                self.errors = error.response.data.errors;
            });
        },
        closeModal: function() {
            this.$parent.showCalcCalorieContent = false;
        },
        clear: function() {
            this.inputParameter.height = 0;
            this.inputParameter.weight = 0;
            this.inputParameter.age = 0;
            this.inputParameter.active = "1";
            this.inputParameter.target = "1";
            this.contents.calorie = 0;
            this.contents.protein = 0;
            this.contents.liquid = 0;
            this.contents.carbo = 0;
            this.error_flg = false;
            this.errors = [];
        }
    }
}
</script>

ボタンはここに配置ました。

身長、体重、年齢と、アクティブ度と目標を入力してもらって、目標となるカロリーと摂取栄養素の量を計算します。

計算式はそんなに難しくないので、フロントエンド側で計算して表示させちゃいます。

    computed: {
        calorie: function() {
            var cal = 10 * this.inputParameter.weight + 6.25 * this.inputParameter.height - 5 * this.inputParameter.age + 5;
            var k = 1;
            // アクティブ度の計算
            switch(this.inputParameter.active){
                case "1": k = 1.2; break;
                case "2": k = 1.55; break;
                case "3": k = 1.725; break;
            }
            cal = cal * k;
            // 目標の計算
            switch(this.inputParameter.target){
                case "1": k = 1; break;
                case "2": k = 0.8; break;
                case "3": k = 1.2; break;
            }
            this.contents.calorie = Math.ceil(cal * k);
            return this.contents.calorie;
        },
        protein: function() {
            this.contents.protein = this.inputParameter.weight * 2;
            return this.contents.protein;
        },
        liquid: function() {
            this.contents.liquid = Math.ceil(this.contents.calorie * 0.25 / 9);
            return this.contents.liquid;
        },
        carbo: function() {
            this.contents.carbo = Math.ceil((this.contents.calorie - this.contents.protein * 4 - this.contents.liquid * 9) / 4);
            return this.contents.carbo;
        },
    },

まず、computedに記載することで、入力パラメータからすぐさま計算処理を行い、結果を反映してくれます。

カロリーの計算式は、

10×体重(g)+6.25×身長(cm)-5×年齢(歳)+5

これにアクティブ度と目的に合わせて係数を掛けます。

アクティブ度

  • 低 カロリー×1.2
  • 中 カロリー×1.55
  • 高 カロリー×1.725

目的

  • 減量 カロリー×0.8
  • 維持 カロリー×1
  • 増量 カロリー×1.2

これらは以下で紹介した本の中にあります。

フロントエンド側はこれで完成。

次はこの計算結果を保持するデータベース周りのバックエンド側を作成していきます。

自分、ぼっちですが何か?