Delphi凸凹道 unit 1;

私が歩いた凸凹道(落石注意)。 unit1は始めたばかりの頃の話が大半です。
ページ単位で取り上げるような物は別途書くでしょう。
なお、私はDelphi3, Delphi5とVB5.0を使ってますので、 それぞれ現在の最新バージョンとは異なる記述があります。
VBはちょっとは分かるような感じですが、Delphiは初めてでした。 何がなにやらわかりません。
でもMSX-BASICからVisualBasicに移った時、 少なくともBASICの基本構文は覚えてました。だからその点では恵まれてたかな。 ゲーム(特にRPG)の表現方法も知ってたし。
Delphi移行時にはWindowsのプログラミングスタイルとか、 いくつかのAPIは知ってました。だから結構今回も恵まれてたかも。 APIはVBもDelphiも同じだし。
それにあちこちいろいろ調べれました。 ちょっと昔は情報断絶状態だったけど、今はずいぶん良くなりました。 昔はインターネットって夢のまた夢・・どころか、存在すら知りませんでした。

私が買ったのがDelphi3。立ちあげて絶句。 関数の一覧の表示が無い・・必死に探してました。 無いはずはない。
無い。オブジェクトインスペクタでイベントの一覧はあるんだけど関数はありません。 こんな環境で開発出来るのか・・ 慣れれば良いかもしれないけれど、VBからの移行組には辛いです。
結局、関数表示をサポートするツールを探してきました。 Source Waypointが便利です。ctrl+wで関数一覧が出てきます。
なおDelphi4以降にはコードエクスプローラーとして関数表示機能があるようです。

ブックマークが無い。・・いや、あった、あります。
CTRL+SHIFT+数字キーで印をつけれます。CTRL+数字キーでそこにジャンプ。 ヘルプは読みましょう。いろいろCTRLキーとかの組み合わせがあるみたいですね。

コード補完機能がDelphiは遅いです。VBは瞬時に候補が出るのですが、 Delphiだとウェイトが常にかかります。ウェイトの調整は出来るのですが、 最速にしてもウェイトが入ります。
結局この機能はOFFにしました。いる時はCTRL+スペースで使えますし。

VBでは大文字小文字の自動変換をしてくれましたが、Delphiはやってくれません。 いちいちShiftキー押して変換しなきゃいけないから面倒。 全部大文字とかにすると訳が分からなくなるし。
でも長い文ならVBもDelphiもコピー&ペーストで済ませます。

使えないコード補完にしろ、 大文字小文字の変換も結局は慣れますね。 数ヶ月やってるとこれで当たり前のような感覚になります。 で、たまにVBをやると驚く。

本屋にDelphiの参考書籍を求めて出かけていったのだけど・・無いっ。
あ、全くDelphi本が無いって事ではなくて、 ゲームやCG作成に参考になりそうな本が無かったのです。 VB本はいっぱいあるのに。シェアの差ですね。
仕方ない。Delphiマニュアル+ヘルプ+WWWで何とかしよう。
(最近は増えてきたような気も・・)(また減ったな・・)

for文。がーん・・Step実行が無い。 他のループで何とかしよう。1ずつ増減するのならいいけど。
Case文。がーん・・文字列条件使えない。
BASIC>Pascalでいろいろ文法差に戸惑います。

べき乗。VBで言う「^」です。 Pascalにはべき乗の演算子が無いみたいですね。
Power関数がべき乗の関数です。mathユニットに入ってます。
あ、mathユニットってDelphiスタンダード版に無いみたいです。 VB5もラーニング版は不幸なバージョンでした(SP対象外だった)が、 それはDelphiも同じ。 第一Delphiスタンダード版にはVCLソースが無いらしい。
あ、べき乗自体はPower無しでも計算で何とか出ます。

LineとかCircleとか、他にもいろいろ・・Delphiに無いです。 ただほとんど同じ命令はあるし、数行で表現出来るから関数化しとこう。 VBと同じ形式にしておけば移植が楽になるし。
言語仕様的なものは違うと困るけど、 こういうのは代用の関数で済ませる事が出来るから楽。 無い物は作る。
あ、こういうVB的関数集も上手くまとめたらおもしろかったりして。

フォントサイズはVBでは手を焼きました。 画面のプロパティ>ディスプレイの詳細で、 Windowsのフォントサイズの設定が出来る訳ですが、 ここを変えちゃうとコントロールの大きさとかみんな変わっちゃう訳です。 VBの時はフォントサイズを確認しながらコントロールの大きさを変えて、 画面に入るように調整しました。これってとても手間がかかるんです。
あ、女神戦はフォントサイズ小が標準です。 ただ、フォントサイズ大でまるで駄目なのは問題なのでプログラムで調整してました。
さて、Delphiです。Delphiは設計時のフォントで実行する事が出来ます。 オブジェクトインスペクタでフォームのScaledプロパティをFalseに設定すればOKです。 実行時のフォントサイズに影響されずに設計時の大きさで動かせます。 これって凄くいい。Delphiやって良かった。
この時文字の大きさはSizeではなく、Heightで指定していく事。 Heightはピクセル単位です。Sizeは実行時のフォントサイズに依存しまたおかしくなります。
あ、ゲーム以外のアプリだったらフォントによって大きさ変わった方が良いかな。

DelphiについていたAPIヘルプ。これ英語版なんです。 何か嫌だなって思ってたら日本語版ヘルプはDelphiのCD-ROMに入ってました。 ただ、ちょっと古いバージョンのヘルプだけど・・。
DelphiのCD-ROMには他にもいろいろ入っています。 例えばVbdelphi.hlp。VBの命令をDelphiでどう書くのか書いてあります。 ただ、これもちょっと古い版・・多分Delphi1とVB2くらいかも。
おまけなんですね、こういうの。でも助かりました。

Gosub〜Return。
MSXの時にはとてもお世話になりました。VBにもあります。 VBではあまり使われない命令のような気もしますが。これは関数内にサブルーチンを作って呼び出す命令です。 Gosubで飛んで、Returnで返ってきます。
Delphiには・・無いだろうなって思ってましたが、それに近い物がありました。 関数内関数と言われる物で、関数の中にいくつも子関数を作る事が出来ます。 通常の関数と同じ様に使えます。
その関数でしか使わない命令はその関数内で終わらしたいので、こういうのも便利です。

キャンバスに文字を書くとき、文字の無い所を透過させる。 これもAPI。VBと違って宣言無しで使えるしずいぶん使いやすいですね。 VB以上にAPI必須って気もするけど。 SetBkMode(Bitmap.Canvas.Handle, TRANSPARENT)。これで文字の背景が透明になります。

ゲームのデータファイル。VBもDelphiもマニュアルにはデータベースがどうこう書いてありますが、 使いません。ファイルをオープンして必要なデータを読み書きしてクローズする。 こっちの方が楽だし、慣れてます。
AssignFileで外部ファイル開いてその後いろいろ(省略)するんだけど、 VBとDelphiってデータの並び方違うみたいですね。 単純に並べるだけなら同じだけど配列変数使ってごちゃごちゃしてくると、 VBで書いたファイルがDelphiで読めません。 読み込む順番を工夫すれば何とかなるはずだけど。 まぁ良いか・・別のファイルにしておけば。 と言う訳で、VB版とDelphi版ではセーブファイルの互換性が無かったんです。
後、バイナリ。これだとVBもDelphiもほぼ一緒。

音楽を演奏する。VBではAPIのmciSendStringを使っていました。 Delphiは・・MediaPlayerでも使ってみようかな。VBでMCIコントロールと言われていたものとほとんど同じです。 VBの時はランタイム問題で使えなかったコントロールもDelphiなら使えます。
でも使ってみたんだけど・・何だか遅い。演奏開始時でかなりのタイムラグがあります。 これでは使えないので結局mciSendStringでやる事にしました。APIなら何とかなる。 VBとほとんど同じでした。(APIだから当たり前ですね。
ただPChar型を使わないといけなかったので、これがちょっと混乱したかな。 VBは全部String型で良かったのですけど、DelphiはPCharって言う型を使わないといけなくて・・ 結局PCharは文字列へのポインタでした。
あ、VB版ではタイマーコントロールで演奏状態をチェックするようになっていましたが、 Delphi版は演奏時間を設定した後、その時間までただ待ちます。 演奏チェックをしない分、環境によっては少しは軽くなったかも・・

VBのDoEvent。一旦Windowsに処理を返す命令です。 DelphiではApplication.ProcessMessagesになります。 VB同様にこのタイミングで意図しないイベントが入り込んでしまった事があります。 例えばApplication.ProcessMessagesした瞬間にキーボードを押して別のイベントが発生したりとか。 うまくフラグではじけば何とかなります。今回も結構はまりました。

VBはEnd命令で終了したのですが、Delphiにはありませんでした。
Haltで無理矢理止める事も出来ますが、それは危ないので使いません。 Haltを使うとVBのEnd命令同様にすぐ止まりますが、リソース解放し忘れとかあるそうです。
DelphiではApplication.Terminateを使います。これはすぐには止まりません。 全てのプロセスを実行後にやっと止まります。 と言う事は、終了処理に入っているのにプログラムは普通に動いたままになります。 フォームとかこの時点ではもう消えているので普通に処理されたらエラーになるし、 ループに入って出てこれないケースもありました。 上手くフラグではじいてExit使ってプロセスを終わって、ルーチンの上へ上へ脱出させます。

Delphiはコンポーネントとか、 フォームを描き込む時(実体化する時)いったん灰色で塗りつぶす事があります。 (灰色かどうかはその時の設定によって違うけど)
VBはそんな無駄な塗りつぶしはおこなわずに直接描き込みます。 Delphiは塗りつぶす分ちらつきます。
フォームは塗りつぶしのメッセージをとらえて、塗りつぶさないように出来るのですが。 問題はBitBtnとかで・・いちいち塗りつぶされたらコマンドウィンドウを出す度に灰色出されては嫌だし・・ でもどうにもなりません。仕方が無いのでVCLのソースを参考にして改造BitBtnを作りました。 これが光の女神戦Delphi移植で一番苦労してた所です。1ヶ月かかりました。 Delphi始めたばかりの時にコンポーネント製作・・結構辛かったです。

CG処理。主にBitBlt。VBからDelphiにしてどれだけ速くなるんだろう。 20倍速?50倍速?
結論、ほとんど同じ。BitBltはBitBlt。VBで実行しようとDelphiで実行しようと一緒。 まぁ、光の女神戦VB版の時点で十分速かったし、後はDirectXなら変わる程度かな。
あ、ウェイトいっぱい入りますので、フルスピードは出しません。 いろいろパソコンがありますが、 速度差がとても大きいのでウェイトで速度差を吸収しています。 遅い環境で実行した場合、ウェイトを小さくするようにして調整しています。
そう言えばDirectXって夢の女神戦時点で実現していたんですね。没にしたけど。 理由は私が使いたかった機能をビデオカードが対応していなかったからです。

どういう訳かリソースからRLE圧縮BMPを読み込んだら(LoadFromStream)、GDIリソース(だったと思う) が漏れてました。何でだろう。DDBとDIBの変換部かな・・ これは謎。Delphiのバージョンによって違うのかな。
良く分からない。で、結局の所RLEは使う必要はありません。 圧縮率で言えば通常の256色BMP+LHAと、 RLE圧縮+LHAでは前者の方が小さくまとまるケースが多いです。

キー入力を調べる。大抵はフォームのキーダウンイベントでキーを検知して、 API/GetAsyncKeyStateを使ってどのキーか判別します。VBの時と一緒ですね。
キーダウンのキー引数はあまり使わないです。 使う時もあるけど、キー検知後にループとかに入る場合が多いので、 GetAsyncKeyState使用が多いですね。 キー引数は最初に押したボタンしか分からないし。
GetAsyncKeyStateはその時点で押したキーを判別します。
if (GetAsyncKeyState(vK_Return) and $8000)<>0 then 〜押した処理・・ って感じ。
ボタンは仮想キーコードってのを使うんだけど、 どういう訳か一部のキーコードが使えない・・あれ? VK_AとかVK_B辺り。値を直接指定してます。 Aなら41。
あ、無ければ自分で定義すればいいか。

とりあえずここまで。つづく、かも。