仮眠プログラマーのつぶやき

自分がプログラムやっていて、思いついたことをつぶやいていきます。

自作ゲームやツール、ソースなどを公開しております。
①ポンコツ自動車シュライシュラー
DOWNLOAD
②流体力学ソース付き
汚いほうDOWNLOAD
綺麗なほうDOWNLOAD
③ミニスタヲズ
DOWNLOAD
④地下鉄でGO
DOWNLOAD
⑤ババドン
DOWNLOAD
⑥圧縮拳(ツール)
DOWNLOAD
⑦複写拳
DOWNLOAD
⑧布シミュレーション
DOWNLOAD
⑨minecraft巨大電卓地形データ
DOWNLOAD
⑩フリュードランダー
デジゲー博頒布α版
DOWNLOAD
⑪パズドラルート解析GPGPU版
DOWNLOAD
⑫ゲーム「流体de月面着陸」
DOWNLOAD

2009年06月

技術解説「地下鉄でGO!」その4 擬似3Dとは

忘れっぽいのは素敵なことです~そうじゃありませんか~

空しいテストの数ばかり飽和の量より増えたなら忘れるよりほかないじゃありませんか~ (傾斜 中島みゆき)



何回目でしょーかテストの点を忘れた回数・・・



いえいえ、こっちの話です。


今回は擬似3D描写のお話。


一応、プログラムを知らない人も読んでくださってるかもしれないので2D描写のことから話し始めたいと思います。


まずスクリーンに画像を貼り付ける場合、必ずスクリーン上のポジションを数値で指定して、貼り付けます。


pos という命令ですが、例えばpos 100,200と指定した場合、このあと来る画像貼り付け命令で貼り付ける画像が、スクリーンの左から数えて100ピクセル、上から数えて200ピクセルの位置に表示されます。


一応2Dはこうやって表示位置の設定をしているのですが、3Dの場合ではpos 100,200,300とz座標が加わったり根本的にまったく違う方法で座標指定している・・・・・・・なんてことはないんです。


画面に奥行きはないし画面自体はxとy座標しか存在しません。


機械(パソコンの画面)にとってはx、y座標が知りたいわけで、z座標なんか言われてもチンプンカンプンなのです。

だからわざわざ私たちが遠近法の計算式で、3次元を2次元で見た場合x、y座標がどうなるか計算してz座標を消してあげないといけないわけですね。


つまり結局は3Dも、2Dと(概念としては)同じプロセスで画像を貼り付けているのです。



プログラム経験者の方はアレと思ったかもしれません。

確かに、3Dプログラミングの場合普通x座標y座標z座標の3つの座標を指定しないと表示できませんし、というか指定してくださいってマニュアルに書いてあるし。


でもそれはプラグインのほうであなたが指定したxyz座標をxy座標に勝手に変換して、最終的に画面に表示しているのです。


プラグインを作った人が、スクリプターに開発しやすいようにと、わざわざちゃんとxyzの3つを指定できるような命令を作っておいてくれていた、という訳ですね。


(例外として光源を計算する方法もありますがこれは処理時間が膨大に膨れ上がるためCGやムービーにしか使われないそうです。)

で、ここからが本題。


今(次)から解説する擬似3Dとは、そこまで高度な3Dを求めていないプログラマーが、そのためにプラグインを使うのが面倒だといって、自分で遠近法の式を作って3Dを再現しちゃうことをいいます。


シューティングの背景とか、ゲーム自体は2Dだけど雲と地面みたいに背景が2重スクロールになってあたかも奥行きがあるように見せるような場合に頻繁に使われます。


でそのためには第一に、遠近法の式を自分で考えて作らないといけませんが、まそれは次回。


次回:技術解説「地下鉄でGO!」その5 擬似3Dをプログラムする





ところで、とあるブログで名言集みたいなことやり始めたみたいです。毎回誰かの名言を最後に載せるのですが、なんか面白いなーと、言うか急にうらやましくなったんでこっちも真似してやってみようかと思います!

さて、最初の名言はー・・


「そのうち、一家に一台の時代が来るかもしれん!」by N・I

技術解説「地下鉄でGO!」その3 式に補正する

今までのをまとめると


s=1500000
repeat -1

await 30

v+=a

s-=v

stick key

if key=8:a+

if key=2:a-

title "残り"+s+"mm 速度"+v+" 加速度"+a+"" ;変数の数値確認用

loop



こうなります。


しかし、このままでは↓キーを5回くらい押したところでものすごい速度になってあっという間に1500m到達してしまいます。


これはフレーム数にもよりますが、ただ単純にs-=vの回数が多いのが原因です。


解決するには、vの値を小さくするか、sの値を大きくするしかないです。


前者の場合ではs-=v/10とこうします。10でなくてもその場に応じて適当な値にしてください。


あまり大きな値で割ると精度が悪くなるので注意

また後者の場合は最初の代入命令のときs=1500000*10と適当な値で掛けて

s-=v

この式はこのままにすれば、いいです。


しかし注意が必要なのは単位がmmではなくなったので、表示するときにはmes s/10 などして

補正してください。

技術解説「地下鉄でGO!」その2 駅まであと何m、の部分

駅までの距離をsとします。


だいたいmm刻みで計算すれば精度的にはokなはずなので、次の駅まで1500mだとすると


s=1500000


と代入してください。

一応もっと精度を上げたい場合はその10倍と、いくらでもできます。

(精度については次回詳しく説明します)


そしてルーチン内にsからvを引く式を書けば、距離が縮まっていくプログラムが完成します。


あとは条件式 if を使って、マスコン(ブレーキ)の最大値を制限したり、速度がマイナスにならないようすれば

基本システムは完成したも同然!


次は、実際にプログラムを書いて順々に解説していきたいと思います。

技術解説「地下鉄でGO!」その1 変数をどう使う?

同じプログラマーで「電車でGO!」が好きな人なら、一度は自分で電GOもどき作りたいなと思うものです。


「地下鉄でGO!」は明らかに「電車でGO!」を意識しているのは明らかなので、地下GOを解説することによって電GO作りたい人にも参考になるってカンジでやってこうと思います



まずゲームを作るにあたり、最低必要な変数を考えます。


それには、このゲームはこれが無いと始まらないってところを考えます。


電車でGOの場合だと、タイトル画面でもなく車種の数などでもなく、加速減速の操作が一番重要なとこですよね?


なので最初は加速減速をキーで操作できるルーチンを作るのです。


では速度をvという変数にしたとき、↓キーを一回押すと加速するようなプログラムはどう作りましょう?


加速するには加速度という概念がないといけないのでaという新たな変数を作ります。


↓キーを押すとaが加算され、vには毎ルーチンごとにaを足す式を作れば可能です。


一応


repeat -1

await 30

v+=a

stick key

if key=8:a+

loop


こんなふうになるはずです。


マスコンは入れれば入れるほど強く加速していくので、aはそのままマスコンの位置変数として使えます。


またaがマイナスの値になればvはへって行くのでブレーキ時の減速するプログラムも同時に完成です。



さて、次回は距離の概念を付け加えます。

ありゃりゃ

ああ、気づいたらブログ更新しなきゃ・・・って思って早2日・・・


結局3日以上ブランクがあいてしまいました・・・スマソ


でも地下鉄でGO!の技術解説も面倒なのでここで一句


repeat -1:await 7:if c!gettime(6){a=gettime(4):b=gettime(5):c=gettime(6):redraw 0:color 255,255,255:boxf:repeat 20:color 80-cnt*4,80-cnt*4,80-cnt*4:font "MS ゴシック",cnt*4+90,1:pos 230-cnt*8,100-cnt*2:mes ""+a+":"+b+":"+c+"":loop:redraw 1}loop


見事な1行です!


今日はこれでおしまい

プロフィール

toropippi

記事検索
アクセスカウンター

    QRコード
    QRコード
    • ライブドアブログ