Archive : 2008 年 9 月

9 月 27 2008

PV3Dでレースゲーム制作 17 - 画質切り替え機能

Posted by tanjo at 11:23 PM

モデル切り替え描画で遠くまで表示できるようになったのはいいけど、それでもやっぱり処理は重くなってきていますね。一気にパフォーマンスを上げるには、画質を犠牲にするしかないっ!
そんなわけで、今までどおりの通常描画モードに加え、パフォーマンス重視のモードを追加してみました。

パフォーマンスモードでは、

  • Flash Playerのレンダリング品質は「低」
  • 3D描画部分の解像度を 1/2 にする
  • 3Dのクリッピング距離を少しだけ狭くする

という感じに調整。

ポリゴン数をなるべく削らずにパフォーマンスを上げるには、Viewport3D の解像度を落としてやるのが効果的です。まあ画質「低」とあいまって、ガッビガビになりましたけど。

quality

気をつけなければいけなかったのは、低解像度の Viewport3D を通常サイズまで拡大するために1回ビットマップに落とし込んでやる必要があるってこと。BitmapData.draw を使って3D描画をキャプチャし、キャプチャしたビットマップを拡大させて等寸・低解像度の状態を作っています。

デモ

レースゲームデモ画面

» ゲームをプレイする (要:Flash Player 9.0.115.0以降)

このゲームのソースファイル Main.as はこちらから参照できます。

描画モードを切り替えるには、プレイ中に [Q] キーを押してください。
劇的、とまではいかないとしても、私の環境だと通常の60%くらいに負荷が下がりました。

9 月 23 2008

PV3Dでレースゲーム制作 16 - 距離に応じたレンダリング切り替え

Posted by tanjo at 3:45 PM

カメラからの距離に応じて、近くは精密なモデルを、遠くの方はザックリとしたものを表示分けできるようにします。もちろん Papervision3D にそんな都合の良いピンポイント機能はありません! FrustumCamera3D のニア・クリップを活かしてなんとか再現します。

(訂正)
サーセン。大嘘でした。
PV3D 2.0 Beta 1あたりで追加された SimpleLevelOfDetail を使えばカメラからの距離に応じて3Dオブジェクトを切り替えたりできます。
しかし!残念なことにオブジェクト単位の判定しかできない模様。私のように環境全体を1つの3Dモデルで作っちゃってる場合には使えませんね。環境全部が一気に入れ替わってしまいますから。

SimpleLevelOfDetail については、ぽりGさんのブログにデモ付きの解説があります。
» flashゲーム作成記 | PV3D:Beta版の機能をいろいろ調べてみた

建物を増やすには

今のコースだとそれほど意味はないけど、市街地みたいなコースを作るにはかなり重要になってきそうです。(超広大3Dを実現しているゲーム「Grand Theft Auto」からヒントを得ました。なんて言ったら大げさかな。)

どういうことかちょっと詳しく書きますと…
現行( » 前回デモ)では以前のエントリで書いたように FrustumCamera3D (PV3D最新版では Camera3D に統合)を使ってファー・クリッピングすることで、巨大な3D空間を限られた処理内で実現しています。
でもこれだけだと、遠くからも見えて欲しい建物もパイロンのような小さなオブジェクトも、同じ距離で判定されてしまいます。市街地を作るにはある程度遠くの建物も表示する必要がありますが、そうすると細かいオブジェクトのポリゴン数がやたらと増えて、処理のネックになっちゃうわけです。

3次元クリップ&2次元合成

そこで、3Dオブジェクトのレンダリングを、「すべての要素を描画する近距離」、「アバウトでいいから大きな建物だけ遠くまで表示する遠距離」の2つに分けることにしました。
具体的には、Camera3D や Scene3D を複数使い分けることで実現します。たとえば…

距離 Scene3Dにあるオブジェクト Camera3Dのクリップ Viewport3D描画順
すべての要素を含む精細モデル near=10, far=22000 最後に addChild
大きなものだけを含む簡易モデル near=13000, far=40000 先に addChild

viewport同士の合成は2次元の処理になります。つまり、「中距離~遠距離をレンダリングしたレイヤー」の上に、「カメラすぐ~中距離までのレイヤー」を重ねたような状態です。2D合成でも距離の順序は保たれているから無問題!なお床面はこれらとは別に、1番最初に描画しています。

近カメラの far と遠カメラの near が同じ値じゃないのは、近・遠距離の間に描画抜けが出ないように調整したため。こんなに重複させないといけないとは。。。

文字の説明だとわかりにくかったですね。
こういう描画になっています。この3つを合成。

synthe

本来なら、(同じカメラを使って)3Dオブジェクトごとにどのくらいの距離まで表示させるか設定できれば良かったんですけどね、最近のFPSみたいな感じに。残念ながらPV3Dでそういう描画は無理そうだったので2D合成でカバーしました。
近距離/遠距離用で2種類のモデルを読み込まなきゃいけなくなるのは難点だけど、まず当面はパフォーマンスの確保が優先、と。

デモ

レースゲーム・デモ画面

» ゲームをプレイする (要:Flash Player 9.0.115.0以降)

このゲームのソースファイル Main.as はこちらから参照できます。

相当注意深く見ないと何が変わったのか全然分かりませんね…。第1コーナーを曲がったあととか最終コーナーの緑色の建物とかはまだ分かりやすいでしょうか。遠くの色が薄い状態の建物が、今回追加した遠距離レンダリングです。

9 月 17 2008

私の戦闘力は52です。

Posted by tanjo at 4:13 PM

おしい!!53だったら、ちょっと面白かったのに…!
何のことかといいますと、ウェブサイトの戦闘力を計ってくれるサービス「Web スカウター」でこのブログを測定してみた結果です。

» Web スカウター - ウェブページの戦闘力を測定できる「あの」ツール - Web Scouter

Web スカウター

ソーシャルブックマーク、Google PageRank、被リンク、RSS購読者数、…といった情報から、そのサイトのオンライン上の影響力ともいうべき「戦闘力」を割り出してくれるサービスです。ブログ向きですかね。

戦闘力はこまめに変動するみたいです。しかも、うちのサイトはまだ /blog しかコンテンツがないにもかかわらず、http://phenotype.jpn.org/ とルートで計測したら92にアップしました。お、形態変化並み。
SEOとしてどれくらいアテになるかは分かりませんが、このアイデアにはそそられますねぇ。

戦闘力を調べるには、戦闘力測定ページの入力ボックスにURIを入れるだけ。戦闘力は結果ページの右の方に表示されます。
またランキングページがあって、人気のサイトを一覧することもできます。これは便利かも。1位は初期ベジータクラスの Engadget Japanese でした。

p.s.
2日後に計測したら、なんと560にアップしてました。
どうやらこの程度のマイナーサイトでは、些細なことで変動しやすいようです。

9 月 16 2008

Linuxでポートマルチプライヤに成功

Posted by tanjo at 2:39 AM

カーネル2.6.24ではポートマルチプライヤに正式対応したとのことで、早速試してみました。

ポートマルチプライヤ(Port Multiplier)とは、分岐接続させた複数台のHDDを、1つのSATAポートから個別に認識する技術。SATA(eSATA)のハブみたいなものです。

使用した環境は以下のとおり。

外付けHDDケース CENTURY 裸族の二世帯住宅
HDD HGST HDP725050GLA360 (×2)
eSATAインタフェース RATOC REX-PE30S
OS Ubuntu 8.04.1 LTS

UbuntuをLive CDとして起動して、裸族の二世帯住宅につなげてみると、…なんとそのままの状態でHDD2台を認識!問題なくアクセスできます。
以前はカーネルにパッチをあてたりいろいろと工夫が必要だったようですが、最新Ubuntuではこうもすんなりいくとは。そろそろUbuntuに乗り換えようかな。

以上、人柱的報告でした。

9 月 14 2008

突然ですが、ナゾナゾです。

Posted by tanjo at 6:42 PM

問題

Googleで「いいえ」と検索すると、意外にも、とある有名なサイトが1位にヒットします。さて、どこでしょう?
*やずや?いいえ、違います。

+++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++
++++++++ネタバレ対策です。すいません。+++++++++
+++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++

答え

解答解説はこの下をドラッグ!(白い文字で書かれています。)

正解は、Yahoo! JAPAN でした。(記事投稿現在)
Googleのいやがらせというわけではなく、アンカーテキストの効果ですね。
ものすごくたくさんのサイトから「いいえ」というキーワードで Yahoo! JAPAN にリンクされているあかしです。Googleに限らず、Yahoo検索でもLive SearchでもたいていYahoo! JAPANかYahoo!モバイルが上位にきますよ。
私が調べた時点だと、「退場」とか「18歳未満」で検索してもYahoo! JAPANが見事1位。あらためてYahoo!の人気に脱帽~。

おまけ

「人生、宇宙、すべての答え」と検索すると、…「42」と表示されます。
Google電卓機能のおまけ。

これは、SF小説『銀河ヒッチハイク・ガイド』に登場するスーパーコンピュータ「ディープ・ソート」が750万年かけて導いた究極の答えが「42」だったという話に由来します。
作中にはディープ・ソートがGoogleplex Star Thinkerなるコンピュータのことを「電卓レベルだ」とバカにする場面があるそうなんですが、そのGoogle電卓は750万年どころか一瞬で答えを割り出しましたよ…というGoogleさんのパロディメッセージみたいです。
「いいえ」も実はメッセージだったりしてね。

» 人生、宇宙、すべての答え - Wikipedia

9 月 10 2008

PV3Dでレースゲーム制作 15 - タイムアタック機能

Posted by tanjo at 10:05 PM

ようやくタイムアタック機能の実装です!ゲームだけしたいかたは下の方にスクロースしてね。

前回までで周回を正しく判定することができるようになりました。なので、あとは「周回が始まってから~次の周回になるまでの累計フレーム数」をカウントしていけばいいだけです。新しい周に入ったら、またゼロからカウントし直す、と。
内部処理ではラップタイムはフレーム数で扱っています。処理しやいからです。分・秒・小数に変換するのは表示の時だけでいいでしょう。
1つ前の周のカウント数とか、累計カウントの最小値とかを変数に保存しておけば、それぞれラスト・ラップタイム、ファステスト・ラップタイムが作れます。おお、レースゲームっぽい!

この辺の処理はあまりにフツーですので割愛させてもらうとして、今回は取得したフレーム数を「XX分YY秒ZZ」と2桁区切りの時間に直す方法を紹介したいと思います。

まずは、フレームを分、秒、小数に変換します。

function frameToTime(frames:int):Array
{
	var time:Array = new Array();
	var fr:Number = stage.frameRate;
	time[0] = Math.floor(frames / (60 * fr));          //分
	time[1] = Math.floor((frames % (60 * fr)) / fr);   //秒
	time[2] = Math.floor((frames % fr) * 100 / fr);    //小数
	time[0] = zeroPadding(time[0], 2);
	time[1] = zeroPadding(time[1], 2);
	time[2] = zeroPadding(time[2], 2);
	return time;
}

フレーム数の int 値を引数に、分、秒、小数の整数値を配列に格納しています。
でもこれだけだと数値が2桁だったり1桁だったりバラバラです。そこで、必ず2桁になるように、数値を文字列値に変換してから配列を返しています。

数値を任意の桁数に直す関数。

function zeroPadding(number:Number, size:uint):String
{
	var str:String = number.toString(10);
	while (str.length < size)
	{
		str = "0" + str;
	}
	return str;
}

「ゼロパディング」と言うそうです。第1引数の桁数が第2引数の設定に満たないときは、頭に「0」を付け足して揃えてくれます。これくらい ActionScript の標準クラスにあるんじゃ…と思ってたけど、どうやら無いみたいでした。
ActionScriptでゼロパディング - 続・ken39arg を参考に、じゃなくて、そのまんま使っています。

実際にこれらを使用するには、たとえば累計フレームのカウント数が lapTime = 2345 だったとすると、

var lapTimeArr:Array = frameToTime(lapTime);
trace("TIME : " + lapTimeArr[0] + "'" + lapTimeArr[1] + "." + lapTimeArr[2]);

これを実行すると

TIME : 01'18.16

と返ってきます。

久々のデモ!

が、しかし、たいして進展したように見えません。。。

ゲームをプレイする

ゲームをプレイする (要:Flash Player 9.0.115.0以降)

*このゲームのソースファイル Main.as はこちらから参照できます。

今回からFlexコンパイルに移行しました。ソースも以前よりはスマートにしたつもりです。主な追加機能は、データファイルのプリローディングとタイムアタック。動作が重いときは「右クリック」 > 「画質」 > 「低」を選んでください。

ちなみに私の最速タイムは 00′50.96 でした。

9 月 10 2008

Google Translateでサイトを多言語対応に

Posted by tanjo at 7:55 AM

Google Translate にて、ウェブサイトを他言語翻訳するガジェットが提供されています。
このブログの右カラムにあるやつです。海外からのアクセスも微妙にあったり、コメントをいただいたりしたということで、ためしに設置してみました。(実用性は低そうなンだけど、、)

ガジェットは以下のページから取得できます。
設置はJavaScriptを自分のサイトの表示させたい部分にコピペするだけでOK。
http://translate.google.com/translate_tools

こんな風に挿入されます。

ページを翻訳するだけでなく、リンク先も翻訳リンクになってくれるので、サイト全体が多言語化してくれます。
気になる翻訳精度は、…まあ、こんなもんでしょうかね、という感じ。特にくだけた言葉になるとグングン怪しくなっていきますね。ブログにはあんまり向かないかもしれません。
しかも当サイトに限って言えば、翻訳するとなぜかスクリプトのソース部分が改行されず1行で表示されてしまう…。これはいったい…。
でもさすがはGoogle、翻訳速度はかなりのものです。

ちなみに Microsoft からも同様のツールが提供されています。入手は以下です。
http://www.windowslivetranslator.com/AddIn.aspx

貼り付けサンプル。高機能っぽいけど翻訳にちょっと時間がかかります。

もう1つおまけ。ガジェットではなく、和英翻訳ページへのリンクだけを作るには、このようなリンクを href 指定すればできるようです。

http://translate.google.com/translate?u=【ページのURI】&langpair=ja|en&hl=ja

9 月 07 2008

PV3Dでレースゲーム制作 14 - 色情報を操る

Posted by tanjo at 11:22 PM

前回の続きです。
周回カウントの判定自体は前回のエントリの内容をそのままコードにすれば良かったので問題なくできました。

実は難しかったのは、コースデータ画像にグラベルとか壁という「地形情報」と、周回判定用の「チェックポイントエリア」、この2つを両方記録して、しかもプログラムは別々に処理できるようにしないといけない点。(前回はサラッと流してたけど。)
データ画像と変換した巨大配列を2つず作ってもできるけど、何とか工夫して1セットで、しかも効率よく実装できないものか…?色情報の扱い方がカギとなりました。

*データ画像→巨大配列で判定する話はこちらのエントリ

いろいろ考えた末、色情報を R/G/B 別々に扱えばできそう、という結論に。
どういうことかというと、地形情報は Blue の値で表し、チェックポイントは Green の値で表すというわけです。(Red は未使用。そのうち別のデータに使うかも。)
データ画像はこんな風になりました。

dt_course01

色情報 地形情報 チェックポイント
0x****ff ターマック -
0x****99 グリーン -
0x****66 サンド -
0x****00 コース外 -
0x**ff** - 判定用エリア1
0x**cc** - 判定用エリア2
0x**99** - 判定用エリア3
0x**66** - 判定用エリア4
0x**00** - エリア外

色はこの2つの組み合わせで決まります。たとえば、「判定用エリア1の砂地部分」は「0×00ff66」で塗られます。
Photoshop のレイヤー合成で「スクリーン」を使えば、「000000」+「000066」+「00ff00」→「00ff66」となり、別々のレイヤーに青・緑それぞれ作っておいても重なれば自動的に期待どおりの色になってくれます。
これなら画像作るのが楽チン!

synthe

RGB16進数の色分解

今度はプログラムのお話。
RGBのデータから、必要な部分の単色の値だけを抜き出す方法です。

複数の情報(地形/チェックポイント)を格納しないといけないので、エリア判定用の巨大配列には、getPixel で取得した16進数の uint 値をそのまま代入していきました。データを取り出すときに、地形情報が欲しいときは Blue の値を取得、チェックポイント判定の時は Green を取得するようにすればOK。

//コースデータの作成
groundData = new Array();
var groundBitmapData:BitmapData = groundBitmap.bitmapData;
for (var i:int = 0; i < 560; i++)
{
	groundData[i] = new Array();
	for (var j:int = 0; j < 420; j++)
	{
		groundData[i][j] = groundBitmapData.getPixel(i, j);
	}
}

たとえば、(100, 200)マス目の情報を参照するには、以下のようになります。

var color:uint = groundData[100][200];
var colB:uint = color & 0xff;		//Blueの値(地形情報)を取得
var colG:uint = (color >> 8) & 0xff;	//Greenの値(チェックエリア情報)を取得

参考サイト:flair4 blog - AS3.0 16進数の色分解ではまった事

「&」はAND演算子、「>>」はビットシフトです。何をしているかは、参考サイトの記事下の方にとても分かりやすい解説があるので、気になるかたは参照してください。
今までビット演算ってどんなとき使うんだろ、、とか思っていたけど、こういう使い方もあるんですね。

あとはGreen取得値を元に前回の周回カウントアルゴリズムを実行するだけ。ちょっと遠回りしましたが、ようやく周回のカウントが実現できました。

次回、タイムアタック付きのデモ公開、…できるといいな。

9 月 06 2008

PV3Dでレースゲーム制作 13 - 周回カウント作成

Posted by tanjo at 2:58 AM

ちょっとでも遊べる要素をまず作ろう、ということで、タイムアタック機能を実装してみたいと思います。

タイムを計測するには正しく周回をカウントしないといけなく、カウントするにはそのためのロジックが必要、と。結構長くなりそうなので、3回くらいに分けて書きます。(またしてもデモはしばらくお預けの予感…!)

周回の判定

まず最初は周回をカウントする方法について。

プレイヤーが逆走したり、途中で折り返してきても正しく判定できるようにするには、やっぱりチェックポイントを順走 or 逆走のどちらで通過したのかを、調べてやるのが手っ取り早そうです。
今作っているコースのように輪っか状に閉じたコースなら、チェックポイントはスタート(ゴール)地点に一カ所、コースを横切るように設置しておけばコトは足ります。そこを順走で通過したら1周カウント、というわけです。

でもこれだとチェックポイント上を往復しているだけでどんどんカウントされてしまいます。そこで、たとえば初期状態が「0」のカウンタを用意して、
 ◆ 「0」のまま順走通過したら1周したことにする。
 ◆ 逆走通過したらカウンタを「-1」減らす。
 ◆ 「0」以外の状態で順走通過したら「+1」増やす。
…という処理をしてあげれば、ちゃんと1周してこないとカウントされないし、ひねくれたプレイヤーが何周も逆走した場合には、その分何周も順走しないと次の周回に進めないようになります。

結局私はコースの中間地点にもチェックポイントを作って、2カ所で判定することにしましたが、基本的な考え方は同じです。チェックポイントを増やしたのは、セクションとかあった方がサーキットっぽくね?と思ったからです(笑)。

順走/逆走通過の判定

やりかたはいろいろありそうですが、私の場合は路面判定のときと同様、コースデータを記録した画像を使ってやっていこうと思います。
画像をもとに巨大な配列を作って、車の座標から今どういうエリアにいるのか割り出す方法です。(→割り出し方の具体例はこちらのエントリ

2枚の接するエリアを作れば、その境界を順走/逆走通過したかを調べることができます。
具体的には、たとえば2つのエリアをそれぞれA、Bとしたとすると、
 ◆ A上にいるときは、変数に「1」を代入する。
 ◆ B上にいるときは、変数に「2」を代入する。
 ◆ それ以外の場所では、変数に「0」を代入する。
とした上で、
 ◆ A上にいるとき、もし代入前に変数が「2」だったら、逆走している。
 ◆ B上にいるとき、もし代入前に変数が「1」だったら、順走している。
というふうに判定できるわけです。

pass

つづく。

9 月 05 2008

裸族の二世帯住宅・入居失敗談&トラブルシューティング

Posted by tanjo at 6:50 PM

nude
YanivG © 2008 cc_attributioncc_noncommcc_sharealike

裸族の二世帯住宅」を買ってきました。画像はイメージです。

裸族の二世帯住宅とは、…CENTURYの eSATA対応 & RAID機能付き のハードディスクケース。
名前のとおりHDDを2つ収納するタイプです。ケース収納型なもんで、露出ゼロ。見た目は裸族シリーズっぽくないですね。接続は3.0Gb/sのeSATAと、USBの両対応。RAID 1 / RAID 0 / 2台認識 / 連結1台認識 の4つのモードが選択できます。ツクモで11,800円でした。

さっそくHDDを詰め込んで、スイッチオン!

しかし、上側ドライブのランプだけエラーを表す赤青点滅が…。何度か電源を入れ直すと両方起動したけど、パソコンに接続すると、上側はピンク表示、下側はピンク⇔赤の点滅、という状態に。
何かがおかしい。。マニュアルと全然違う。。
いろいろいじったり調べたりしたところ、この報告と似たような不良でした。つまり、

  • 出荷状態がマニュアルの記載とは異なり、スタンダードモードではなく、ミラーリング(RAID 0)(RAID 1)モードだった。
  • HDDを2つ収納した状態だと、上側ドライブの起動に失敗しやすい、というかほとんど成功しなかった。

なんてこった。不良が2つ重なってたことで、問題の解明に手間取りましたよ。

不良交換したら、快適に

さて、明らかに初期不良ということで、翌日交換してもらいました。
今度は問題なく両方のドライブが起動でき、モード設定もバッチリできます。使ってるHDDが「動いているか心配になるほど」と評判の HGST HDP725050GLA360 なこともあり、とても静か。しかも当たりロットだったのか、HDDがほとんど発熱しないためファンの音もそれほど気になりません。(裸族の二世帯住宅は温度によるファンコントロール機能付きです。)

いろいろと苦労はしましたが、結果的に快適な状態になってくれたので、まあ良しかな。
あとは突然壊れたりしないことを祈るばかり…!

トラブルシューティング

最後に、裸族の二世帯住宅を買おうとしているかたへ、私がトラブルから学んだ注意点を。

  • 安かろう悪かろうというほどではないにしても、この手の商品の中では不良報告が多いような気がします。私のように片方のドライブだけ起動しない/しなくなったという報告はいくつかあります。
  • モード切り替えボタンは数秒間長押ししないと反応しません(マニュアル未掲載)。切り替わると一瞬アクセスランプが消灯します。
  • モード表示ランプはスイッチの位置を表しているだけで、実際にそのモードで動いているとは限りません。
  • マニュアルのとおり初期状態がスタンダードモードだとは限りません。使い始める前にモードボタンを押して設定し直した方が良さそうです。
  • 初期状態では、ドライブの起動失敗 or ドライブ未接続だと、アクセスランプは消灯するはずです。もしHDDが故障していないのに赤ランプが点いていたりしたら、初期不良かモード設定ミスかと思われます。
  • HDDを収納するとフタが完全には閉まらない状態になるかもしれませんが、ロックがかかれば問題ないようです。

…こういうことは価格.comにでも書いた方がいいのかな。。ま、いっか。