Tsuzu's Notes

主にIT系備忘録

【Siv3D AdC 2015 15日目】 3DゲームとそのためのBullet&Siv3D連携ライブラリを作った話

この記事はSiv3D Advent Calendar 2015の記事です。

Tsuzuです。STEINS;GATE 0をやっていたら記事が書けず前日に焦って書いてます、ごめんなさい。
かれこれSiv3Dを使い始めて1年近くが過ぎたようです...。時がすぎるのは早いですね。
今回は今年、私の学校の文化祭で部活で展示したゲームを作った話をさせていただきます。

ゲームの概要

3Dの四人対戦ゲームです。 ルールはとても単純で、自分の陣地に、地面に落ちているオブジェクトを運んでくる、というだけです。オブジェクトの形状によって得点が異なります。 また、このゲームは4人で遊ぶことを前提として作られているためCPU対戦などは搭載しておりません。 f:id:tsuyochi23182:20151214145349p:plain

製作について

実装コストの高いDirectXを直で触ったり、C言語的なインターフェースのDxLibを使うのは気が進まなかったので現代的なC++で書くことができるSiv3Dを利用させていただきました。また、内部的に物理演算を利用する必要があったため、Bullet Physicsを利用しました。
そして製作する上で最も苦労したのが3Dの複数視点です。Siv3Dの3D機能はまだ不完全(これからどんどん良くなるようなので期待です!)のため、複数の視点を扱うことはできませんでした。そのため、4つのexeに描画を分けて行わせることで対処しました。サーバプログラムとクライアントプログラムをわけ、プロセス間通信にはThriftを利用しました。(今回はThriftを利用しましたが次期Siv3DではTCP通信に対応するようなのでそれを使えそうです。Thriftでは転送用に別途クラスを定義する必要があったので大分手間が省けそうです。)
また、四元数(Quaternion)はあまり使ったことがなく、慣れなかったので度々苦労しました。 今回、システム側の製作に時間をかけてしまってデザインなどに力を注げなかったのがとても悔しいです...。また、Siv3DのSlackや、TwitterでSiv3D製作者の@Reputelessさんには度々アドバイスをいただきました。製作者と簡単にコミュニケーションが取れるのはこのライブラリの他ではなかなかない、とても良い点だといつも感じています。

Siv3DとBulletの連携ライブラリ

実は、大変でしたが楽しかったところでもあります。製作の中で一番最初に行いました。
Siv3D(正確にはDirectX)とBulletでは座標系が異なります。それ自体の変換はZ軸の値をひっくり返すだけで良いのですが、各部分に適用させるとなるとこんがらがりました...。
仕組みとしては内部的にSiv3DとBullet側のbodyを同時に保持するクラスを作り、update関数が呼ばれるときにアップデートとstepを行い、draw関数が呼ばれたときに物理演算から座標および回転を取得してそれをSiv3Dで描画するようにしています。
拡張性のためには描画処理を内包するのは良くないとも考えましたが、とりあえず今回使いやすくなれば良いと思い、内包した形にしました。今後描画時に関数を指定して自由度を挙げれるようなものにしようと思っています。
需要はないと思うんですが近いうちにコードを綺麗にしてバグ修正をして公開しようと思っています。よろしければ使ってやってください。

おわりに

いつもSiv3Dと製作者の方にはお世話になっています。ありがとうございます。
1月には新バージョンも出るということで新機能をVisual Studio 2015で使えることを楽しみにしています。個人的にはMac版も待ち遠しいです(

明日の記事はChunChunMorningさんです。よろしくお願いします。

部活動での活動と、個人的な活動 (中高生プログラマ Advent Calendar 2015)

この記事は中高生プログラマ Advent Calendar 2015の記事です。

はじめに

Tsuzu(@Wp120_3238)です。 1日目の記事として、私の参加している部活動の活動と、軽く個人的な活動について話したいと思います。
プログラミング言語C++を主に使ってます。

部活動での活動

私の部活は5学年合計で部員が50人ほどいます。(他のところを知りませんが)パソコン部の中で見ても人数は多いほうかな、と思います。 音楽、CGなどを製作している部員もいますが、私は(芸術的センスがないので)プログラミングしかしていません。

競技プログラミング

競技プログラミングとは、簡潔に言えば問題が出され、その問題の条件に沿ったソースコードを書いて得点を稼ぐ競技です。
最近では数多くの大会が開催されています。
私の部活でも幾つかの大会に参加しています。今年私は以下の大会に参加しました。

  • 情報オリンピック (以下JOI)
  • パソコン甲子園
  • Super Computing Contest (以下SuperCon)
  • パソコン甲子園は予選落ち、JOIは本選*1で敗退しました。
    SuperConでは、友人とチームを組み、本選に進みました。SuperConの本選は、いつも使うパソコンではなくスパコン*2で動くコードを書かなければいけません。膨大な計算量を扱い、高速化するのが大変で、全5日間の日程中4日間は課題に取りくみ、朝早くから日が暮れるまでの長い間問題に向き合っていたため精神的にも肉体的にも疲れました。良い実績は残せなかったものの、他の参加者、来てくださっていた企業の方と交流することもでき、いつもはできない経験を積めたのでとても充実した5日間でした。
    あ、余談ですが、SuperCon、予選だけでもいいのでできればC++を使わせて欲しいですね...。

    ところで、この記事が公開された12日後にはJOI2015-2016の予選ですね...。去年は予選を突破できましたが今年はできるか怖いです...。
    私は競プロの雑魚ですが、このAdvent Calendarの参加者には多くのプロがいるので競技プログラミングに興味を持った方は期待していいと思いますよ!

    NFCによる出席チェック

    最近作ったものの紹介。 私の部活は前述の通り50人ほど部員がいます。今までは毎回部活の度に紙で出席をとっていました。データを集計するためには打ち込むという手間があります。さらに、そもそもここはプログラミングをする部活なんだからもっと電子的に出席を取っても良いのでは、と思い作ることにしました。私の学校はほぼすべての生徒が電車通学をしているので電子乗車券(SuicaPasmoなど)を持っています。電子乗車券の中にはICチップが内蔵されており、このICチップはNFC*3によって読み取ることができます。
    NFCを読み取るNFCリーダは、多くのAndroidデバイスに搭載されています。専用のリーダではなくAndroidデバイスを採用した理由としては、ドキュメントが豊富で、代用も効きやすいと判断したためです。また、各ICチップには識別IDが割り当てられており、これを使って部員の区別をしました。

    方法としては、IDを受け取って管理するためのサーバを建て、Androidデバイスからはソケット通信で読み取ったIDをサーバに送信します。
    最初に部員の学年、名前と電子乗車券のIDを紐付けました。そして、あとは部活に来たタイミングで部員に電子乗車券をAndroidデバイスにかざしてもらうだけで、自動的に内部識別IDに変換し、ファイルに書き込むようになっています。
    また、やむをえない理由で欠席することなどの登録や、IDの追加、削除等は専用のAPIを用意し、一部の部員から使えるようにしました。

    実際に運用を開始してから1ヶ月ほどが経ちました。 聞いた話によるとこういうシステムは大学でよく利用されているらしいですね。 最初のころ、財布にある関係ないICカードが検出されうまく出席が取れないなどの問題が起きましたが、それ以降は特に問題なく利用できています。 しかし、割と修正したいところはあります...。データベースも使わず全て平文のテキストファイルやjsonファイルで保存されていたり、エラー処理が適当だったりとかなり不十分な点は多いです(部内でしか使っていないので問題は起きていませんが)。また、今は部活に来たかどうかだけをつけていますが、来た時刻、帰った時刻までつけるようにしたり、Google Formsによる欠席連絡などの機能の追加も検討中です。 私が部活をやめるまでの間により良いものにして後輩に託せるようにしたいです。

    ゲーム制作とかもしたんですがそれはSiv3D Advent Calendarの方に書きたいのでここでは割愛します。

    個人的な活動

    一つのことにずっと拘って取り組む、といったことはあまりしていません。割と色々なことに手を出してみたりしています。ですが基本的に使うプログラミング言語C++のみです。
    一番よくやるのは、簡単に使える自分向けCUIツールを作ってます。(画像をpdfに変換したり、iOSデバイスを接続するとMacのロックを解除して外すとロックする、みたいなものです。) 私がプログラミングができて良かったと実感するのはそういうのを作った時ですね。 最近はC++14、1zなど新しいC++の機能についても興味を持って調べたりしています。また、沢山あるC++のライブラリに軽く手を出してみたりしています。C++のライブラリは(ネットワーク、GUI周りは不完全ですが)優秀なライブラリが多くそれらを使ってみるだけでも割と楽しめます。
    (作ったものはGitlabにアップロードしていますが大したものはありません...。)

    終わりに

    今回初めてAdvent Calendarに参加して記事を書かせていただきました。
    ソースコード以外の長い文章を書くことは少ないので読みづらい部分があると思います、すいません! 予想以上に堅苦しい文章になってしまい困惑しています...。画像とかをつけられれば良かったのですが生憎つけられる画像がありませんでした。とりあえず書き終えることができほっとしています。あとは他の方々の記事を楽しむのみです!
    今回このAdvent Calendarは色々な人と交流を持ちたいという目的だったのでTwitter等で絡んでいただけると嬉しいです。Tsuzu @Wp120_3238(再掲!!)

    明日はyuki74wさんの記事です。よろしくお願いします。

    *1:情報オリンピックは予選、本選の後、春合宿に進みそこで日本代表になる選抜が行われます。

    *2:スーパーコンピューター。今回のSuperCon本選ではベクトル演算器を利用したスパコンを利用しました。

    *3:Near Field Communication、近距離無線通信のこと。Bluetoothなどとは違い、とても近い二つのデバイスの間で通信ためのもので、片方のデバイスはICチップの場合もある。

    開発環境

    いつも使ってるものなどなど

    Hardware

    • Macのデスクトップ/ラップトップ各一台
    • iPhone 6s(iPhoneアプリ開発)
    • Xperia Z Ultra(Java打ちたくないからリモートコントロールとかファイル操作用)

    OS

    Editor

    • Sublime Text(よく使う)
    • Vim(設定ファイルいじるのと簡易コーディング)
    • VS Code(Markdownエディタ)
    • Xcode/VS2013, 2015(アプリ、ゲーム開発等)

    Compiler

    終わりに

    C++しか基本的に打ちません、C++でどうしてもできないなって思った時に適宜合ったものを使うようにしてます。 とうとうHTML/JS/CSSを打つ必要が出てきたので頭を抱えている今日この頃です。 一般的に使われているものしか使っていませんがそれが拡張性なども考慮すると一番だったりしますね。

    First commit

    いくつ目のブログだろう...

    何度ブログを潰して再び建てたかもはや覚えていません。
    Wordpressを自鯖に建てていたけれど管理とか面倒だったから無料のサービスを使うことにしました。
    ともあれ、よろしくお願いします。
    

    なぜ今更?

    Twitterで言うほどのことでもないけど、Qiitaに書くのもなあ、なんて思ったことを書き留めておく場所が欲しかったため。
    不定期で気ままに更新する予定。
    

    内容

    C++とかプログラミング系の記事が多くなりそう。
    あと他にもたまに書くかもしれないけれど前述の通り気ままだからどうなるか分からない。
    

    追記

    Hatena Blog、メインのUIはとてもいい感じだったけれど認証とかの裏のUIが微妙だった。
    普通は見えないからいいけれど。