SVX日記
2024-06-11(Tue) 太郎くんはサーキットを時速100kmで走ることにしました
一段落してしまった気分でしばらく放置してあった自作のレースゲームだが、近所のサーキットを走ってみたくなったので開発を再開することにした。
まずは画面切り替えを故意に遅延していたのを是正する。厄介なのは地図タイルをネットワーク越しに得る都合上、故意でなくても少なくない遅延があることだ。処理を集中することなく、段階的に処理が進むよう、こんなコードを書いてみた。
draw: ->
n = 0; while(n < @tile_reqs.length)
tile_req = @tile_reqs[n]
unless(tile_req[3])
tile_req[3] = new Image # Image インスタンスを生成
else unless(tile_req[4])
tile_req[3].src = tile_req[2] # Image.src を設定
tile_req[4] = true
else if(tile_req[3].complete) # 読み込み完了?
@constructor.pats[0] = tile_req[3]
@put_source_plane(@constructor.pats, 0, tile_req[0] << 8, tile_req[1] << 8) # ソースプレーン(回転前)に転送
tile_req[5] = true # キューから削除せよ
if(tile_req[5]) then @tile_reqs.splice(n, 1) else ++n
要するに1フレームで複数の処理をすることを避け、分散させるわけだ。まだ試作段階なので、分散のアルゴリズムにはチューニングの余地があるが、とりあえずそれほど大きくはツッカカることなく走り続けられるようになった。
そこで改めて表題の問題だ。現状スペースキーを押すと固定速度で前進走行するようになっていて、それは0.3という適当な値を与えている結果なのだが、いったい時速何kmで走っているのだろう。別に「ゲームなんだから考えません」という方向性もあろうが、以前に書いたように「実際に遊んだときに実際のF1のラップに近いタイムが出るようにしたいと思っている」のであれば、その辺をキッチリさせる必要があるのだ。
まずは、0.3で走っている現状の速度を求めてみよう。どうやるか。実際にコースを一定距離走らせ、経過時間を求めて算出すればいい。そうなると長い直線を持つコースが望ましいが……そうだ、昔、自分が働いていたつくばの土木研究所の試験走路を走らせてみよう。
query = new URLSearchParams(window.location.search)
switch query.get('course')
when 'silverstone'
lng_d1 = -1.022485; lat_d1 = 52.069097; v = 91 # シルバーストン
when 'marinabay'
lng_d1 = 103.864217; lat_d1 = 1.291532; v = 58 # マリーナベイ
when 'doken'
lng_d1 = 140.072549; lat_d1 = 36.115692; v = 184 # 土木研究所
else
lng_d1 = 136.540617; lat_d1 = 34.843099; v = 164 # 鈴鹿
なんか懐かしいなぁ、って思いながら車を走らせていると、視界が恐ろしく狭いことに気づいた。試験走路から一般道に出て、当時の寮に帰ってみようと思ったのだが、どこを走っているのかわからず、帰れない。仕方ないので、より小縮尺のグーグルマップをすぐ右に別に開いて、それを参照しながらドライブしてみた。つうか、これは「ラリーX」じゃないのかw? それにしても、これだけでもだいぶ楽しいな。気づくと土浦学園線、土浦ニューウェイを通って土浦駅まで走っていってしまっていた。何をやってんだオレわw。
試験走路に戻ろう。とりあえず、わかりやすい目印を決めてそこまで走ろう。スタート地点からそこまでの距離を、グーグルマップの「距離を測定」機能で求める。1.03km。で、ストップウォッチを片手に、車を走らせる。29秒。「1.03km / 29s x 3600s = 127.9km/h」。おぉ、おおよそ時速100kmだったんだな。
まずは0.3が127.9km/hになった理由を求める。0.3は256分率表現で76.8。60FPSなので4608/s。ズームレベル20なので4ビット右シフトして288ピクセル/s。24ピクセルが2mなので24m/s。時速にすると86.4km/h……あれ? いや、地図の側を緯度補正して24ピクセルを2mにしてるんだから、速度の方も補正しなければならないのか。「86.4km/h x 256 / 178 = 124.26km/h」。おぉ、だいたい同じになった。計算は合っていそうだ。
これを逆にして100km/hから求めればいい。「100km/h * 178 / 256 =69.53km/h」。秒速にすると19.31m/s。24ピクセルが2mなので232ピクセル/s。ズームレベル20なので4ビット左シフトして3708/s。60FPSなので61.8。256分率表現なので0.241。ということになる。んが、毎回こんな計算をするのは無駄なので、計算順序を入れ替えて定数にまとめてしまう。「0.3472 * 178 *1.0 / 256 = 0.241」緯度が変わったら178を変更し、200km/hにしたければ1.0を2.0に変更すればいいわけだ。