アサヒビール園のお食事券を買った話。

ネットのメール広告で、アサヒビール園のお食事券10000円分が8000円で購入できると聞いて。

今回このお食事券でアサヒビール園にご迷惑をかけてしまいまして。

というのは、このお食事券、

関東の人達をターゲットにした広告。

これをWebで購入後、チケット交換店舗に行って、お食事券に交換して貰って、初めてお食事が出来るというもので、

その交換可能な店舗が関東にしか無くて、北海道で購入したオイラはお食事券に引き換えできないという事態に陥ったのです。

結局どうなったかというと、白石のアサヒビール園はまなす館の偉い人が取り計らってくれて、お食事券を用意してくれました。

結局お得に出来たじゃねーか、という話もありますが、自分はそれ以上にめんどくさい事態になってしまったという思いです。

みんなには同じめんどくさい事態にならない様、購入する際は気をつけて欲しい。

以下、自分の愚痴です。

なんで関東向けの広告が北海道人に届くわけ?

アカウントの住所北海道に設定しているんだから北海道の広告を送りなさいよ。

関東でしか使えない広告は関東人にだけ送れ。

地域判定きちんとやってくれ。

頂いたチケットは大切に使わせて頂きます。

【cocos2d-x】プロジェクト作成直後のソースファイルを解析する。

Cocos2d-xの開発環境作成についてはこちらにまとめてあります。

https://qiita.com/takishita2nd/items/0b54af9860f54c65fd24

今回は、プロジェクト作成直後に作成されるソースファイルの中身を覗いてみます。

とはいっても、いきなりソース解析も難しいので、こちらの初心者用の解説を見ながら確認していきました。

https://www.tuyano.com/index3?id=9496003

基本的に弄るソースはClassesの中だけです。

それ以外はCocos2d-xのライブラリ本体だったり、各プラットフォームのビルド環境なので、今後一切触る必要は無いと思います。

むしろ、書き換えたら正常に動く保証はない。

AppDelegateクラス

アプリケーション全体の設定を記述します。

タスク切り替え時の処理とかをここに書くことになります。

最初は弄ることは無いと思います。

HelloWorldクラス

上のリンクにあった初心者用テキストには、Layerクラスを継承してHelloWorldクラスを作成していると書いてありますが、実際にはSceneクラスを継承しています。

class HelloWorld : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

Cocos2d-xの概念として、画面毎にシーンを作成し、その中に画面を構成するオブジェクトを配置する、というイメージのようです。

大きな差分はこれくらいかな。

init()で画面に配置する部品をオブジェクト化して配置しています。

青の部分はメニューになっていて、クリックするとアプリを終了するコールバックが呼ばれます。

赤い部分はフォントを読み込んでテキストを表示しています。

黄色の部分はResourceフォルダの中にある画像を表示させています。

でもイマイチ座標周りがよく分からん。

visibleSizeが画面のサイズで、

originがOpenGLの座標系?を表している?

画面の解像度が変わっても表示が崩れないように計算していると思うのだが。

でも、ここまでで、表示位置を変えることはできると思うぞ。

ほらできた。

【マインクラフト】ハードコアモードでサーバを立ち上げる方法(Java版のみ)

ハードコアモードって何ですか?

ゲームモードはサバイバルで、難易度ハード固定、しかも死んでしまったら終了、復活できない、という超ハードなモードです。

これはJava版にしか存在しないモードです。

統合版勢残念。

シングルモードでは、上の設定にすればハードコアモードでワールドが生成されますが、

これをサーバでやってしまいます。

とは言っても、やり方はそんなに難しくなくて、

server.propertiesファイルの中に、

hardcore=false

という項目があるので(わかりやすいですね)

hardcore=true

と書き換えてサーバを立ち上げればOK。

ハートのアイコンが上のように変わればハードコアモードです。

ここからはチートの話ですが。

死んでしまうと、ゲームモードをスペクテイターモードに変更するか、タイトルに戻るかを選択することが出来ます。

スペクテイターモードというのは、世界を眺めるだけのモード。

死後の世界を気の済むまで自由に眺めることが出来ます。

復帰することはできません。

死んだかどうかのフラグデータはworldフォルダーの中に入っているので、定期的にworldフォルダーのバックアップを取っておいて、死亡後にworldフォルダーをごっそり復元すれば復帰できます。

まぁ、そんなことやるくらいなら、最初から普通にハードモードでプレイすればいいんだけどね(めんどくさい)

やり直しがきかない世界だから面白いハードコアモード。

腕試しにいかがですか?

おいらのVSCodeで使用している拡張機能

VSCodeっていろんな拡張機能がありますよね。

拡張機能の追加で自分が使いやすいように、好きにカスタマイズできるのがVSCodeのもう一つの特徴でもあります。

あまり変わった物入れてないけど。

ctagsx

Laravel開発環境に入れています。

PHPってデフォルトだとタグジャンプできないんすよ。

でも、この拡張機能を入れて、コマンドでtagsファイルをプロジェクトのホームディレクトリに置いておくと、

ctrl+関数左クリックでタグジャンプ出来るようになります。

sftp sync extension for VS Code

これはラズパイのコーディングに使用しています。

ラズパイの指定フォルダとローカルPCのフォルダでソースファイルの同期を取り、ローカルPCで編集・保存したファイルを自動的にラズパイ側へ反映してくれます。

Linux環境での開発にも使えますよ。

VSCODE POWER MODE!!!

これは完全にお遊び系の拡張機能。

文字を入力するとエフェクトがかかります。

花火を打ち上げながらコンボを決めてコーディングするとテンション上がります。

言っていることがわからなければググってみてください。

【北海道大戦】シーンを追加する

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

https://github.com/takishita2nd/HokkaidoWar

バトルシーンを追加するに当たりまして、

今まではエンジンに直接オブジェクトを配置していましたが、

シーンを使用するとなると、このやり方では上手くいけないっぽい。

なので、メインシーンを追加して、このシーンのレイヤーにオブジェクトを配置する必要があります。

なので、今回はその修正を実行。

    class HokkaidoWar
    {

        public HokkaidoWar()
        {
        }

        public void Run()
        {
            asd.Engine.Initialize("北海道大戦", 1200, 1000, new asd.EngineOption());

            // シーンの登録
            var scene = new MainScene();
            asd.Engine.ChangeScene(scene);

            while (asd.Engine.DoEvents())
            {
                asd.Engine.Update();
            }
            asd.Engine.Terminate();
        }

    }

いままでエンジンに追加していたオブジェクトは全て無くなり、シーンを作成して、そのシーンに移行、という処理に変わります。

    class MainScene : asd.Scene
    {
中略
        protected override void OnRegistered()
        {
            var layer = Singleton.GetMainSceneLayer();
            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;

            cities = new List<City>();
            var r = new Random();
            foreach (var map in mapData.list)
            {
                City city = new City(map.name, map.point, map.population);
                cities.Add(city);
            }

            _battle = new Battle(cities);
            aliveCities = _battle.GetAliveCityList();
        }

        protected override void OnUpdated()
        {
            asd.Vector2DF pos = asd.Engine.Mouse.Position;

            switch (gameStatus)
            {
                case GameStatus.SelectCity:
                    cycleProcessSelectCity(pos);
                    break;
                case GameStatus.ActionEnemy:
                    cycleProcessActionEnemy(pos);
                    break;
                case GameStatus.ActionPlayer:
                    cycleProcessActionPlayer(pos);
                    break;
                case GameStatus.ShowResult:
                    break;
                case GameStatus.GameEnd:
                    cycleProcessGameEnd();
                    break;
                case GameStatus.GameOver:
                    cycleProcessGameOver(pos);
                    break;
            }

            if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
            {
                switch (gameStatus)
                {
                    case GameStatus.SelectCity:
                        onClickMouseSelectCity(pos);
                        break;
                    case GameStatus.ActionEnemy:
                        break;
                    case GameStatus.ActionPlayer:
                        onClickMouseActionPlayer(pos);
                        break;
                    case GameStatus.ShowResult:
                        onClickMouseShowResult();
                        break;
                    case GameStatus.GameEnd:
                        break;
                    case GameStatus.GameOver:
                        break;
                }
            }
        }

後略

OnRegistered()はシーン登録時に実行されます。

オブジェクトの配置はここで行います。

レイヤーはシングルトンで取り出すようにしました。(いろんなところでオブジェクトの配置やっているので)

OnUpdated()には、while (asd.Engine.DoEvents()){ }内で実行していた処理を行います。

これは、asd.Engine.Update();実行時に実行されるイメージです。

細かい所は結構修正しているのですが、概要はこんな感じです。

とりあえず、シーンを使用して、今までと同じ動きが出来ることを確認しました。

次はバトルシーンの追加をしていきましょうか。

【料理】【リュウジのバズレシピ】至高のジャーマンポテト

久々のお料理。

こちらのレシピ動画を参考にしました。

ちょっと作り方間違えたけど、それでも十分いける。

あっという間にビールが無くなってしもうた。

これは罪な料理やわ。

まだジャガイモあるから3回作れる。

また作ろう。

そして運動もしよう。

ワードプレスのログイン画面にアクセス出来ないようにする

このままじゃやばいことは知ってた。

ログイン画面が表示できてしまうと、そこから簡単に侵入できてしまうかもしれない。

なので、セキュリティを高めるために、ログイン画面を別のURLに移動させて、ブログから見えないようにします。

まず、ログイン画面へのリンクですが、これはウィジェットのメタ情報を削除すると消えます。

続けて、ログイン画面のURLを変える方法。

これはプラグインを使う方が簡単です。

プラグインの新規追加から「WPS Hide Login」を検索し、ヒットしたプラグインをインストール、有効化。

プラグインの設定でログイン画面に遷移するためのクエリパラメータを設定することが出来るので、自分しか分からないパラメータに変更して保存。

ログイン画面へのURLが表示されるので、必ずブックマークに保存してください。

これでワードプレスは安全になりました!

【ラズパイ】【いろいろ計測モニター】Windows側からも操作しちゃう

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

最新ソースはこちら。

ラズパイ https://github.com/takishita2nd/RaspiDisplayMonitor

Windows https://github.com/takishita2nd/IroiroMonitor

Windows側からラズパイの情報を取得できるなら、

Windows側からでもラズパイを操作する事も出来ます。

なので、Windows側からスイッチ操作を行う処理を作ってみます。

Windowsにボタンを設置。

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Grid.Column="0" Content="時刻" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Width="239" Height="86" FontSize="48"/>
        <Label Grid.Row="1" Grid.Column="0" Content="温度" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10" Width="239" Height="86" FontSize="48"/>
        <Label Grid.Row="2" Grid.Column="0" Content="湿度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
        <Label Grid.Row="3" Grid.Column="0" Content="CPU温度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
        <Label Grid.Row="4" Grid.Column="0" Content="GPU温度" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Margin="10" Width="239" Height="87"/>
        <Label Grid.Row="0" Grid.Column="1" Content="{Binding DateTime}"  HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24"/>
        <Label Grid.Row="1" Grid.Column="1" Content="{Binding Temperature}"  HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
        <Label Grid.Row="2" Grid.Column="1" Content="{Binding Humidity}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
        <Label Grid.Row="3" Grid.Column="1" Content="{Binding CpuTemp}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
        <Label Grid.Row="4" Grid.Column="1" Content="{Binding GpuTemp}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48"/>
        <Button Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="2" Content="ボタン" Command="{Binding ButtonClickCommand}" FontSize="48" />
    </Grid>

ボタンを押すと、ラズパイ側にPOSTリクエストを送信するようにします。

今後の拡張性を考えて、コマンド番号みたいなものを送れるようにしましょうか。

    [JsonObject("CommandModel")]
    class Command
    {
        [JsonProperty("number")]
        public int number { get; set; }
    }
    public class MainWindowViewModel : BindableBase
    {
        private const int CommandSwitch = 1;

        public DelegateCommand ButtonClickCommand { get; }

        public MainWindowViewModel()
        {
            ButtonClickCommand = new DelegateCommand(async () =>
            {
                Command cmd = new Command();
                cmd.number = CommandSwitch;
                var json = JsonConvert.SerializeObject(cmd);
                try
                {
                    HttpClient client = new HttpClient();
                    var content = new StringContent(json, Encoding.UTF8);
                    await client.PostAsync("http://192.168.1.15:8000/", content);
                }
                catch (Exception ex)
                {
                }
            });

これで、ラズパイ側にPOSTリクエストを送れるようになりました。

次はラズパイ側のコードを書いていきます。

class StubHttpRequestHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        content_len = int(self.headers.get('content-length'))
        requestBody = json.loads(self.rfile.read(content_len).decode('utf-8'))

        if requestBody['number'] == 1:
            lock.acquire()
            GLCD.GLCDDisplayClear()
            lock.release()
            pushButton()

        response = { 'status' : 200 }
        self.send_response(200)
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        responseBody = json.dumps(response)

        self.wfile.write(responseBody.encode('utf-8'))

HttpRequestHandlerクラスにdo_POSTメソッドをオーバーライドします。

これを実装することで、POSTリクエストを受診して処理することが出来ます。

受信したデータがボタン操作ならば、ラズパイ側で行っているボタン操作と同じ処理をおこないます。

def pushButton():
    global mode
    mode += 1
    if mode > 4:
        mode = 1

しかし、ここで考えなければならないのは、ラズパイ側の周期処理とHTTPサーバ処理は非同期処理を行っていると言うこと。

はい、処理が競合しちゃいます。

なので、スレッド間の待ち合わせ処理を行う必要があります。

方法はいろいろあるのですが、今回は一番簡単な方法を使用します。

Lockを使用する方法です。

lock = threading.Lock()
    try:
        while True:
            lock.acquire()
            Humidity = AM2320.GetHum()
            Temperature = AM2320.GetTemp()

            if sw == True:
                GLCD.GLCDDisplayClear()
                pushButton()
                sw = False

            if mode == 1:

-中略-

            lock.release()
            time.sleep(1)
    except KeyboardInterrupt:
        GLCD.GLCDDisplayClear()
        GPIO.cleanup()

lock = threading.Lock()を定義し、同じlockで周期処理全体と、HTTPのスイッチ処理をlock/releaseで囲みました。

これで、一方がlockされている場合、もう一方はlockがreleaseされるまで処理に待ったがかかります。

これを使用すれば、ラズパイの遠隔操作も可能になります。

カレーパンだ。

カレーパンだ。

すごい行列だったね。

赤カレーと黒カレーの2種類ありまして、どちらも280円です。

赤カレー

黒カレー

若干辛さが違います。

どちらかが辛いと言うわけではなく、辛さの種類が違うって感じで。

食べ比べて面白いです。

あと、中にステーキ肉が入っているのも特徴的ですね。

【ダイエット支援】【食事管理】グラフの値をパーセンテージにして、適正量かどうかを見えるようにする。

前回までの状況はこちら

前回のままだと、摂取量をそのまま数字としてグラフに表示させているだけなので、

この数字が適正量なのかを判断するために、適正値との割合をパーセンテージにして表示させたいと思います。

といっても、どれくらいが適正量なのか、というのが、体型などに左右されやすいものなので、

こちらの記事の計算式を参考にして、

体重60kg、摂取カロリー2000kcalとして計算すると、

  • タンパク質120g(体重×2g、1g=4kcal)
  • 脂質55.5g(総カロリーの25%、1g=9kcal)
  • 炭水化物255g(総カロリーからタンパク質と脂質を除いた残り、1g=4kcal)

この数字を直に与えました。

            baseData: {
                protein: 120.0,
                liqid: 55.5,
                carbo: 255.0,
                calorie: 2000.0
            },

これ、ちゃんとした条件をもとに計算する仕組みが必要だね。

                    self.datasets.push(response.data.data.protein / self.baseData.protein * 100);
                    self.datasets.push(response.data.data.liqid / self.baseData.liqid * 100);
                    self.datasets.push(response.data.data.carbo / self.baseData.carbo * 100);
                    self.datasets.push(response.data.data.calorie / self.baseData.calorie * 100);

これでグラフがパーセンテージになります。

なので、どの栄養素が足りてなくて、どの栄養素を取りすぎているかがわかります。

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