「プログラミング」に関する日記(24)

プログラミング関係の話題。プログラミングコーナーを更新したとか、プログラミングの内容に踏み込んだ話とか。

<前 次>

値型と参照型

ああもう!
値のことは後で考えるとかいってたけど、よく考えたらノード一つ一つには何らかの形で値が含まれるわけだから、ちょっとの手直しならともかく、これから根本的に内容を見直す予定なので、値のことは先に考えておいたほうがよさそうです。
どんな風に根本的に見直すつもりなのかというと、現在はなんとなく基底クラスのポインタをノードに保持させておいて、そのポインタの指している実体は派生クラスという形を取っていたのですが、そうすると値のコピーという点で不都合なことが多いので、最初から全部の型に対応した構造体一つで値を表そうかと考えています。
で、これをそのまま実装すると使用メモリが増えてしまうので、ここらで共用体という今まで私が使ったことのない構造を使ってみようかと思っています。
ただ、共用体といえども大きなクラスを含んだりすると結果的に同じようなことになってしまうので、その点は値型と参照型という形で、まあ、なんというか、値を示す構造体に値の実体を入れるのと実体へのポインタを入れるので分けて、大きなデータの場合はまた別のところで管理して、その管理されているデータへのポインタを値として持っておこうと考えています。
そんなわけで、スキャナの書き換えは中途です。

スキャナ書き換え中

てなわけでスキャナの書き換えを始めました。
ノードはいろんなところで使いそうだしそれはそれで独立した内容を持っているので別ファイルに分けて、トークンの内容は完全にノードに含んでしまえるのでトークンのクラスは削除しました。
まだスキャナ自体の書き換えはできていないのでエラーが出ていますが。

型の不一致

スクリプトのパーサを作り始めてみて、スキャナがCMSToken型を生成して、パーサがCMSNode型を解析しているという、ちぐはぐな状態になっていることがわかりました。
これに対する対応は、一つには型をどちらかに統一する方法、もう一つには何らかの形で型変換をしてやる方法があります。
最終的な動作速度やコードの簡潔さで言えば前者のほうがよさそうですが、最初わざわざ分けて作ったものをまた統一するのはどういったものかと…

大雑把な計画

スクリプト講座、本当は配列について書こうと思っていたのですが、順番が悪いのと、パーサについてうまい考えが浮かんだので、急遽予定を変更してパーサの話にしてしまいました。

で、そのスクリプトを使う予定のBomber丸Worldですが、このままのペースでいくと、社会人になるまでに完成しそうにないので、ちょっとスケジュールを決めて期間内に終わるように考えたいです。
とりあえず7月中にスクリプトを作り上げ、7月末までにゲームとして動くようにして、夏休み期間を利用してテスト版を公開し、プログラムの動作チェックをしてもらえるようにしたいです。
そして翌年2月ごろまでにシナリオなども完成させて、3月末には正式公開できるようにしたいと考えています。
まあ、とてつもなく大雑把な計画ですが、なんとか頑張ってみます。

必要なファイルを見定めてました

で、Bomber丸のソースのあるフォルダを見ていたら、ずっと昔作った大砲で猫ちゃんをいじめるゲームを発見してしまいました。
非公式の拡張コントロールを入れていたため(公式だったら大丈夫という保証もないけど)ロードできませんでしたが、ソースは残っているはずなので、またソースから復元ができるか試してみようと思います。
猫ちゃんの絵の著作権が不明なので公開するならばキャラは変更しますが。

今度の更新はまたスクリプトのページにしようかなと考えています。
こないだ日記に書いたことを膨らませて。

ぅあ

自作スクリプト言語が暗礁に乗り上げそうだったので昔捨てたLuaについてまた調べてました。
まず、特定の命令を呼び出すには、Luaのassert(loadstring(s))()とCのlua_callを絡めて使えば好きなLuaプログラムをCプログラムから走らせることができそうです。
そして、以前の関数を上書きすることに関しては、変数と全く同じように受け渡しができるため、クラスの継承に似たことも簡単にできてしまうようです。

フェードできたぞ

ふにゃさんのフェードプログラム、実際に組み込んでみると、多少の問題はありましたが無事組み込めました。
ファイルの場所を移動した関係でリビルドしないといけなくなったり、MIDIイベントのステータスバイトにチャンネルが載ってこなかったり、イベントを変更せずにツールを通すにはタイムスタンプを押しなおした上でDMUS_S_REQUEUEを返す必要があったり、そのあたりの細かいところでちょっと詰まってました。
ともかくこれで、眠ったときの曲の切り替えがスムーズになり、またBomber丸Worldに使うことも出来るようになりました。

気のせいかもしれません

NeoMuplのMIDIポートの保存が出来上がりました。
本当は保存・読み込みはできていたのですが、保存すべきデータをセットしたり、読み込んだデータを反映したりするのを忘れていたため、今まで動いていませんでした。
デフォルトではあまりうまく再生できないMicrosoft Synthesizerになっていることが多いと思うので、ぜひとも変更しておくべきだと思うのです。

スクリプト言語の件、色々考えてみました。
関数については、if文などと同じように普通に解析して、解析時についでにその場所へのポインタを保持しておくということにしておけばうまくいきそうな気がします。
気のせいかもしれません。
配列については、値型ではなく参照型ということにしてしまえばなんとかなるかも、という気がします。
やはり気のせいかもしれません。

頓挫しそうだ

いやあ、久々の更新なのにネガティブな内容でごめんなさい。
とにかく値をどう扱うか、クラスとして扱うならクラスをdeleteするのはいつなのか、特に配列型というのは値でありながら内部に変数をも含んでいるわけですから厄介なのです。
もう、最悪の場合配列型は廃止することも考えなくてはいけなくなるかもしれません。
関数については、全部の処理を関数の中に入れているならあまり問題なかったのですが、普通のコードと混ぜて書かれた場合、普通のコードを解析しながら一方で新しい関数の出現を疑わなければならないので厄介なのです。

今日はNeoMuplを使ってVisualC#2005での発行の実験をしてました。
まあ、つまり、発行という機能を使ったことがなかったので、どんなものか見てみようと思ったわけです。
とりあえず現状のところ、使うことはあまりないかなー。と思っています。

VB版を読み込んだ!

スクリプト講座、書けるものならどんどん続きを書いていきたいんですが、どうにもこうにもゆきづまり気味です。
ん~・・・でも止まったら止まったでちゃんと止まったことを告げておくべきかなぁ・・・。

NeoMuplのVB版データのインポートができました。
文字コードの関係でリスト読み込みのところでのC#版データとVB版データの共存はできませんでしたが、リストに追加するだけならC#版データを考慮する必要がないので簡単でした。

カウンターが吹っ飛んだ

トップページを見ればわかると思いますが、カウンターが吹っ飛びました。
最近はバックアップを取ってないし、そもそも地味で目立ってないし、それ以前に私自身忘れかけてたので、もう戻さなくていいかと思ってます。
でも今後のためにロック処理はきっちりしておかないと。

それはそうと、爆ボンのページのバトルステージ4と7を詳しく書きました。
「よくばりはまれ」と「みずのせせらぎ」です。

それと、ふにゃさんのBGMの睡眠時用アレンジ、あれをMIDIファイルじゃなくてプログラムで制御することにしました。
というのも、Bomber丸Worldでも同じようなことをしようと考えていて、その練習もかねてDirectMusicToolを使ってみようと思い立ったのです。
そうでなくとも今の状態だと眠った次の瞬間に起こすとボリュームがおかしくなるので、そのあたりの不自然さの解消もかねています。

SetStretchBltMode

ふにゃさんの全体像画面、出来上がりました。
画面をはみ出すほど大きいステージだと縮小表示されるのですが、その縮小結果が最初やたらと黒々としたものになっていたので、どうなってるのかと思い、調べてみたら、SetStretchBltModeで縮小方法が変更できて、これの初期値が黒優先となっていたために暗い色ばかりになってしまっていたようでした。
それなりの画質で高速なものとか、高画質で低速なものなどがありましたが、通常チップは最初にマップチップそのものを高画質のStretchBltで縮小し、その結果をBitBltでどんどん使っていくという方式で速度を確保し、キャラチップのほうはその都度それなり画質のStretchBltで表示するようにしました。
なお、全体像では背景色は手抜きのため黒となっておりますのであしからず。
でっかいステージも9割方できてきました。

ところで、この高画質StretchBlt、実はTokioGLと縮小結果がほぼ同じなんですよね。
それでいてこのスピード、素人が練習で作った描画アルゴリズムとは根本的に違うのか、あるいはハードウェアで対応しているんでしょうかね。

NeoMuplは、プレイヤークラスをDirectShow、DirectMusic、普通は使わない無音の3タイプを作って、それらを一箇所で扱えるようにしていました。
DirectMusicは今のところ実装していないんですけどね。
あと、項目のプロパティの画面を作ったりしてました。
一応編集機能が、今実装できるものに関しては全部作り終わって、後はその変更結果を実際のデータに反映するところに来ています。

1173711171.png

ブレンディング

ふにゃさんのとげとげの拡張をするついでに、最後に一つ余ったキャラ枠をどう使うか考えてました。
順当なところで1アップか、あるいは取らなくてもいいけど取ったバナナの数にカウントされるボーナスアイテムか、それとも他のものにするべきか、そして決まったところで、アイテムの外観はどうするか、そのあたりが決まっていないのです。

それはそうと、画像フォーマットを一つ考えてみました。
インデックスカラーの長所で、パレットを差し替えれば画像全体の色が変えられたり、パレット番号何番は服の色、などと色に論理的な意味がつけられたり、そういうところを活かしつつ、なおかつたくさんの色を無理なく表現できてインデックスカラーの苦手そうなアンチエイリアシングもしやすい形式です。
まず、パレットは意味のある必要最低限の色だけを用意しておいて、画像本体には、どの色とどの色をどんな割合で混ぜ合わせるかのデータを入れるのです。
もしかしたら似たようなのが既にあるかもしれないのでまた調べてみます…。

LongScroll

VB6のスクロールバーの最大値を32767から2147483647に仮想的に引き上げるクラスを作ってみました。
方法としては、従来のスクロールバーの値域0~最大32767を0~好きな値にマッピングしているので、指定した値が32767を超えるとスクロールバーの指す値が大雑把になってきます。
例えば最大値を65534にすると、スクロールバーで指定できる値は、0、2、3、4、8・・・となりますが、もちろんその間の値もプログラム側で数値指定してやれば取ることができます。

とりあえず、これをByteEditとLineConstructorにつけてやって、ファイルサイズ制限や読み込み行数制限を取っ払ってやりました。
ByteEditのほうはヘルプも最新のスタイルシートを使ってリニューアルです。

オブジェクト配列

いやー。ListBox、stringの配列しか受け付けなくて融通が利かないと思っていたら、まるっきり逆で、ToStringさえ実装されていればどんなobjectでも受け入れるのでめっちゃくちゃ融通が利くみたいですね。
思ったより楽に進みそうです。

そうそう、パネルγのプレイ動画をアップしてみました。
さすがにマシンの性能が足りずコマ落ちが激しい状態になりましたが、せっかくなのでアップしておきました。

ListViewとDataBinding

ふにゃさんが一区切りついたのでナマライザ作ってました。
ListViewでもDataBindingが使えるかなと思ったのですが、どうにもDataBindingが適用できるのはどうでもいいプロパティばかりで、肝心のItemsプロパティには適用できなかったようです。
おかげで自分で表示を更新するプログラムを書かねば…って、本来これが当たり前なんですけどね。
まあ、表示そのもののプログラムは、表示するべきデータを用意するプログラムと比べればずっと単純で楽な作業であるはずなのでいいと思うんですけどね。

間に合った!

本当は今日やろうと思えば更新できたのですが、やっぱり時間がなくてうまくチェックできていない状態でアップするのはよくないので明日更新することにしました。
今日やったことは、リプレイの演出の改良、つまり本当のリプレイの完成。
そして、今更ながらふにゃの動きに関する不具合の修正。
この不具合は本当はずっと前からわかっていたことなのですが、それによってふにゃの動きが変わってしまうため、改善に踏み切れないでいました。
ただ、今度リプレイを実装するともう本格的に手遅れになるため、今回を改善の最後のチャンスとして、思い切ってみました。
もちろん、今まで放置できたのだから重大なバグであるはずがないのですが、ふにゃの向きに関するバグなので、見た目に左右非対称で不自然ですし、もしかしたらどこかで向きが違うために変な動きになる可能性もあるということで、修正することにしました。
あと、リプレイに関しては、にっこりキーが記録されていなかったので、それも記録するようにしました。
これもこれで一度公開してからでは修正できない部分だったので、なんとか間に合ったというところです。
あと、内部的にゲーム本編とテストプレイのプログラムを統合しました。
これによる大きな違いはありませんが、今後の改良の際に両方に反映するのを忘れてテストプレイだけ古いということはなくなるはずです。

そういえば、そろそろスクリプトのほうも進めてやるかと思い、久しぶりに見てみたら、全然わからなくなっていました。
元々方針を間違えていたのは明らかだったのですが、ちょっと今はそれを修正することはできそうにもありません。

メタルを逃がせ!

ドラクエ8やってました。
ちょっとした発見です。
おどかして追い払った敵からは経験値はもらえないがアイテムはもらえる、というのはよく知られたことですが、メタル系の敵はおどかし損ねたときに自らの意思で逃げることはしないのです。
つまり、普通に戦えばアイテムごと逃げられて得られなかったアイテムも、おどかして逃がせば手に入る可能性が高くなるのです。
だから、経験値よりもアイテムがほしい場合なんかは、下手に戦うよりもおどかしたほうが確実ということになるのです。
もっとも、レベルも上げたいので普通に戦いましたが。

PHPのarray_merge関数、仕様上重複する配列の要素が配列だった場合、古い配列は新しい配列でそっくり置き換えられて古い配列は残らなくなりますが、その点を改善して重複する配列の要素が配列だった場合、更にその配列同士をmergeする、mixed_mergeを作ってみました。
添字が数値だった場合array_mergeと全く異なる挙動を示すのが少し問題ですが、まあ、そっちのほうがTGscriptには合っているので。

データバインディング

いやー、使ってみるとなかなか便利ですね。
データバインディングとやらは。
データを与えれば勝手に表示してくれるのでプロパティの設定さえしてやればコードは一行で終わってしまいます。

爆ボンのラスボス戦のスピード攻略とその録画をやっていたんですが、なかなかうまくいかなくてかなり参ってしまいました。
何しろ初っ端で爆撃を始めてくれるかどうかがランダム、爆撃が終わってからお手玉で運べるかどうかもランダム、レグルスの奇行もランダム、で、シリウスが早い段階で攻撃してくれるかもランダムで、それを反撃に活かすのには微妙なタイミングが必要で、まあ、つまり、ものすごく運任せだったということです。
それで何十回となくやり直したんですが、一度成功して、それがほぼ完璧ながら少しだけ不備があり、だめもとでもう一度だけ録り直しをしてみたら、連続で成功してしまいました。
それもよりパーフェクトな状態で!

ジェノサイドキャノン!

VB小ネタを更新してみました。こっそり。
ダブルクリックのタイミング調整についてです。
ふにゃさんのエディタの改良に使ったもので。

で、今日はふにゃさんのバージョン1.04をアップしました。
YouTubeで動画を公開していた操作説明のほか、先ほどのダブルクリックでエディタを便利に使えるようになりました。
これに伴い動画のほうも正式公開として、ダウンロードページから見られるようになりました。
ちなみに、ダウンロードできるファイルのサイズが小さくなっているのは、アーカイバを変更したためで、中身は当然増えてます。

地球防衛軍1のインフェルノを全部クリアしました。
二人協力プレイで。
インフェルノだとダロガがなかなか強いです。
まあ、2だとバゥがイージーですら強かったりするんですが。
というわけでジェノサイド砲ゲットです。
4丁ジェノサイドなんてなかなかクレイジーです。

そして今日は、メテオスオンラインでも始めてみました。
まあ、オリジナル版と比べて、色々感じることはあるのですが、ポイント購入さえしなければただだし、よかろうと思います。

<前 次>