E500BASIC高速化のすべて

PART 7 表示を高速化


 PART4の(4)について考えていきましょう。
 ゲームを作る場合は表示部分の速度がボトルネックになっていることは多くあります。そのため単純なアクションゲームを作っても遅いと感じてしまったことがある人もいるのではないでしょうか。ポケコンBASICで作られたゲームであってもアクションゲームならば最低5cps、できれば10cpsくらいの速度は欲しいところですからね。

 PC-E500シリーズのBASICにおいて表示に関係した命令はPSETLINEGPRINTPRINTの4つがあります。グラフィック表示の命令とテキスト表示の命令を同列で記しても仕方ないと思う人もいるかもしれませんが、それぞれは他の命令で置き換えが可能です。
 PSETを使えば、ドット単位でグラフィック表示が可能なので速度さえ気にしなければLINEやGPRINTを置き換えが可能です。同じく、LINEでもキャラクタ表示ができるためGPRINTからの置き換えが可能です。そのように置き換えた際の速度の違いがどの程度になるのかを示したものが下記の表です。

速度比較(PSETを1とした時の速度)
 PSETLINEGPRINTPRINT
12×8ドット
1
3.6
24
65
48×8ドット
1
3.6
26
122

 この表は12×8ドット、および48×8ドットの画像を表示した際の概算速度ですが、同じサイズのグラフィック表示をするのにPSETやLINEだと非常に非効率的というのが分かると思います。したがって、
PART3「VS」において「VSターボ」ではLINEをGPRINTに変えることで高速化をしています。それと同じくGPRINTでキャラ表示を行っているゲームならばそれをPRINTで行うこと、つまりフォント書き換えを使用することで高速化が可能になります。
 遅い表示命令を速い表示命令に変えることで高速化が可能というのは分かったと思いますが、実際は簡単に置き換えができない場合の方が多いです。例えばGPRINTをPRINT(フォント書き換え)で置き換える場合も表示キャラがキャラクタ単位で表示、キャラクタ単位での移動しかできないですね。工夫をすればPRINT文で1ドット単位の移動はできるようになりますが、制限が多いために用途はかなり限定されます。

 置き換えができない場合であっても速くする方法がないわけではありません。
 GPRINTではPART4の省略で書いたようなダブルクォーテーションを省略することで高速化ができます。GPRINT "FF"GPRINT 255と同じものですが、ダブルクォーテーションが無い分だけ高速になるわけです。ただし、横1ドットのキャラ表示以外だとダブルクォーテーションを除いた場合はセミコロンでキャラを繋げる必要があり高速化どころかかえって遅くなってしまうために使える場所はかなり限られると思います。
 GPRINTにもPRINTにも言えることですが、上記の表を見ての通り1回のGPRINT/PRINTで表示する量が多いほどサイズ当たりの速度が速くなっています。それは、GCURSORやLOCATEの処理時間も無視できないからです。しかし、キャラのサイズが大きくなれば表示そのものに時間がかかるため相対的にGCURSORやLOCATEの処理時間が小さくなります。
 また、PRINTにおいてはPRINT#による表示の高速化を行えば一度に多く表示した際の高速化効果をさらに大きくすることができます。

 一度に大きなキャラを表示するにはOPASを使うという方法があります。OPASはフォント書き換えの考えを応用したものですが、1ドット単位でスクロール表示を行う場合はGPRINT比で最大100倍速(画面全体をスクロールさせる場合)が可能になります。このスクロール機能を使えば、「ポケコンオリンピックINナガノ」(ベーマガ98年4月号掲載)のカーリングやスケートのような1ドット単位でスクロールするアクションゲームも実用的な速度で制作可能になります。
 OPASは工夫次第では見た目の小さなキャラクタ表示でも高速化が可能になることがあります。「ピーチバレー」(ベーマガ97年9月号掲載)は敵、味方合わせて4人のキャラを使ったバレーゲームですが、普通にGPRINTを使えばキャラ表示部分だけで約200m秒かかってしまいます。これでは表示だけのプログラムでメインルーチンが5cpsとなり、移動ルーチンなどを加えたら3cps以下になるために快適動作は期待できません。OPASは原理上小さいキャラ表示には向いていませんが、コートに固定されたキャラをコート自体を左右にドット単位でスクロールさせることでキャラ移動を実現したのでGPRINT比5倍速の表示速度となりました。こうすることで移動ルーチン自体も簡略化できるためメインルーチン全体の実行速度も8cps(125m秒)が実現できました。
 「シュプール2」ではプレイヤーキャラの表示、近景である旗の擬似3Dスクロール、遠景のドット単位の横スクロール、スピードメーターの4つのものをOPASを使うことで1つのPRINT文で表示することで実現しています。1つのPRINT文でたくさんのものを表示することで大きな高速化効果が得られメインルーチンの実行速度は7.7cps(130m秒)になりました。表示にかかっている時間は、ゲーム内で使われている上記4つのものを合わせて60m秒程度なのですが、普通にGPRINTを使い全く同等の表示を行った場合は1回の表示に2秒くらいかかるために30倍くらいの高速化が実現できたことになります。
 このようにスクロールなど画面上の大きな部分の書き換えを伴う場合はOPASが非常に有用であることが分かると思います。

 高速な表示命令を使用することで表示自体の高速化が可能になるとはいえ、それを生かすにはそれ相応の工夫が必要になるということが分かったと思います。特にPRINTにおいてはフォント書き換えとそれを応用したOPASがあるため工夫次第では速度の向上率はかなりのものに達します。(上記の表におけるPRINTの速度はフォント書き換え時で高速化テクニックを未使用時のもの)

 ただ、高速な命令を使うといってもなかなか簡単にはいかないでしょう。私はベーマガやPJに掲載されたゲームプログラムをたくさん高速化してきましたが、表示方法を変えることによって大きく高速化できたのはたかじょゆうき。さん作「So Nervous」(E500用)くらいです。フォント書き換えを使用していたのをOPASに変えるだけで5倍速が実現できました。その時に使ったテクニックを応用して作ったのが「パネルQ」です。
 なぜ高速な命令を使うのが簡単にはいかないかというとPART5のアルゴリズムのところで書いたように元からあるオリジナルのゲームに忠実(キャラの表示位置や一度に動作する移動量などがオリジナルと変わらないもの)に高速化しようとするからです。LINEを使用しているゲームにおいて単純にGPRINTに置き換えたり、GPRINTを使用しているゲームにおいて単純にフォント書き換えやOPASで置き換えられるゲームなんてほとんどないです。

 オリジナルに忠実にする必要はないのならば手っ取り早い高速化方法として例えば3体いる敵キャラを2体に減らしたりとか、メインルーチン1回当たりの移動量を増やして見た目の移動速度をアップさせるという方法があります。前者は、速くなる反面ゲーム性が変わってしまうし、後者は見た目の移動量がアップしているだけであって速度が速くなるわけではないのでキー反応が悪いゲームが改善されることはないです。

 しかし、新規に作る場合はそんなことを気にせず高速化が生かせるようなものにすれば良いのです。それは、フォント書き換えやOPASを使いやすいゲーム内容にするなどによって格段に高速化が可能になるということです。実際上記の「ピーチバレー」や「シュプール」などはそういうものがあることで初めて実現できましたからね。
 こういった高速化方法があるというのを知っておいた上でプログラミングするのと知らないでプログラミングをするのでは大きく変わってきます。知っておくことで選択の幅が広がるわけですからね。フォント書き換えというものも知らなければPRINTを使って高速にキャラ表示を行うということもできないためにGPRINTのみでアクションゲームを作り「BASICだから遅い」と思ってしまうのです。(もしもGPRINTを使用したらシュプールは0.5cps、ピーチバレーは2.5cps程度の速度になったと思われる)
 「BASICだから遅い」のではなく「遅い命令を(遅い使用方法で)使っているから遅い」というのがこのPART7を読めば分かったと思います。

PART8に続く


PART 1 なぜBASICを高速化するのか
PART 2 効率的な高速化を行うためには
PART 3 BASICの高速化とは
PART 4 どうやったらBASICが高速化できるのか
PART 5 アルゴリズムの見直し
PART 6 メインルーチンの軽量化
PART 7 表示を高速化
PART 8 IF文をうまく使う
PART 9 「BASICだから遅い」は言い訳の言葉

RETURN

inserted by FC2 system