【COCOS2D-X】アイコン画像をピッチリ並べる

とりあえず、アイコンをピッチリ並べてみました。

ポイントは、座標や拡大サイズを全て計算で算出すること。

こうしないと、機種が変わったときに、確実にレイアウトが崩れます。

    float buttonScale = visibleSize.height / (visibleSize.height / 4.0);
    float buttonBase = 0.0;
    auto homeButton = Sprite::create("btnHome.png");
    if (homeButton == nullptr)
    {
        problemLoading("'btnHome.png'");
    }
    else
    {
        homeButton->setPosition(Vec2(sprite->getPosition().x + sprite->getContentSize().width * scaleRate / 2 + origin.x, visibleSize.height + origin.y));
        homeButton->setAnchorPoint(Vec2(1.0,1.0));
        homeButton->setScale(buttonScale);
        buttonBase = visibleSize.height - homeButton->getContentSize().height * buttonScale;
        this->addChild(homeButton, 1);
    }

    auto charaButton = Sprite::create("btnChara.png");
    if (charaButton == nullptr)
    {
        problemLoading("'btnChara.png'");
    }
    else
    {
        charaButton->setPosition(Vec2(sprite->getPosition().x + sprite->getContentSize().width * scaleRate / 2 + origin.x,
                                      buttonBase + origin.y));
        charaButton->setAnchorPoint(Vec2(1.0,1.0));
        charaButton->setScale(buttonScale);
        buttonBase -= charaButton->getContentSize().height * buttonScale;
        this->addChild(charaButton, 1);
    }

    auto equipButton = Sprite::create("btnEquip.png");
    if (equipButton == nullptr)
    {
        problemLoading("'btnEquip.png'");
    }
    else
    {
        equipButton->setPosition(Vec2(sprite->getPosition().x + sprite->getContentSize().width * scaleRate / 2 + origin.x,
                                      buttonBase + origin.y));
        equipButton->setAnchorPoint(Vec2(1.0,1.0));
        equipButton->setScale(buttonScale);
        buttonBase -= equipButton->getContentSize().height * buttonScale;
        this->addChild(equipButton, 1);
    }

    auto questButton = Sprite::create("btnQuest.png");
    if (questButton == nullptr)
    {
        problemLoading("'btnQuest.png'");
    }
    else
    {
        auto scale = buttonBase / questButton->getContentSize().height;
        questButton->setPosition(Vec2(sprite->getPosition().x + sprite->getContentSize().width * scaleRate / 2 + origin.x,
                                      buttonBase + origin.y));
        questButton->setAnchorPoint(Vec2(1.0,1.0));
        questButton->setScale(scale);

        this->addChild(questButton, 1);
    }

例えば、「キャラ」のアイコンは「ホーム」のアイコンの下に並ぶように座標を計算して配置していますし、

その下の「装備」も「キャラ」の下に並ぶように座標を計算で算出しています。

「クエスト」のボタンは、上の3つのアイコンを並べた空きスペースにピッチリ収まるように、拡大率を算出して配置しています。

アイコンの拡大率も計算で算出しているので、機種や解像度が変化しても、アイコンの大きさが変わる程度で、大きくレイアウトは崩れないと思います。

思った以上に良い感じです。

【プロジェクトセカイ】指をクロスさせる必要なんて無かった

問題の譜面。

いろいろ試したんだけど、

やっぱり指をクロスさせるにはやりづらくって、

いや、指をクロスさせても問題無いのよ。

でも、指をクロスさせなくても、指がホールドのバーの中にあればコンボが繋がる事が分かりまして、

はるかに、こちらの方が簡単。

でも、こんなの最初見たときは戸惑うわな。

ラズパイ 400(Raspberry Pi 400)が普段使いできるPCになるわけないだろう。

自分、ラズパイ4を使用しているが、この記事には唖然とした。

そりゃ、サイトとしてはラズパイを持ち上げざるを得ないかもしれないけどさぁ。

そもそも、CPUは他のPCと比べて遙かに劣っている。

ラズパイで動作しているOSやアプリケーションはラズパイ用に最適化・軽量化しているので、そんなマシンでPCが使用しているようなアプリがまともに動くわけがない。

Webツールも然りである。ブラウザ自体が軽量化されているので、まともにJSが動く保証はない。

それでもラズパイ4でだいぶマシになった方だけれども。

ただ、ラズパイ4で電子工作を行う場合としては、遙かに魅力的なマシンである事には間違いない。

【テクテクライフ】北海道開拓の村

特にチェックポイントはないのですが、近くの牛角に予約を取っていたので、ついでに行ってきました。

ここは敷地が全て野外の博物館の様になっていて、北海道開拓時代の建造物がこのエリアに移設、復元されています。

明治・大正時代の建物ばかりなので、かなりレトロな雰囲気を体験することができます。

建物自体は未だにしっかりしているので、冷暖房さえ完備すれば住めそう。

こういう所でキャンプしてみたいな。

なんかおった。

出口にリンゴと大根の無人販売がありました。

大根50円。

大根の美味しい食べ方を検索中。

お疲れ様でした。

VPSをHTTP2に対応させてみた。

簡単にできるんだね。

こちらのサイトを参考にしました。

http://www.dcom-web.co.jp/lab/web-server/nginx_with_http2

nginxの設定でlistenにhttp2と書き足すだけで良いらしい。

Protocolがh2になっていれば、HTTP2を使用しています。

HTTP2で何が変わるのか?

従来のHTTP1.1では、1リクエストに対して必ず1レスポンスを返す必要があります。

1ページの中に複数のコンテンツ(htmlとかjsとかcssとか)が合った場合、これらのファイルを一つずつダウンロードする必要がありました。

しかし、HTTP2では、多リクエスト、多レスポンスが可能になります。

これはどういうことかというと、送信中のリクエストの応答を待たずして次のリクエストを出せるのですね。

なので、複数のファイルを平行してダウンロード出来るようになります。

なので、その分ページの読み込みが早くなります。

今のブラウザはほとんどHTTP2に対応しているので、あとはサーバ側の設定を変えればHTTP2での通信になります。

あ、それと、HTTP2はデフォルトSSLによる暗号化通信なので、サーバ側に証明書が必要になりますよ。

HTTP2に関する小話

HTTP2は元々Googleによって開発された通信プロトコルで、後に正式にHTTP2の規格に採用されました。

TCPより上位のプロトコルなので、簡単に双方向の通信を行うことができます。

おそらく、最近のスマホゲームのマルチプレイなんかは、この技術が使われていると思われます。

それ以前は、一つ下位のプロトコルである、TCPで通信していたと思われます。

でも、TCPって思った以上に扱いが難しんですよね。

nifmoからBIGLOBEモバイルに乗り換えようか、と言う話。

今、スマホのSIMは、格安スマホのNifmoを利用しているのですが、

プロバイダーがBIGLOBEに変わったので、

格安SIMもBIGLOBEモバイルに乗り換えようか、と思いました。

回線をまとめた方が良いのかな、というざっくりとした考え。

ということで、料金プランを比較してみた。

今利用しているNifmo。

https://nifmo.nifty.com/sim/card_voice.htm

今7GBのプランを使用しているので、月2300円支払っています。

BIGLOBEモバイルの料金プランを見てみると、

https://join.biglobe.ne.jp/mobile/plan/?cl=head_mobile_plan

ギガの容量が違うので、細かい比較はできませんが、

例えば、ギガを6GBに落とせば少し安くなる計算ですわな。

では、今の利用状況を確認すると、

6GBじゃ足らんかったわ。

7GB越えて利用できているのは、先月の繰り越し分らしいです。

おそらく、位置ゲーとテザリングでの利用が大半だと思います。

家ではWiFiでゲームしているので。

うーん、乗り換えるメリットが無くなってきたぞ。

さらに、MNPを行うのに、Nifmoに手数料3000円必要になり、BIGLOBEのSIMを発行して貰うので、おそらく初期手数料3000円かかるでしょう。

うん、やめよう。

メリットがない。

今のギガが足りなくなって、大容量プランに切り替える場合にまた考える。

マインクラフトサーバを外部に公開しようと思ったけど

モデムの設定を変更して、グローバルIPに接続すれば内部の仮想PCに繋がるようにして見たんだけど。

ダメだった🤔。

グローバルIPにpingを送っても応答がない。

いや、正確には、自分のPCからpingを送ると応答があるが、

外部のpingツールサイトを使用すると応答がないのである。

そして、今朝、もう一度確認してみると、

外部からの接続を可能にする設定が消えていた。

※後で分かったんだけど、昨日から今日までの間に、IPv6に切り替わったらしい。おそらく設定項目が変わったのはその影響じゃ無いかと

でも、外部に公開する手段が無くなってしまったので。

頓挫しました。

しゅーりょー。

【北海道大戦】確認ダイアログ追加とバグ修正

https://github.com/takishita2nd/HokkaidoWar

最初のプレイヤーの都市選択で確認ダイアログを出すようにしました。

あとは、最後までプレイできることも確認しました。

ただ、戦力差がありすぎると、バトルがワンパンで決着が付いてしまうのが、ちょっとよろしくないですね。

マインクラフトサーバ(仮想PC)にファイアーウォールを設定する。

このやり方で設定できるはず。

ただしHTTPは動かさないので、その設定は省いている。

$ sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
$ sudo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$ sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
$ sudo iptables -A INPUT -i lo -j ACCEPT
$ sudo iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$ sudo iptables -P INPUT DROP
$ sudo iptables -P OUTPUT ACCEPT

さらにマインクラフトのポート番号を開ける。

$ sudo iptables -A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT
$ sudo /etc/init.d/netfilter-persistent save

この状態でLANからサーバに接続できることを確認。

そしたら、ルータの設定を変えて、仮想PCに流れるようにしてみようか。

【ラズパイ】【カメラ】クライアントを閉じたら動画撮影を終了する

前回のままだと、クライアント側(ブラウザ)を撮影中に閉じてしまうと、動画撮影を終了する人がいなくなってしまいます。

これを防ぐためには、クライアントが生存していることを常に確認する処理が必要になります。

まぁ、今回はプレビュー画面で常にデータのやりとりを行っているので、これを利用しましょう。

    def do_GET(self):
        parsed = urlparse(self.path)
        if parsed.path == '/Streaming':
            global lasttime
            lasttime = time.time()

            enc = sys.getfilesystemencoding()

プレビュー画をリクエストがあったら、その時間を記憶しておきます。

def videoCapture():
    global capture
    global out

    while capture:
        nowtime = time.time()
        if nowtime - lasttime > 10:
            capture = False
            out.release()
            out = None
            break
        _, img = cap.read()
        out.write(img)

ビデオキャプチャーの周期処理の中で、現在時刻と、プレビュー画要求時の時刻を比較します。

周期処理の時刻がキャプチャー時の時刻より10秒経過していたら撮影を終了します。

ブラウザを撮影途中で閉じた場合、プレビュー画要求時の時刻が更新されなくなりますので、こうすることで、ブラウザを閉じてから10秒後に撮影は終了します。

さて、カメラでやりたいことが終わってしまった・・・

次何しようかな。

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