323DIA
アプレットはほぼ完成で、掲示板スクリプトを作ればミディビが本当のミディビになります。
掲示板との相性を考えるとまだ若干作らなきゃいけない部分もあるし全般設定はデザインがかなり悪いので改良する必要がありそうですが、機能としては大体出揃ったようです。
アプレットはほぼ完成で、掲示板スクリプトを作ればミディビが本当のミディビになります。
掲示板との相性を考えるとまだ若干作らなきゃいけない部分もあるし全般設定はデザインがかなり悪いので改良する必要がありそうですが、機能としては大体出揃ったようです。
ミディビ、テンポチェンジで手間取ってます…。
なんか、、、eclipseの止まるタイミングが分かりません。
なんでドラッグの最中に凍るかな。
ミディビ送信データを変更するためリンクを切ります。
そして今はエラーメッセージの表示方法とテンポ・作者などの全般設定を作っています。
ブラックシティのゴールドカードについて書き終えました。
これで隠しワールドを除けば全部です。
それでは、私はやることがあるので。
ブルーリゾートとホワイトアイス完成です。
今度はブラックシティ…アルタイルタワーはでかいから大変そうですが…。
そうそう、DirectX10SDKをダウンロードしました。
VC++6では引き続きDX8ですが.NETには.NET用のSDKがあるようなので。
そうそう、VC++6と.NETといえば、前の更新のときにわかったのですがVS2005EEって、最適化ができるんですね。
VC++2005EEは最適化ができるけどWindowsネイティブプログラムは作りにくい。
VC++6.0SSはWindowsネイティブプログラム作り放題だけど最適化ができない。
そしてVC++2005EEではスタティックリンクライブラリが作れます。
となれば、VC++2005EEでスタティックリンクライブラリを、目いっぱい速度優先にして作り、VC++6.0SSでそれを利用してソフトを作るのはどうかと思ったわけです。
プラットフォームSDKを使わなくて済んで、効率のよさが求められるアルゴリズムではVC++2005EEでライブラリを作って、メインのVC++6.0SSに組み込むんです。
次の更新は、VC++6.0SSで、直接コードを書いて最適化なしで実行するのと、最適化されたライブラリを呼び出して実行する場合の実行時間を比較する、ってのがいいかな。
で、早速ライブラリ一つ作ってみたんですが、もうびっくりするほど簡単でした。
ソースのCPPファイルを追加して一個関数書いてコンパイルしたらそれだけで一個の関数があるライブラリの完成。
難しそうだったら効率は度外視しようかと考えていたのですが、これはさすがに度外視するにできませんね。
グリーンガーデン完成しました。
ついでにボスもコンプリート。
ボスは前から書いてるのでリスト化だけ。
1面はずっと前に書いたもので、3面を今日作りました。
そうそう、あまり関係ないけどキャラボックスにちょっと手を加えました。
もしかしたらゲーム以外にも使えそうな気がしまして。
爆ボンのコンテンツ、レッドマウンテンが完成しました。
他もまあ適当にアトランダムに更新されてます。
そうそう、カスタムパーツも記載しました。
最終的にはあれにパーツの取れるステージのページへのリンクをつけるつもりです。
うちの爆ボンコンテンツはマニアックなデータベース兼完璧な攻略ガイドになる予定です!
Bomber丸Worldの開発室のBGMのページを必要なリソースのページに改装しました。
つまり、画像も含めて書いているということです。
要望があったので爆ボンのページを集中的に作ることにしました。
いつまで続くかわからないんですけど少なくともわくわくモードのゴールドカード100枚分は作るつもりではいますよ。
簡易攻略でも作っておけば後でまたゆっくりそれぞれについて記述しようと思います。
あたまいてー
そういうことで中間コードを書いてみました。
とりあえず今のアルゴリズムとしては、計算式を見つけたら何はともあれ計算結果を一時変数に入れる、配列に対しては要素に直接値を代入するか要素を変数に代入するだけしかしない(変数名、インデックス、値で3つになるため)、命令を呼び出すときはパラメータをリストで渡して結果を一時変数で受ける、などなど、変換規則も考えつつ書いてみました。
# 例えば、イベントとか
msg("ハローワールド!\nこんにちは世界である!!");
&eee(select("それがどうした", "なるほど", "げこげこ"));
sub eee {
talk("みふみん", "あなたは".$_[0]."とおっしゃるのですね。");
if ($_[0] eq "げこげこ") {
for ($i=0; $i<10; $i++) {
$p = $i*($p+1);
msg($_[0].$p);
}
}
}
$param0[0] = "ハローワールド!\nこんにちは世界である!!";
$temp0 = msg @param0;
$param1[0] = "それがどうした";
$param1[1] = "なるほど";
$param1[2] = "げこげこ";
$temp1 = select @param1;
$param2[0] = $temp1;
@_ = @param2;
gosub eee;
$temp2 = $return;
goto LABEL0;
label eee;
$param2[0] = "みふみん";
$temp3 = "あなたは";
$temp4 = $_[0];
$temp5 = $temp3 . $temp4;
$temp6 = $temp5 . "とおっしゃるのですね。";
$param2[1] = $temp6;
$temp7 = talk @param2;
$temp8 = $_[0];
$temp9 = $temp8 eq "げこげこ";
if (!$temp9) goto LABEL1;
$i = 0;
label LABEL3;
$temp10 = $i < 10;
if (!$temp10) goto LABEL2;
$temp11 = $p + 1;
$temp12 = $i * $temp12;
$p = $temp12;
$temp13 = $_[0];
$temp14 = $temp13 . $p;
$param3[0] = $temp14;
$temp15 = msg @param3;
$i++;
goto LABEL3;
label LABEL2;
label LABEL1;
$return = undef;
return;
label LABEL0;
昨日の。
やっぱり中間言語レベルまではコンパイルしたほうがいいかな。
などと思ってます。
だって、逐次解釈とはいったって、式の中に命令が入っていたり、特定の命令で実行する場所が色々な場所に飛んだりして、今どこの何を実行中なのかがある程度プログラムからわからないとうまく動かないんですよ。
例えば2つの関数の結果を受け取って一つの価を返す関数。
f(g(x), h(y))
みたいなのね。
BASICのような逐次解釈じゃ難しいの。
最低限gとhの実行結果を持っておく変数が必要なわけ。
ああなんだかわからなくなってきた。
3番地コードで示される中間コードにコンパイルするの。
Add X Y Z
といったら
X = Y + Z;
と解釈するみたいに。
ん~。
ちょっとサンプルプログラムを手動コンパイルして雰囲気をつかんできますわ。
Bomber丸Worldのイベントや戦闘時のキャラクターの行動等はPerlに似たスクリプトで作ることにしました。
なぜPerlっぽいのにしたのか。
第一なぜ既存のプログラミング言語と似たようなものを使うことにしたのか。
完全オリジナルじゃいけなかったのか。
まずやりたいことを考えてみます。
1.計算式を使いたい。
2.イベントでも戦闘でも同じ感覚で記述したい。
3.決まりきった処理は関数のようにして呼び出したい。
4.変数や配列を使いたい。
5.変数は明示的に宣言しなくても使えるようにしたい。
6.数値も文字列も深く気にせず使いたい。
7.長い行は複数行に分けて書きたい。
8.変数と関数の区別を容易に付けたい。
9...きりがない。
もちろん、Perlを完全に実装するなんて無茶なことはしません。
例えば、便利そうでも実装が面倒な連想配列は実装しませんし、数値は解析の容易な整数のみです。
変数の省略も原則として認めませんし、標準関数はほぼ全て新しいものに置き換えられて、ローカル変数なども基本的にありません。
また、Perlは実行時にコンパイルして中間コードを生成し、高速化を図りますが、全体的なスピードが要求されず、多くのスクリプトが次々呼び出されるRPGではインタープリタ式のほうが適切だと思うので今回はコンパイラではなくインタープリタとして作ります。
一応言語仕様そのものは汎用性のあるものに作るつもりなので、出来上がったインタープリタは今後公開することがあるかもしれません。
キャラボックスほぼできましたよ。
というわけで使っている様子を写してみました。
すごいですね。ラプソーン一番ですよ。
しかし一位ですら高々1.4KB。原稿用紙3枚半。
やろうと思えばまだまだいけそうですね。
System.Collections.Generic.SortedListって遅い!!
なんちゅう遅さだ!!
O(n)で要素を追加できるからx個のデータの中からn個をを追加するならO(xn)ですむはずなのにものすごく遅い!!
他のSortedDictionaryも同様。
私が欲しかったのは要素の追加が(logn)程度で行える、整列された、値の重複を許さない、値のコレクションだったのですが、どうにもなさそうだったので普通の配列で頑張ってみることにしました。
string[] outArray = new string[1];これ、O(n2)の処理なんですがもう感動的な早さです。
int count = 0;
bool found;
foreach (string data in inArray)
{
found = false;
foreach (string item in outArray)
{
if (item == data)
{
found = true;
break;
}
}
if (!found)
{
if (count >= outArray.Length) Array.Resize(ref outArray, count * 2);
outArray[count] = data;
count++;
}
}
Array.Resize(ref outArray, count);
Array.Sort(outArray);
キャラボックス作ってました。
.NETのピクチャボックスだとなんとGIFアニメーションが動くようです。
速度が全体的に鈍いけどかなり便利になってますね。
今日はゼルダの伝説から、ガロを描いてみました。
特に理由もなく。
こういう簡単な服装はええですのお。
ついに・・・ついにマザー1をクリアしましたよっ!
しかしザコの強さに比べてラスボスはたいしたことがありませんでしたね。
低レベルクリアとか一人クリアができるというのはこれゆえか?
何年もかけてプレイしたために最初のほうはほとんど覚えてないからまた今度最初からプレイしてみようかな。
後半のいいムードのイベントが台無しにならないような立派な名前をつけて。
「はぢをしれェ」という名前がまともに通るのはギーグに怒鳴られるシーンだけじゃないか。
VisualC#、どちらかというと―IDEの影響が大きいかもしれませんが―VisualC++6よりははるかにVisualBasic6に近い感じがします。
ちょっとコードの一部を出してみると、
pnlInfoUpper.Height = cmbName.Height * 3;
lblName.Left = lblGame.Left = lblInfo.Left = 0;
lblName.Height = lblGame.Height = lblInfo.Height = lblGame.Top = cmbGame.Top = cmbName.Height;
lblInfo.Top = cmbName.Height * 2;
lblGame.Width = cmbName.Left = cmbGame.Left = lblName.Width;
data.Load();
ChangeView(ViewMode.ABC);
LayoutInfo();
プロパティを指定してコントロールの大きさを変更してるあたり、いかにもVBです。
他にもVBと同じ仕様のforeachがあったり(本当にVBのFor Eachに括弧をつけただけです)、refをつけて明示的に参照渡しにしたり(VBではByRef)、VBをC言語風の見た目にしたような感じでした。
ファイルの読み書きについてはJavaに似ていて、System.IO名前空間のクラスを使って読み書きします。
StreamReaderはテキスト読み込みクラスで、
sr = new StreamReader(filename, Encoding.GetEncoding(932));
でテキストファイルを開き(Encoding.GetEncoding(932)はシフトJIS)、ReadLine()メソッドで一行ずつ読み込めます。
もしかしたら変な予備知識がない分VB.NETやC++.NETより使いやすいかもしれません。
いや、だからこそC#にしたんですけど。
そうそう、コーディング中にもガンガンエラーを出したりヒントを出したりしてくれるので下手にヘルプを引くよりまずは何かを入力してみるというのが結構有効です。
そして、ヘルプは、大して速くもない自分のパソコンを使うよりも、Googleで検索したほうが圧倒的に早く、正確な情報が得られます。
う~む、C#のコントロールによるレイアウトはJavaのように自然な大きさに調整されるとかそういうのはないみたいです。
でもまあレイアウト関連はVBとかに比べるとやっぱり自動的にやってくれる部分が多くて助かります。
えっとですね。C#。どっちかというとIDEも含めればVBに近いです。
VBをC風の文法でかけるようなものです。
オンラインヘルプがあまり当てにならないのがつらいところですがメンバ自動表示や、ツールチップなどで機能を簡単に説明してくれたりするのでそっちで補えそうです。
そうそう、ミディビ更新しましたよ。
内容はバグ修正のみ。プログラミングコーナーも更新です。
しかしVC++.NETを触ってみた感想、.NETにあわせてC++が結構拡張されてるみたいです。
^って何よ。
下手したらMFC以上にタチ悪いかも??
^というのはどうにもオブジェクトのハンドルらしいです。
gcnewで生成したオブジェクトを代入しているあたり、どうもガーベジコレクタが働いて、使われなくなったら自動的に解放されるらしいです。
しかし、後付けの機能が増えるに従い際限なく複雑化するC++がいい加減嫌になってきたので.NETはC#にすることにしました。
VC++2005はWindowsネイティブもできるから選んだというのに色々面倒なステップが必要な上にRADツールもつかずSDKは英語ということで、とても実用に堪えるものではなく、騙された気分でした(VC6があるので)。
というわけでVC#を導入。
なんかこれはこれでライセンス登録が必要らしいです。
でも少なくとも.NETに無理矢理C++を当てはめたVC++.NETよりは見通しがよさそうな気はします。
ドラクエ8のもう一つのエンディングを見てしまいました。
本当はただラスボスのマダンテが見たかっただけだったんですが、たいした技を使うひまもなくあっさりお亡くなりになられたのでそのままエンディングに入ったのですが、そこでアルゴンリングをもっていることに気づき、ククールにも指摘されたのでちょっと王様に見せてみたらなんか駆け落ちするはずだったところが堂々と結婚できることになり、チャゴスが前にも増して気の毒なことになってしまいました。
今日はMFCの練習もかねてキャラボックスのC++バージョンを作ろうとしたのですが、MFCをどう使っていいのか、画像形式は何が使えてどこまで表示できるのか、などがわからず断念し、.NETならどうかなと思ってVC++2005Expressをインストールしてみました。
ただ、インストールに時間がかかってしまったので本格的に使い始めるのはまだ先になりそうです。
ミディビを久々に更新しました。
今日やったのは、
・音の強さを変えられるようになった。
・編集単位の導入。
・演奏開始位置を指定できるようになった。
・ピアノロールをクリックしたときのコードをある程度まとめた。
・sequencerをMIDIAppletに移動。
・演奏/送信をMIDIAppletに任せてMIDIDocumentはデータ管理のみにした。
とまあ、こんなものです。
普段ならタグ使ってリスト表示と行くところですが、今回はサンプルに付属するテキストからのコピーなのでそのままプレーンテキストになってます。
そうそう、先ほどブラウザ上で動かしたら、演奏中に他のページに移動すると演奏が止まらなくなるバグを発見したのでそのうち直すつもりです。
多分明日になるでしょうね。
この挙動はプログラミングコーナーの更新ネタにはもってこい。
ドラクエ8で袋の中身を一度全部売ってしまったら50万ゴールド近くにもなりました。
大切な道具もあったのですぐリセットしましたが。
で、今日は弟がサントラを買ってきていました。
それで、曲の英語名を調べようと英語のサイトを回っていたら、北米版ドラゴンクエスト8の公式サイトに出会いまして。
北米版ではなんと主人公がスーパーサイヤ人になるみたいです(http://www.dragonquest8.com/)。
しかもボイスありということで。
北米ではドラクエは今まで初期のものしかなく間が長かったためドラクエを1から順番に見てきている日本人とは別の配慮が為されているようです。
個人的には日本がイバラに包まれるCMが好きですね。北米版。
竜の試練とやらを受けてきました。ドラクエ8で。
景品で新しい剣をもらいました。
メタルキング相手にはテンションを上げてはやぶさの剣+メタル斬りがもっとも有効ですが、普通の相手だとなかなかのパワーを見せてくれます。
ヨッシーストーリーを久しぶりにやったらデータが消えていました。
ハイスコアはともかくトライアルモードで選べるステージが減ったのはつらいです。
そうそう、旧TWSの掲示板を閲覧専用にしました。
書き込みのほうがもはやTGWSのほうで充分ですし、書き込まれるのも宣伝書き込みだけになっているのが現状ですので。
それでも掲示板そのものを消さないのは管理人の勝手な都合からです。
プログラミングコーナーのビット操作のところにビットフィールドのことを追記しました。
構造体やクラスの中限定で任意のビット長をもつ変数が使えるというのです。
ただ、ビットフィールドは構造体等の32ビット境界があるのでうまく変数をつめて書かないと帰って無駄が大きくなることもあり、また、配列が使えないという欠点もあったりします。
Bomber丸Worldでは、行動アルゴリズムをクラス化し、さらにGoToを実装しました。
GoToという行動タイプは今までになかったものですが、これは目的地をマップ座標で指定して、その場所へ向かうという行動を取ります。
簡単に言えば、人を追いかけるFollowの場所版ということです。
この行動は、まず目的地を最高点にし、他の場所に目的地に行くのにかかる歩数分だけ低くした点数をつけ、自分は最も点数の高くなる方向へ向かうというアルゴリズムになっています。
これ、まず全ての場所を最低点で初期化し、次に目的地を最高点にして、その場所を中心とした回り4箇所に点数をつけ、次は今点数をつけた周りに点数をつけ、更に次も同じようにして点数をつけ、自分の位置にたどり着くまでこれを繰り返します。
ただ、これを馬鹿正直に全部の場所を調べて点数をつけていたら検査する歩数の3乗のオーダーで処理回数が増え、高々32歩でたどり着く場所に1万回以上の処理が必要になったりするのでうまいこと処理を省くために調べる範囲を減らしたり調べるまでもないマスを読み飛ばしたりしています。
今日は押すアルゴリズムの改良と行動タイプ"Random"を実装しました。
押すアルゴリズムは、昨日作ったものだとキャラが沢山いたとき再帰呼び出しで無制限に次のキャラに動くよう促し続けると、袋小路などで「お前がどけ」「そっちこそ邪魔だ」の無限ループが発生し、フリーズすることがあったので、再帰呼び出しに制限を設け、一定回数以内の処理で動けなければその方向には移動できないということで解決しておきました。
一度これを呼び出し回数ではなく再帰の深さで判定するようにしていたのですがそうすると処理回数が4深さのオーダーで増えて、飛び出し回数で制限したときと同じ1024回で打ち切りにできるようにするには押せるキャラクターは高々5人程度になってしまい、人ごみをかき分けて進むようなネタが使えなくなってしまうことがわかったので、元の呼び出し回数式に戻しました。
再帰の深さを使ったバージョンは確実に動く人数を制限できるため、打ち切り深さを1から始めて順に深くしていけば動く人数を最小限に抑えることが可能だったはずなのですが、ちょっと袋小路の中に30人ほど人がいたら処理回数は10億回程度になりますからね、とてもじゃないが使い物になりません。
一方処理回数で打ち切る方式は適当に次々呼び出してどこかで道が開けた時点で処理終了になるのでどんなに遠回りだったとしても呼び出した経路上にいた人全員が動き出し、一人を動かすつもりが百人以上ごそっと動き出すこともしばしばです(もちろん数百人が密集していた場合だけですけどね)。
この方式だと呼び出し回数が確実に1024以下になるため、CPU負荷はそれほどかかりません。
まれに処理回数が1024に達してしまうほどの遠回りをして打ち切られることもありますが、その場合はそのフレームでは移動を諦めて、次のフレームで改めで最初から処理を開始すれば、動けるなら今度こそ高い確率で動けるでしょうし、動けなければ高々1024回の処理の後に何もしないだけです。
で、行動タイプ"Random"は、次の動きを決めるフレームでは上下左右に動くか、あるいは何もしないか、をランダムで決めます。
しかし今考えると、RPGの場合、話しかけられたら止まらなければいけません。
"Random"にしたキャラクターは結構せわしなく動くので一時的に行動タイプを"Still"などにして止めなきゃならないんですが(キャラは行動タイプを与えると勝手に動くので外部から制御するには行動タイプを変更するしかない)、そのあとはまた本来のキャラの動きに戻す必要があるので、行動タイプを変更するときは前の行動タイプを、関連する変数と共にスタックにつんでおかなければいけません。
つまり、動作とデータをひとまとめにして扱う必要があるのです。
これって…オブジェクト指向にする理由に一致するよね?
というわけで行動決定アルゴリズムはクラスにすること決定。
数が多いので少し面倒くさそうですが。
ダウンロードページのギャラリーに開発中の画像を公開し始めました。
今日はキャラが動かせるようになりました。
方向を与えてやれば、その方向が移動であるか、その方向に誰かいないかを判定して、移動可能であればその方向に移動します。
そして、動こうとした方向に誰かいた場合、そのキャラに動くよう促して、動いてくれた場合はもうその場所にキャラはいないので自分も移動します。
それから、行動アルゴリズムのうち、User、つまりユーザーの操作に反応して動くタイプを作るため、キー入力クラスも作りました。
現在は画像表示を作っているので今のところ仮のものですが。
今日の画像は、白いのを操作して、他の二人を押していっているところです。
で、マップ表示ができるようになって調子に乗ってキャラも表示できるようにしちゃいました。
キャラ部分がまた作りこみが甘いうちからテスト実行なんかしちゃってエラー続出。
自分で考えた仕様を自分で把握しきれていないというのが最悪でした。
思い出したおかげでなんとか形になったものの、次のステップに進む前に一度キャラ部分の再点検が必要そうです。
さて、ようやくマップ表示できそうなところまでこぎつけました。
今日作ったのは、マップチップ管理の読み込み部分。
とりあえず読み込んでいないものは随時読み込んで、終了時にまとめてメモリ解放しています。
この先マップチップ管理には必要なくなった画像を随時解放していく部分を作るのですが最後に一気に解放する処理があるので今のところ優先順位を落としています。
そしてマップの地形データの読み込み。
マップチップ番号とチップを置く高さが入っています。
しかしまだこれでもマップは表示できる段階ではありません。
早くマップぐらい表示したいんですが。
今日はマップ表示でもやったろかと思ってたんですがマップデータを用意する前に考えなくちゃいけないことがいろいろあったため作れませんでした。
まずマップチップが用意されてない。
まだテスト段階なので素材はテスト用マップチップでいいのですがそれを使えるようにするためのデータの形式が決まっていなかったのです。
で、それを考えていると今度は内部的に3Dで処理している座標の扱いがまだ決まっていないためにマップの高さ情報が決められないということに気付いたので今度は座標系をきっちり決めることになったんですよ。
で、まあ、決めた結果はいつものようにダウンロードページの開発室においてあります。
ミディビ更新しました。
できること自体はそんなに変わっていません。
Bomber丸Worldのキャラの動きについて考えてます。
動きタイプをFollowにすると基本的に特定の人物についていくんですが、実は人によって歩調が違ってましてね、つまり、相手の動きが速いと取り残されることがあるということです。
それから更に踏み込んで考えたのが、バルーンモンキー。
バルーンモンキーって知ってますか?マザー2の。
ジェフの後についてくるキャラクターなんですが、ほっとくとしばらくその辺をうろうろしていて、ある程度距離を置くと思い出したように駆けつけてくるんです。
そのようにしてつかず離れず追いかけてくるのがバルーンモンキー。
これが結構面白そうなのでやってみたいのです。
アルゴリズムは案外簡単です。
ある距離以上に離れるまではRandomで歩かせておいて、離れたらFollowモードに内部的に切り替えるのです。
あと、前に言ったかどうか知りませんが、相手を押すというシステムも作っています。
押すリスクも加えて追いかけるプログラムを書くのは少し難しそうな気がしますがそう難しくもなさそうなのでまあできそうな気がします。(どっちだ
ミディビ作ってます。
エラー処理をちょっと作ってます。
プログラミングコーナーのほうも作っていますよ。