したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |
レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。

おちゃめくらぶ掲示板

800御茶目菜子:2011/12/04(日) 14:57:33
プチコンで3Dレースゲームを作ろう
11月27日にはプチコンで「疑似3Dゲームを作る」というテーマにおいてスキーゲームを
作ったにょ。
スキーゲームは旗さえ表示できればそれっぽくなるということで非常に単純なものだった
(「プチコン スキー」ではスキーらしい動きを実現するために多少悩んだ)けど今度は
レースゲームを作ってみることにするにょ。
疑似3Dのレースゲームを作る上で最初のハードルになるのがカーブの表現にょ。
直線ならば消失点に向かっている2本の直線を描けばそれっぽくなるけどカーブをそれっぽく
描くのはなかなか難しいからね。
1行12文字という極めて小さな液晶でグラフィック使用不可というポケコンであるPB-100
においても疑似3Dレースゲームは多数発表されているのだけどカーブに見えるように
プレイヤーの方でイメージを働かせば問題がないもののPB-100よりも格段に表現力が高い
プチコンならば誰が見てもカーブに見えるようなものを描きたいにょ。
しかし、カーブというのは奥に行くにしたがって曲がっていれば自然な感じに見えるため
それっぽく見せるだけならば非常に簡単にょ。

例えば、テキストを使った簡単なものだとこのようになるにょ。

CLS
A$="■■■■■■■■■■■■■■■■■■■■" '■を20個
R=0
B=0
C=0
FOR I=0 TO 9
D$=MID$ (A$,0,20-I*2)
LOCATE 6+I+A,23-I
PRINT C$;
C=C+R/12
B=B+C
@LOOP
GOTO @LOOP

(※最後を無限ループにしているのは「OK」の表示で道路が消えるのを防ぐため)

簡単に説明すると奥に行くにしたがって狭くなる道を用意して、カーブの場合はずらす
量を積算することで奥に行くにしたがってずらす量を大きくしているというだけの非常に
シンプルなものにょ。
Rの値が0ならば直線だけど-4〜+4の間(0以外)で変化させるとカーブになり、数値によって
曲がり方が変わってくるにょ。
R/12の12という値はRが-4〜+4の範囲内で画面内に収まるようにするためにしたものであり
それ単体には何も意味はないにょ。(-4〜4にしたのは今回作ったレースゲームのコース
データがそのようになっているというだけであり、-9〜+9にしたいとかいうのであれば
12という値はそれに応じた数に変えればいいだけ)

テキストということもあり、カーブはガタガタで表示されているのでなめらかさが全く
ないという問題やさらなる急カーブを表現したい場合には画面外へのはみ出し処理を行う
必要があるため実際はグラフィックを使った方が(画面外への座標もちゃんと受け付けて
それに対応した描画をしてくれるために)簡単かつキレイなカーブを描くことが可能に
なるにょ。

VISIBLE 1,,,,,1
GPAGE 0
GCLS
R=4
A=0
B=0
FOR I=1 TO 70
W=150-I*2
GLINE 128+A-W/2,192-I,128+W/2+A,192-I,15
B=B+R/80
A=A+B
NEXT

基本的にテキストのサンプルと同じであるため内容を説明するまでもないものだけど
Wの値が道幅になっておりGLINEを使ってセンターラインの座標(128+A)を基準に描画して
いるにょ。
センターラインを基準にしておけば道幅の半分の量を左右に足していけば済むために計算も
楽になるにょ。
アーケードゲームにおいてもかつてはこういった疑似3Dのレースゲームはたくさんあった
けれど「ポールポジション」など多くのゲームはラスタースクロール機能を使って実現して
いるにょ。
このラスタースクロールを行えば簡単だけどそれをソフトウェアによって実装する必要が
ある場合にはラスタースクロールに拘る必要はなくこういった簡単なものであっても
カーブはそれっぽく表示できると思うにょ。
ただし、メインルーチン1回あたり上記のようにGLINEを70回実行しているのはさすがに
高速なプチコンとはいえかなり負担が大きいためループ回数を減らすために多少荒くは
なるけどGFILL(塗りつぶし四角形)を使った方が良いと思われるにょ。

ここまで書いてきてスキーゲームの時に書いたような疑似3D表示を行う場合の2つの注意点
「拡大率の変化」「表示座標」はレースゲームには当てはまらないのかというとそうでは
ないにょ。
それでは、別の観点からカーブを描いてみることにするにょ。
まず、道を上から見た場合に長方形の集合体と仮定するにょ。
イメージしにくければ同じサイズの本や紙を長い廊下や広い部屋に線路のように繋いで
敷き詰めていくといいかもしれないにょ。
その場合は真上から見たら1つ1つの形は長方形だけど床の付近に顔を寄せて低いアングル
から斜めで見ると台形の集合体で構成されていることが分かるにょ。
これは長方形にパースがかかることで1つの長方形(1つの本)だけを見てみると長方形の
奥の辺の方が手前の辺よりも短くなるからにょ。
そして、遠くなるにしたがってその長方形(見た目は台形)がどんどん小さくなるにょ。
その縮小率が前回書いたような指数関数的なものになっているにょ。

これを画面上で描くようにすればいいのだけど台形を描画するというのはかなり大きな
負担になってしまうために1つ1つの四角形は長方形で補うことにするにょ。(カーブを
描く場合には道路に角度を付くため歪んだ四角形を描画する必要があるため台形でも
正しく表現はできないため速度面で有利な長方形で統一しても問題ない)

VISIBLE 1,,,,,1
GPAGE 0
GCLS
R=4
A=0
B=6
W=150
Y=191
FOR I=0 TO 49
GFILL 128+A-W/2,Y,128+A+W/2,Y,15
A=A+R/1.5
B=B*0.94
W=W*0.94
NEXT

上記の道の大きさを奥に行くにしたがって「一定割合で縦横ともに縮小したもの」と前述の
ように「一定量ずつ幅のみを狭めたもの」は一見すると両方ともカーブらしさが表現
出来ているため大差ないように見えるけどそこには根本的な落とし穴があるにょ。
それを図示したのがこれにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/image/road.png

この図の(A)を見てのように一定割合で縮小したものはあえて言うまでもなくすべての
長方形が相似となっているにょ。
それに対して図の(B)のように幅のみを縮小していった場合には一見疑似3D視点では違和感が
ないように見えるけどそれを仮に上から見た場合には手前にくるにしたがって奥行きの
長さが短い長方形になってしまうにょ。
これが意味するものは何かというと前回書いたような単純な拡大をした場合には近づくに
つれて遅くなって見えるということにょ。
確かにこれだと1ラインごと(長方形1つごと)の移動を行った場合には実際の移動距離は
短くなっているからね。(単位時間ごとだと移動距離が短くなっている)
前回書いたように疑似3Dで近づいているように見える物体を画面上で一定速度で動作させた
場合には近づくにつれて遅くなっているように感じるのはこれが原因にょ。

この(B)の方法で疑似3Dを行うならば等速で近づいているように見せるためには前回書いた
ように近づくにつれて画面上の移動速度を早める必要があるにょ。(遠くにいるときには
1ライン分の移動だったら近づくにつれて2ライン分、3ライン分の移動量に変えてやれば
よいけどこれも自然な移動量に見せるためには指数関数的に増やす必要がある)
一定割合で縮小している場合は遠くにいても近くにいても1ライン分だけ移動させれば
ちゃんと等速で近づいているように見えるにょ。
しかもその障害物のサイズは道路の縮小率に合わせて計算すれば違和感のないサイズに
することができるためサイズの違和感も無くなるにょ。
つまり、一見面倒くさそうに感じる(A)の方法だけど違和感の無い表示を行うためには
かえって楽ができるということになるにょ。

さらに(A)の方法は1つ1つの四角形のサイズ(画面から見て奥行き側のサイズ)がちゃんと
計算されており、それだけで距離情報を持っているので視点移動をすることも可能になり、
その際も上記のように道路上を動作する障害物の速度やサイズの計算は簡単に出来るにょ。
http://www.youtube.com/watch?v=7Xb1zJOEqrc
あくまで疑似3Dであり奥行き方向への距離情報しかないため画面の左右に視点を変えたら
表示の誤差が出てしまう(上記のようにカーブを描く場合は本来ならば歪んだ四角形を
描画する必要がある)けど上下移動ならば全く問題ないにょ。
視点は固定で速度やサイズの違和感が無くすための補正処理をちゃんと行う(もしくは
そこまで気にしない)という人ならば(A)と(B)どちらの方法を用いても問題はないのだけど
今回のレースゲームは前回のスキーゲームと同じく疑似3Dがテーマであり違和感がより
少なくなる一定比率で縮小する(A)の方を選択するにょ。

そして、出来たのがこのゲーム「PETIT RUN」にょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/1page.htm#prun
http://www.youtube.com/watch?v=ATXR_cHntt0
1画面のタイムアタック専用レースゲームとなっているにょ。
1画面ということで敵車や障害物などは無いけど前回のスキーゲームのように距離に応じた
サイズや座標で表示させることができれば障害物を表示することは簡単に可能になると
思うにょ。(敵車を表示させる場合にはそのアルゴリズムを考える必要があるけど)
とはいえ、タイムアタックに特化してゲームデザインをしているためため障害物が無くても
十分に楽しめると思うにょ。
障害物はないけど白線の移動速度やサイズは違和感がないと思うにょ。
上記(B)の方法で補正なしにPETIT RUNを動作させた場合はどうなるのかを比較すればこの
「違和感」というのがどのようなものかは一目瞭然だと思うにょ。

 「PETIT RUN」を(A)の方法ではなく(B)で表示する場合の変更点
 11行目 E=7 を E=3 に変更
 14行目 FORの前に D=0 を追加
 14行目 V=V+R+R を D=D+R/5:V=V+D に変更
 18行目 E=E*P:F=F*P を F=F-4.5 に変更

さて、このPETIT RUNを作るに当たってやはり問題になったのは自分の車の表示にょ。
何せプチコンのプリセットのスプライトデータには車の代わりに使えそうなものはない
からね。(車をGLINEで表示するのはスキーゲームの旗のように簡単ではないため1画面に
収めることが難しくなる)
まぁ適当な無機物を使っても良かったけどそれならば人間を走らせた方がいいということで
そうなったにょ。
人間の3DレースゲームといえばPS用ゲームの「ランニングハイ」とか実際にあるわけだし
問題はないにょ(笑)
私はポケコンでもレースゲームをいくつか作ったけど10年前に作った疑似3Dのレースゲーム
「3D DRIVING」はOPASを駆使しても「シュプール」と同じく8fps程度だったのに対して
PETIT RUNは60fpsの速度が得られているにょ。
そのため動作は非常にスムーズにょ。(ポケコンの「3D DRIVING」にあった遠景スクロール
さえもなくグラフィック面はあまり力を入れてないからこそ可能になった)

このPETIT RUNは1画面に収めるために随所に省メモリテクニックを使用している(最初に
作った段階では辛うじて24行に収まっていたけどリストを見直す度に無駄な部分が
見つかってきたためその都度導入を断念していたものを投入することができた)とはいえ
特筆するようなものはないにょ。
しかし、白線の動作と車の挙動だけ書いておくことにするにょ。
特に車の挙動に関しては非常に重要な部分であり、これによってレースゲームの難易度
(プレイしやすさ)は大きく変わってくるわけだしね。
前回作った「プチコン スキー」のような疑似3Dゲームが難易度がやたら高くなっている
のは下記のような3つの理由があるにょ。

 (1)自分の絶対的な位置が分からない
 (2)慣性がある
 (3)旋回による視点移動がある

(1)プチコン スキーの場合は辺りが一面真っ白であり、自分の位置は旗との相対的な
位置しか分からないにょ。
しかし、PETIT RUNのようなレースゲームの場合は道路があるためその道路を基準に
自分の位置を把握可能になるにょ。

(2)プチコン スキーは旋回ボタンを押している間はどんどん進行方向が変わっているにょ。
しかし、背景のスクロールもないためその進行方向は旗を基準にしなければ分からないにょ。
さらにその旗は随時速度が変わっているし、進行方向を把握するためには慣れでカバーする
しかない状態だったにょ。(そのため後からガイドラインの線を付けることにした)
しかし、PETIT RUNはハンドルの左右という2択しかないため進行方向の把握は非常に
容易にょ。(プレイヤーは常に道に対してまっすぐ進んでいるため自分がハンドルを切った
方向が道に対する進行方向になる)

(3)プチコン スキーでは左右旋回をしているという感覚を味わってもらうために旋回を
するたびに視点を変えているにょ。(そうしないとただ自分が左右移動しているだけの
状態になってしまう)
これは視覚的に楽しめるという反面、(1)(2)の条件と合わせると難易度を高めている
理由となっているにょ。

視点移動については「PETIT RUN」においては別バージョンとなる「PETIT RUN D」において
対応しているにょ。(視点切り替え機能を付けるために画面はかなり簡素化してしまった
けど普通に作ったら5行分オーバーしてしまったのを何とか1画面に収めることができた)
http://ww5.tiki.ne.jp/~ochame/petitcom/1page.htm#prund
http://www.youtube.com/watch?v=MPHhq3qGEqU
基本的にドライバー視点だけどゲーム中にリアルタイムで後方視点に切り替えられるにょ。
これは1画面ゲームでは画期的だけどドライバー視点は情報量が少ないのとコースデータを
表示に反映させるスムージングのアルゴリズムがドライバー視点向きではない(とはいえ
短いリストでスムージングを行うにはこれしかなかった)ためにこの視点切り替え対応
バージョンとなる「PETIT RUN D」よりも標準の「PETIT RUN」の方が遊びやすいのでは
ないかと思われるにょ。

本来ならば実際の進行方向への視点補正も必要だけどこのゲームの場合は「基本的に道に
対してまっすぐ進んでいる」ということもあり、それは行ってないにょ。(ハンドルを
切った量を別パラメータで用意している場合にはこの補正を行わないと不自然になる)
情報が十分に多ければ視点切り替えを行うことは十分に意義があるけど1画面ということも
あり最小限の情報しかない(PETIT RUNでもコースの曲がり具合しか分からないのに
ドライバー視点ではそれが分かりにくくなっている)という状況下では視点切り替えがなく
なおかつ後方視点というのが最もプレイしやすいと思われるにょ。
後方視点とドライバー視点の変更アルゴリズムを書いておくとドライバー視点は道路を
近くで見ているということで200ピクセルだった道路の横幅を712ピクセルにして、縮小率を
下げることで遠近感を強調し、それに伴う水平線の位置の変化を値を調整することで
変わらないようにしているという単純なものにょ。(このサイズ変更はリアルタイムで計算
しているため障害物を表示する場合でもどちらの視点であっても内部的には移動量を
変えたり当たり判定を変えたりする必要はない)

こうしてみると視点固定型の疑似3Dレースゲームはよほどおかしな挙動でない限りは
「プチコン スキー」のように難易度が跳ね上がるということはないと思われるにょ。
その挙動において基本となるのがアクセルとブレーキに関してにょ。
これはレースゲームを作った経験が無い人だと悩む場面だけど私の場合は過去に自分が
作ったポケコンゲームを元にしたシンプルなものを搭載しているにょ。
それが、12行目の S=(S+(16AND K)/57)*0.99 という式にょ。
アクセルボタンを押したらアクセル、離したらブレーキという場合にはその2通りの
条件分岐があるし、アクセルを押した場合には上限速度を超えないようにしないといけない
わけだしブレーキを使用した場合には速度がゼロ未満にならないようにしないといけない
ために S=S+((K AND 16)==16)*(S<=29.5)/2-((K AND 16)==0)*(S>=0.5)/2 のような感じに
なるにょ。(最高速度30でアクセルを押したら0.5速くなり、ブレーキをかけたら0.5遅く
なる場合)
これと比べたら短いし、速いというメリットがあるし、最初の加速が良く最高速に達する
には時間がかかる(アクセルボタンを押している時間と速度は完全に比例しない)という
点も個人的には好みにょ。

あと、操作キャラが人間であることを考慮して左右のハンドルを切っていないまっすぐに
進んだ状態では最高速と加速がアップするという要素も加えたにょ。
これによって戦略的要素が増えたにょ。
デフォのコースではこれを生かしたターボスタートによって通常走行ラインよりも最大で
0.08秒タイムを縮めることが可能になっているにょ。(19秒8台になると0.01秒を縮めるのが
難しくなってくるためこの0.08秒は非常に大きい)
何しろこのゲームはリストの短さと遊びやすさを優先させているため慣れるとタイムに差が
出にくくなってしまうからね。
特にアクセル全開で走るとタイム差が全く無くなってしまうためアクセルを離さなければ
ならない場合のみタイム差が発生するにょ。
しかし、この要素を取り入れることでハンドルを切るたびにタイム差が発生するため
0.01秒単位のタイムアタックが熱くなるにょ。(いかにアクセルを緩めず、かつハンドルを
切っている時間を短くするかがタイム短縮のポイントとなる)

それと重要になるのはカーブの時の挙動だと思うにょ。
シミュレータではないので厳密な計算は不要だけど急カーブが簡単に曲がれすぎても
難しすぎても面白くないので疑似3Dではいかにそのバランスをとるかが重要になるにょ。
そのバランスを取る上で考慮すべきことは「カーブを曲がる際には遠心力が働く」という
簡単なことだけにょ。
あえて説明するまでもないことだけど遠心力は速度の2乗に比例し、カーブの半径に反比例
するにょ。
もちろん速度の2乗に拘る必要もないため自分のゲームに合ったもの(自分がベストと
考えるバランス)で問題はないと思うにょ。
タイムアタック重視のレースゲームといえばアクセルワークとコーナーのライン取りが
重要だと私は考えているためPETIT RUNではそれを重視してバランス調整をしているにょ。
これが13行目の X=X+R*S*S/340 というものにょ。
あとコースアウト判定はインに厳しくアウトに優しくなっているため超スピードでぎりぎり
曲がりきるという感覚を味わいやすくなっていると思うにょ。(特にそれはオプションの
コース4で顕著に現れている)

このゲームで唯一疾走感を実感できるものが道路に描かれた白線にょ。
1画面に収めるために障害物や背景オブジェクトは一切登場しないからね。
白線は一定間隔ずつ現れるのだけどこれはトータルの移動距離を示すHを一定倍数し剰余を
演算しているだけだからほとんど長くならずに追加できるのでリストパフォーマンスは
非常に高いと思われるにょ。
15行目の C=13+((I+H*40)%8>=6)*2 がそれに相当するにょ。
これは、道路を描いている四角形(ライン)のうち8ライン中6ラインが道路の地の色を
示すというものにょ。(差し引き 8-6=2 で白線は2ライン分の太さとなる)
この「8」「6」の数字を変えることで白線の間隔や太さを変えることが可能になるにょ。

一般的にゲームのスピード感を増加させるためには移動速度を上げれば良いのだけどこれは
このゲームにおいては白線の移動速度においてそれがいえるにょ。
このゲームでは最高速度(Sの値)は約31.8となっており、移動距離Hを40倍している(言い
変えるとコースの基本単位の1/40移動すれば1ライン分移動となる)ために最高では
1フレームあたり31.8×40=1272増加することになるにょ。
1200でHの値は1つ増えるように設定されてあるために最高速度まで上げても1フレーム
あたりでは1ライン程度しか移動しないにょ。
この移動量を増やせば(例えば40という数字を80に増やすなど)さらにスピード感は増す
と考えがちだけど注意しておかないといけないのはその上げ方にょ。
白線が一定間隔で出ている以上はその間隔と同じ速度(このゲームでは1フレームあたり
8ライン)で動作させた場合は元の位置と同じ位置に白線が表示されることになるために
動いているようには見えなくなってしまうにょ。

では、それよりも遅ければ良いのかというとそうでもないにょ。
白線が8ラインおきにある場合には1フレーム当たり白線を7ラインの移動移動した場合には
逆に1フレーム当たり1ライン後退しているように見えてしまうにょ。
それならば8ラインの半分の速度である4ラインくらいならば十分高速に進んでいるように
見えると思うかもしれないけど8ライン中に白線が2ラインの場合には4ラインの移動すれば
今まで存在してなかった白線と白線の中央に白線が存在しているように見えてしまい再び
停止しているように見えてしまうにょ。
つまり、スピード感を上げるために白線の移動量を増やすことは効果的だけどその量は
白線間隔の半分を大きく下回るように必要があるにょ。(移動量を大きくすればするほど
スムーズさを失う)
これは白線だけに止まらずゲーム内に現れるオブジェクトすべてに言えることにょ。
言葉で説明されてもよく分からないという場合は実際にH*40の数字をH*200とかH*300にして
実際に自分の目で確かめるのが一番にょ。

あとやはりコースが1つでは物足りないという人もいるかもしれないにょ。
デフォのコースは無難なものにしたけど簡単すぎるとか難しいとかいう人もいると思うし、
1つでは飽きてしまうかもしれないにょ。(私はスーファミ版のF-ZEROのMUTE CITY Iだけで
数ヶ月遊んだけど)
1画面で複数のコースを用意するのは無理(乱数列が自分で選べるのならば乱数を使うと
いう方法もあるけどプチコンではそれができないし、自分の好みのコースの乱数列なんて
なかなか難しい)ということで、やはりコース作成が簡単にできるデータ構成にすることで
プレイヤー自らに新しいコースを造ってもらうという選択肢を用意することにしたにょ。
コースデータは非常にシンプルで「5」が直線で「1」が左急カーブ、「9」が右急カーブ
となり、その間の数字がそれに応じたカーブとなっているにょ。(プチコンのソフトウェア
キーボードを普通に見ていれば「1」「9」のどっちが左右のカーブに相当するのかが
分からなくなることもないと思う)

前回のスキーゲーム、今回のレースゲームと2回に分けて疑似3Dゲームについて書いてきた
けれど疑似3Dゲームで重要なのは「表示に違和感がないこと」「操作に違和感がないこと」
ということにょ。
3Dポリゴン(もしくはワイヤーフレーム)でないのだから厳密に計算するということに
それほど大きな意味はないもののプレイをしていて違和感を感じるようなレベルだと
良いとはいえないにょ。
ただ、それらは原因が分からないと対処が難しいけどほとんどの場合は前回、今回書いた
ように違和感を感じる原因は明らかなものとなっているにょ。
とはいっても、プレイしていて面白いというのが最も重要にょ。
多少違和感を感じてもそれを吹き飛ばすような面白さがあれば問題ないということにょ。
ただし、プレイヤーに違和感を感じさせることによって面白さを損ねているという場合が
あるためそういう場合は上記のように違和感を無くすことが重要になるにょ。
1画面であろうと違和感を無くすゲームを作ることは「プチコン スキー」「PETIT RUN」を
見て可能であることは分かってもらえると思うにょ。




掲示板管理者へ連絡 無料レンタル掲示板