・ドキュメントD言語はC++と構文がかなり似てるのでdoxygen[仕様書生成ツール]が使えるのではないかと思います。→D言語のソースにdoxygenを使う・インターフェース外部(DLL側etc)からもEXE側のライブラリを呼び出したいことがある。例)スクリプトとしてのD言語そこで、インターフェースを用意したいです。外部から呼び出しもしないのにインターフェースだけ用意するとすべてのメンバ呼び出しがvirtualになってしまうのでまずいのかなぁと思います。簡単そうなところから作っていきます。タイマークラスの制作から始めようと思います。現在の時刻をUTCで取得します。この実装で1秒が何Ticksであるかを示す定数。精度がかなり悪いです。おまけに後者は249が返ってきました。期待はしてなかったですけど、かなりションボリです。ここは、timeGetTimeを呼び出す必要がありそうです。timeGetTimeはmmsystem.dllを呼び出します。ソースレベルでリンクするlibの指定ができるとよさそうですが、その機能はD言語にはありません。この時点で、SDLのほうにもtimerクラスぐらいあるという情報をいただいたので(そりゃまあゲーム用のライブラリなら持っていて当然でしょうけれど)Linuxのことも考えて、まずはSDLのほうのtimerクラスの出来を調べるところから始めましょう。(実は私、SDLはド素人です。)SDLについては、DedicateD[英語]のほうでD言語用のportingライブラリを公開されていますので、こちらからdownloadしてきます。あと、実装の確認のためSDLのソースも本家から落としてきます。SDLのtimerの実装(Win32)を見たところ、原則、timeGetTimeで、_WIN32_WCEシンボルが定義されているときだけ(WindowsCE環境)、GetTickCountを用いてありました。これは正しい実装です。timeGetTimeの前に初期化段階でtimeBeginPeriod(1)があることも確認しました。これで、Win32環境で用いるならば1msの精度のタイマーが得られることが保障されていることがわかりました。timeBeginPeriod〜timeGetTimeを行なっていないならば、SDLとは見切りをつけたほうがいいんじゃないかと思っていた私にとって、これは満足のいく実装でした。yaneSDK3rdのソースを持ってきて1時間ほどいじくる。これでfps設定〜調整、測定がこれを使うだけで出来るようになりました。サンプル書いておきます。秒間フレーム数30に設定。一回の描画処理に50ms必要。よって、実描画は秒間20回ほどしか行なえない。{//ここで描画処理を行なう//1回の描画に50ms必要だと仮定する。次にゲームで必要となる数学関係のものを制作。ゲームで必要となる数学関係のモジュール・高速なsin,cos,atan・MT法によるrand・ゲームで使うようなcounter・2次元ベクトルライブラリ(y4d_vector2D)・3次元ベクトルライブラリ(y4d_vector3D)MT法によるrandは誰かが用意していたようですが、OO風でないのが嫌なので、yaneSDK3rdのものを持ってきて10分ほどいじって完成。以下、MT法による乱数発生クラスの呼び出しサンプル。0;}高速なsin,cos,atan、それから丸め処理用の関数を用意。以下、呼び出しテスト。VirtualKeyy4d_inputは、ゲームで必要となる入力関連のモジュールです。JoyStickクラスについてjoystickは、軸もボタン扱いする。軸入力もボタンとして扱います。...(以下ボタンのついている限り)もっと多機能な取り扱いがしたければ、直接SDLを呼び出せば良いでしょう。ループ毎にupdateが必要。isPushは前回押されていなくて今回押されていればtrue。isPressは前回の状態は関係なく、今回押されていればtrueが返ります。0;}ジョイスティックがパソコンに繋がっていない場合、JoyStickにはNullDeviceとattachするので、エラーチェックなしにisPress,isPushを呼び出して構いません。KeyBoardInputクラスについてキー入力クラスです。SDLそのまま呼び出しているだけなので、何なく完成。SDLのキー入力は、ウィンドゥに付帯するものなので、SDLのウィンドゥを初期化してある必要があるようです。(なんだか使いにくいなぁ..)まあ、Windows以外のプラットフォームでは、ウィンドゥがないと入力出来ないこともあるでしょうから、仕方ないですか..。VirtualKeyキー入力統合クラスです。キーボードの↑キーと、テンキーの8キー、ジョイスティックの↑入力を、一つの仮想キーとして登録することによって、それらのどれか一つが入力されているかを、関数をひとつ呼び出すだけで判定できるようになります。全体的な流れは、キーデバイスの登録→仮想キーの設定としておいて、InputしたのちisPress/isPushで判定します。このクラスの応用事例なので、そちらも参照すること。yaneSDK2ndの時代から存在するクラスで、大変使いやすいので、非常に気に入っています。SoundLoaderクラスSoundクラスSoundはSDLを呼び出しています。wav,ogg,mid,riff,..etc..いろいろ再生できます。サウンドを再生するときはSDL_mixerを用いるとずいぶん楽です。SDL_mixerではmusicチャンネルと、chunkと呼ばれる8つのチャンネル、計9個のチャンネルがあり、それぞれを同時に再生することが出来ます。ファイルを再生するときに、チャンネルを指定しないといけないのです。そのへん、管理がなんだか面倒です。サウンドを停止させるときも、チャンネルに対して停止させることしか出来ないので、そのチャンネルを再生中なのが自分自身なのかどうかをサウンドクラスは把握している必要があります。MIDI再生できるのはmusicチャンネルのみだとか、MUSICチャンネルではRWopsが使えないだとか、SDLを用いたライブラリの設計者としては、いろいろ苦労させられる部分もあります。言っても、自前でサウンドクラスをがりがり書くよりは遙かに楽なので、ささっと作りました。その結果、再生は、これだけで出来るようになりました。endlesss.play();非常に楽です。あとは、これをcacheしたりするクラスを用意して、実際はそちらから使うと良いです。SoundLoaderクラスSoundLoaderは読み込みcacheを実現するためのクラスです。読み込みをしたときに、一番最後にアクセスしたものから自動的に解放したりする仕組みを提供します。サウンドにおけるクロスフェードとは、片方のBGMがフェードしながら、もう片方がフェードインしてくることを言います。y4d_auxの周辺FileSysクラスFileSysクラスファイルを検索するときに、pathとして指定されたフォルダも調べて欲しいことがあります。ファイルを読み込むときに、zipを読み込むためのアーカイバや、自作のアーカイバや、暗号化フィルタなどを通したいことがあります。商用ゲームならば、bmp(png?)が丸見えだとさすがに体裁が悪いので、暗号化フィルタを用意するのは当然として、暗号化フィルタを用意した結果、ファイルがシームレスに扱えないのでは困りものです。そこで、yaneSDK4Dで使用しているクラスは、すべてファイルを読み込むときは、FileSysを用いて、こいつがpathの処理や、アーカイバの処理を受け持ってもらうことにしました。ファイル名を連結するのにしても、駆け上がりパスなどを考慮しなくてはなりません。自動補間する"a"と"b"をつっつければ、"a\b"が返ります。3.駆け上りpathをサポートする"dmd/bin/"と"../src/a.d"をつくっければ、"dmd\src\a.d"が返ります。4.カレントpathをサポートする"./bin/src"と"./a.d"をくっつければ、"bin\src\a.d"が返ります"../src/a.d"と"../src.d"をつっつければ"..\src\src.d"が返ります5.途中のかけあがりもサポート"./src/.././bin/"と"a.c"をつっつければ、"bin\a.c"が返ります。".."で始まるならば、それは除去されない"../src/bin"と"../test.c"をつっつければ、"../src/test.c"が返ります。".././test.d";=>r"..\..\test3\test.d"FileSysクラスは、こういうファイル名の連結もサポートします。検索して、存在するファイルの名前が返る。ときに必要ならば自動的に呼び出されます。FileSys.read("src/some.txt");phobosのstd.zlibは、zip書庫をサポートしていないので自前で読み込む必要があります。→zip書庫の読み込み実装しました。FileSysを作っているときに気づいたことを書き残しておきます。・RWopsSDL_RWopsについては、こちら。http://risky-safety.org/~zinnia/sdl/sourcetour/no5/簡単に言うと、メモリ上に読み込まれたファイルを、ファイルっぽく扱うための仕組みです。これが必要になるかと言うと、FileSysではアーカイバ等も扱うのですが、展開後のものは、単なるメモリです。それを再度ファイルに書き出して、それを読み込んだのでは2度手間なので、そういうことはしないのです。メモリを直接指定して、それを使いたいのです。そのため、SDLではメソッド名の最後にRWとついているものがあって、そちらに対してはRWopsを渡すことが出来るので、これを利用します。ところが、SDL_mixerのmusicチャンネルとかは、RWopsを受け付けてくれないのです。MIDI再生などはファイルを指定でないと再生してくれない環境があるからだと思うのですが、これはかなり迷惑です。そこで、ファイルが実在すれば、そのファイル名を返し、ファイルが実在しなければ(ただし、アーカイブとしては存在する)、メモリ内にそのファイルを読み込み、テンポラリファイルに書き出し、それを返すようなクラスが必要になります。FileSys.TmpFileがそのための機構なのです。テンポラリファイルを生成するための方法が、PhobosやSDLには存在しないので、環境依存の方法で作成するしかなくなってしまいます。Windowsのほうは、何とかしておいたんですけど、他の環境は..適当な実装でお茶をにごしてあります。ThreadクラスMicroThreadクラスこのクラスを通じて呼び出した関数は、関数の途中でresumeし、次に呼び出されたときに、以前の状態を再現することが出来ます。詳しくは、こちらもどうぞ。→マイクロスレッドの実装ゲームでは必須のクラスと言えるでしょう。switching(次のスレッドへの切り替え)は、非常に高速で、Dコンパイラの場合、小さな関数ならばマイクロスレッド用のスタックも数百バイト程度で済むので、シューティングにおいて、敵一匹とか弾ひとつに対してひとつのマイクロスレッドを割り当てても構いません。yaneSDK4Dでも、ゲーム用のフレームワークとしては、タスクシステムを実装した上で、マイクロスレッドを併用してプログラムを組んでいくことを想定しています。タスクシステムについては、http://yaneurao.hp.infoseek.co.jp/yaneSDK3rd/のサンプル10か、さらに詳しい解説については、やね本2などを参考にどうぞ。タスクシステム自体をクラスとしてあらかじめyaneSDK4Dに含めたほうがいいのかは微妙なところですが、とりあえずプロトタイプだけでも用意しておこうと思っています。Threadクラススレッドクラス自体は、std.threadかSDLのthreadを何らかのwrapを行なって使用するべきだと考えています。(まだ作りかけです)ただし、同期オブジェクトは、synchronized文/修飾子がサポートされているので、わざわざそれ相当のものを作る必要もなさそうです。2Dグラフィックスの周辺yaneSDK3rdのときはソフトウェアでαブレンドや加色合成etc..を行ないましたが、もうそういう時代でもないでしょうから、3Dのハードウェアアクセラレーションで行ないます。2D描画にも3D描画を用います。2D描画を行なうときは3Dの知識を一切知らなくても使えるようにしておきます。・加色/減色合成転送a)×b)の組み合わせすべて出来ます。ハードを用いるので、ブレンドだろうが、何だろうが、そんなに遅くはないです。(3Dのアクセラレーションをハードで行なえることが大前提ですが。fontの描画を行ないます。SDL_ttfは22ポイント以下のフォントサイズだと正しく描画できないので、n倍に拡大して描画して、それを自前で縮小するコードを書きます。Windows時はWindowsのフォントフォルダをディフォルトで検索しに行くようにしてあります。それから、文字リポジトリを用意し、一度描画したフォントはテクスチャ状態でキャッシュしていくようにしてあります。これにより、非常に高速に描画されます。etc..を実装して、Cg(シェーダー言語)を呼び出すようにするつもりです。CgはOpenGL用のものはportingされていますが、Windows上をメインのプラットフォームと考えているので、OpenGLの速度では少し耐え難いものがあります。よって、DirectX9にも対応させようと考えています。yaneuraohttp://bm98.yaneu.com/dlang/。