表示 - みる会図書館


検索対象: 月刊 C MAGAZINE 2001年4月号
79件見つかりました。

1. 月刊 C MAGAZINE 2001年4月号

イラー角表現では , よく目にする東西南北 が直交した世界地図上で北上して東に向 かうようなルートでしか補間ができないの です。そしてクオータニオンなら , 最短ル ートでの補間が可能になります。 クオータニオンにはオイラー角表現の弱 点を補う効能があるみたいですね。いよい よ説明に入りたいところですが , その前に 少し準備をしておかないといけません。 その準備とは複素数 (complex number) のことです。ご存じの方も多いでしようが , おさらいもかねて進んでみましよう。複素 数とは Fig. 1 のような形の数のことです。 複素数は a で表される実部とわ i で表され る虚部から構成されています。ここで出て くる i を虚数 (imaginary number) といい , こ れは 2 乗して -1 になるという頭の痛い存在 です。どれだけ想像しても思い描けないと いう意味で虚ということなのでしようか。 それでも数学者はこの複素数を図示する方 法を考えました。それが複素平面 ( ガウス 平面 ) です。 複素平面 複素平面は Fig. 2 の図を見ながら説明し ます。まず直交する 2 軸を決めて水平の軸 を実軸と呼び , 右を正として実部の値を表 現します。また , 垂直の軸を虚軸として上 方向正で虚部の値を表現します。すると , 平面上に 2 次元グラフとして複素数の位置 を図示することができます。 なんか数学の授業みたいでつまらないか もしれませんが , この複素平面表示からは いくつかの重要な発見があります。まずは Fig. 1 複素数の式 複素数 Z = 0 十 bi 絶対値 (absolute) という概念が生まれます。 複素数の大きさといわれても理解しにくい ですが , 絶対値 ( 長さ ) といわれればもうべ クトルでおなじみですよね。そうなんです。 複素数の演算の多くは 2 次べクトルとして 取り扱うことが可能になるのです。 Fig. 3 は , 1 や i に注目して図示したもの です。実数 1 に虚数 i を掛け算することを考 えてみてください。答えは迷わず i です。 さらに i に i を掛けると -1 に , -1 掛けるよ引こ なります。どんどん i を掛け続けただけで す。出てきた結果を複素平面上で追いかけ ると・・・・・・なんと半時計回りに回転していま す。ここでいう回転がすなわち 3D オプジ ェクトの回転ではありませんが , 虚数の不 0 クオータニオン Fig. 2 複素平面 うことを始めに説明しておきましよう。複 オンですが , そもそもこれは何なんだとい 日本語では四元数と呼ばれるクオータニ 思議さという意味で紹介しました。 素数の 1 段階上の概念というほうが理解し やすいでしようが , ここでは少し乱暴に割 り切った考え方をします。複素数が実数世 界に虚数 i という概念を導入して構築され た数学の 1 分野だとしたとき , 同様に i , j, というルールを実数に導入して生まれた 世界のことをクオータニオンだと考えまし よう。 演算も性質も実数やべクトルとは異なり , ときには複素数とも異なる , 新たなルール による世界を学んでいきます。もちろん , 努力の報酬として最初にあげた 3D での効 能を期待して話を進めていきましよう。 丿レー丿レ まずは定義から見てみます。クオータニ オンとは Fig. 4- (a) のような形をしていま す。 ' こでがクオータニオンで , w , x , y, z はそれぞれ実数です。複素数と同じよ うなーだけでなく j やも存在していますが 何となくやろうとしていることはわかるは ずです。先ほどの複素数が実部と虚部とい z = 0 十わー 1 08 C MAGAZINE 2001 4

2. 月刊 C MAGAZINE 2001年4月号

利用することができます。 また , フレームに関係なく , 実時間をゲ ーム時間とすることもあります。こうする と表示などの処理の遅れなどに左右されな くなります。 WonderWitch では , sys_get_tick_count() で , 実時間を調べられます。ゲーム開始時 に sys-get-tick-count ( ) で値を保存し , そ こから任意のタイミングで再度 sys_get_tick ー count ( ) の値を得て , そこから保存した値 との差を得ます。この差がゲーム時間とな り , ゲーム開始時からどれだけ時間が経っ たのかを知ることができます。 背景の表示 WonderWitch では , キャラクタフォント という 8X8 ドットの単位で画像を扱います。 ところがこのフォントは 512 個しかありま せん。全画面で使ってしまうと , スプライ ト用のキャラクタフォントが足りなくなっ てしまいます。そこでいろいろな工夫が必 要になります。 ・背景の組み立て 全画面の背景が使えないのなら , 木や建 物といったいくつかの部品を作って , その 部品を組み合わせることで背景を作ります。 ロールプレイングゲームなどではよく使わ れている手法です。これなら部品ごとにキ ャラクタフォントを定義して , 背景を作る ときは , そのキャラクタフォントを複数画 面に指定していけばいいので , 全画面ぶん のキャラクタフォントを必要としません。 「どの場面でどの部品を組み合わせるか」 については , それ専用のリストを用意する 1 32 C MAGAZINE 2001 4 char backpic 」 ist [WIDTH] [ ] #de f ine BACKP I C—SWAMP 2 #define BACKPIC—TREE 1 # de f ine BACKP I C—NON 0 ことにします。たとえば , {BACKPIC—NON, BACKPIC—NON, BACKP I C_TREE , BACKP I C—TREE , } なお , 背景のスクロールはスプライトに とになります。 述のリストを元に背景を組み立てていくこ 「見えていない領域」ができたら , そこへ前 るためには , スクロールするたびに , この 背景が流れているようにスクロールさせ えない領域となります。 す。また , それとは反対側にある部分が見 そのはみ出た部分が表示領域に出てきま のです。この状態でスクロールを行うと , まり , 表示領域からはみ出した部分がある 実際には表示されない領域があります。っ 用に使える SCREENI, 2 のプレーンには , での画面構造を思い出してください。背景 本連載の第 1 回で紹介した WonderWitch ■スクロール 要になります。 一部を省略するといった演出的な工夫が必 なるかもしれません。そんなときは背景の これでもキャラクタフォントは足りなく とは思います。 リサイズを減らす方法をとったほうがいい た工夫をして , データの定義に必要なメモ キャラクタフォントに対応させたりといっ の部品を表したり , 1 つのデータで複数の ビットで 1 つのキャラクタフォント / 背景 実際にはメモリがもったいないので , 4 描画するようにします。 クタフォントへ定義していくことで背景を き , これを元に画像データを拾ってキャラ ストをゲームで使うぶんだけ用意してお ングゲームなら縦 1 列ぶん ) に相当するリ のような 1 列ぶん ( 横スクロールシューティ は影響を与えません。擬似スプライトに見 られるような画面更新の作業などは必要あ キャラクタの管理 りません。 す。こうしておくとみんな同じように扱え で変化するようにしてプログラミングしま キャラクタの移動もこの構造体を渡すだけ などが行われるようにしておきます。また , 体のデータを渡すだけでスプライトの設定 キャラクタを表示するときは , この構造 とめてしまいます。 のようになります。これを構造体にしてま ・その他キャラクタ個別に必要なテータ ・撃たれたときの得点 ・キャラクタフォントの番号 ・スプライトの番号 ・キャラクタの動きを返す関数 ・キャラクタの種類 ・移動位置の相対座標 ・表示位置の座標 ・画像テータ これらをまとめると , す。 の関数や撃たれたときの得点などもありま 利です。敵機や弾の場合は動きを得るため タとしてすぐに取れるようにしておくと便 ラクタフォントやスプライトの番号もデー ラクタとの調整のため , 定義しているキャ してそれを表示する座標です。ほかのキャ す。まず , 画像データは必ずあります。そ の処理を想像しながら決めることになりま どのようなものでしようか ? これは実際 敵機 , 自機 , 弾などに必要なデータとは ■キャラクタに使われるデータをまとめる いくようにします。 よう。そのあとで操作などの機能を加えて 弾に関係なく共通化することにしてみまし キャラクタに関係する処理を自機 , 敵機 ,

3. 月刊 C MAGAZINE 2001年4月号

ムのプロバティ」ウインドウが表示される ので , [ 詳細 ] タブを開きます。次に皿 ボタンをクリックすると「環境変数」ウ インドウが表示されます。 「〇〇のユーザー環境変数」の「変数」の列 に「 PATH 」がなければ皿ボタンをクリッ クして , 「変数名」欄に " PATH ' , 「変数値」 欄に PATH=C:YAPPYFILEYDOC" を記述し てボタンをクリックします。「変数」の 列に「 PATH 」があればその行を選択し て , 甌ボタンをクリックします。「変数 値」欄の最後に ";C:YAPPYFILEYDOC" を記 述してボタンをクリックします。 [ コボタンをクリックして「システムの プロバティ」ウインドウを終了すれば , パ スの指定ができ , カレントディレクトリが どこであっても XYZ. EXE を実行できます。 パスの設定が長くなってしまったなどの 理由で , 複数の行に分けたい場合は , 以下 のようにします。 SET PATH=%PATH%; C : *NEW SLT は , それ以降の指定の文字に設定・変 史するものです。上記の例では , "SYPPAT H " で今までの PATH の値を変更することを 指示しています。 " % PATH % " の部分に今ま での PATH の値が代入されます。その後ろ にある ; C : \ NEW が新しく追加されたパスの 設定です。上記のようにすれば , パスの設 定は , 「今までのパスの設定 + 新しいパスの 設定」に変わります。 SET の次にくる文字 や % で囲む文字によって Windows の設定を じようずに設定・変更できるようになります。 この例は , あくまで C:YAPPYFILEYDOC ディレクトリが存在した場合に限ります。 実行ファイル名は何でもかまいません。上 記のパスの指定は , MS-DOS/Windows に C:YAPPYFILEYDOC ディレクトリに実行フ ァイルを探しにいかせるためのものです。 なぜバスを通すのか Windows では MS-DOS プロンプトを使う ことはまれで , わざわざパスを通す必要は なさそうです。しかし , フリーで使うこと のできる Borland C + + Compiler や ISI C -86 試食版 , Java DeveIopment t は , MS-DO S プロンプトでコンパイルすることが前提 となっているため , パスを通さなければコ ンパイラが動きません。これらのコンパイ ラは , プログラミングの初学者がよく使い ますが ( コンパイラは値段が高いですから ) , プログラミング学習前のインストールの段 階でつますいてしまうのです。 MS - DOS プロンプトを 使いこなす これまでの説明で , パスについてわかっ たと思います。 BorIand C + + Compiler や ISI C -86 試食版 , Java Devel 叩 ment Kit は , MS -DOS プロンプトで使うことが前提になって います。せつかくここまで理解できたのな ら , MS-DOS プロンプトをもっと使えるよ うになりましよう。 MS-DOS プロンプトからは , 実行ファイ ル名を打ち込む以外に , MS-DOS プロンプ ト内部で用意されているコマンドがありま す。これらはとても便利なので , 覚えてお カレントディレクトリ いて損はありません。 ようなオプションがあるかは , " / ? " オプ とは違った動作をします。コマンドにどの なオプションを付けると , コマンドは通常 ョンと呼ぶもので , " / " の後ろにいろいろ とします。コマンドの後ろの " / B " はオプシ DIR /B ァイル名の一覧だけを出力したい場合 , ファイルサイズも表示されますが , 単にフ あります。 DIR ではファイルの更新時間や です。 DIR コマンドにはほかにも使い方が DIR 名を見てみましよう。そのコマンドは , ィレクトリにあるディレクトリ・ファイル トディレクトリです。まずは , カレントデ などとなっています。これは現在のカレン C : *Windows> MS-DOS プロンプトの最下行は , 必読 DOS の仕組み ションを指定します。すべてのコマンドに / ? オプションがあるとは限りませんが , 初 めて使うコマンドは試してみましよう。 緒にコマンドの説明書も見られます。 C:YWindows ディレクトリにはファイルが いつばいあるので , キーを押したと たんに画面が流れてしまいます。 1 画面ず つ表示が止まってくれたらと思ったなら , MORE DIR と打ち込んでみましよう。 MORE コマンド は , 出力を 1 画面ずつ表示するコマンドで す。そして DIR と MORE の間にある " " は パイプと呼ばれるもので , 最初のコマンド の出力結果を次のコマンドへ橋渡しするも こでは , DIR でカレントディレ のです。 クトリ内の一覧が出力され , その出力を M ORE コマンドで 1 画面ずつ表示しています。 画面が止まっているとき , ーキー を押せば次の画面になります。 DIR の出力結果をファイルにして , あと でメモ帳で確かめたいと思ったなら , DIR > ファイル名 と打ち込んでみましよう。コマンドの後ろ に " > " を付けると , " > " の後ろに指定したフ ァイルにコマンドの出力結果を記録できま す。そのとき , 指定したファイルがすでに 存在していた場合は , 元のファイルの内容 が消えてしまうことに注意してください。 また " > " ではなくて " > > " を使えば , 元のフ ァイルの内容の後ろにコマンドの出力結果 を記録できます。また " く " を使うと , コマ ンドに入力することができます。たとえば DIR コマンドの出力結果を記録したファイ ル kekka. txt があったら , MORE く KEKKA . TXT とすれば , 1 画面ずつ KEI A Ⅱ XT の内容を 表示します。 " > " " > > " " く " による操作をリダ イレクトと呼びます。 ワイルドカード DIR コマンドの結果をある条件で絞って 表示させたいときには , ワイルドカードと 特集プログラミング入門必読 DOS の仕組み いうものを使います。ワイルドカードには , 27

4. 月刊 C MAGAZINE 2001年4月号

五ロ なり次の行には続かない をコンパイルしましよう。コンパイルには プログラムの動作は次のようになります。 JDK に含まれる javac というコマンドを使い List 1 では , 1 行目の / * でコメントが始 最初にどれかのクラスのメソッドが押され ます。コマンドラインから , まって , 3 行目の * / で終わっています。ち る。押されたクラスは次に , 別のもしくは なみに 2 行目の * はなくてもいいのですが 自分のクラスのメソッドを押す。そのクラ javac Opinion. java と打ち込みます。もし正常にコンパイルで コメントとわかりやすいように入れていま スはさらに別のクラスのメソッドを押す。 きたなら何も表示せずに終了します。何も す。よく使われる手法です。 そうしていく過程で入出力とか数値計算と 表示しないけれど , ディレクトリの中を見 5 ~ 9 行目までが , Opinion というクラス かが行われ , 最終的に望む動作がなされる , の内容の記述です。 Java の場ム ' ' ということになります [ 注 3 ] 。 てみると , ロ , っー、う 記述を普通「宣言」といいます。 6 ~ 8 行目ま List 1 は , 1 つのクラスに 1 つのメソッドだ 0P土n土0n. Class というファイルができているはずです。そ でが main というメソッドの宣言です けという , 最小の Java プログラムです。ち Java プログラムは , クラスと ( それに含ま うすれば成功です。成功しなかったら失敗 ょっと大きいプログラムだと , 数十のクラ れる ) メソッドの宣言によって成り立って です。そういうときはコンパイラがエラー スにそれぞれ数個から数十個のメソッドが メッセージを出すので , それを見てソース います。 存在します。 6 行目の main というメソッドは , プログ を修正し , もう一度コンパイルしてくださ 先ほど , Java がオプジェクト指向プログ ラミング言語であると言ったことを思い出 ラムの中で最初に押されるスイッチの役目 無事に拡張子が . class のファイルーーー以後 してください。オプジェクト指向とは・・・ を果たします。 Java プログラムの中には最 クラスファイルと呼びます -- ーができたと と考え出すとめんどうになるのですが 低 1 個 main メソッドがあり , そこからすべ く単純な意味では「クラスを使ったプログ します。いよいよ実行です。実行には , や て始まります。その main の前後に付いてい る , ばぶりつく・すたていっく・ばいど・ はり JDK 中の , java コマンドを使います ( jav ラミング」ということになります。 a コマンドというのが JVM として働くプログ Fig. 3 に「オプジェクト指向プログラム」 すとりんぐ・あーぐすというのは , main メ ラムなのです ) 。 の概念図を示します。図の中のスイッチが ソッドに付きものの記述です。今は考えな 付いた機械のようなものがクラスで , プロ いでください。といっても気になるでしよ java Opinion うから , 一応意味を書いておきます。 というように起動します。このときはコン グラムはいくつかのクラスからなります。 パイルのときと違い , 拡張子「 . class 」を付 クラスの表面にあるスイッチはメソッドを メソッドが公開であること ・ public けてはいけません。拡張子を付けて起動す 表します。 を意味する ると , かえってエラーになります。 メソッドがインスタンスへ 「空地に屋根ができたね」「やーねー」 の参照を持たないことを意 味する ちゃんと表示することができました。 メソッドが返却値を持たな List 1 の解説 いことを意味する ・ String ロ 文字列型の配列という型を 表す String [ ] 型の変数 ・ args main メソッドを書くときには , これらと セットにします。 7 行目の「 system. out. println ( … ) 」という のは , Java で一般的にコンソールに文字列 を表示するやり方です。ちなみにこれは表 示し終えたら改行します。改行したくない ときは System. out. print ( … ) を使います。 System というのもクラスです。 Java のラ イプラリの中にあるクラスは , import とい う手続きをしたあと , 自由に使うことがで ・ stati c Fig. 3 オブジェクト指向プログラムの概貪 図 ( プログラム ) ・ VOid ここで簡単にソースコードの内容を解説 しましよう。もう一度 List 1 を見てくださ 1 ~ 3 行目はコメントです。これはプログ ラムの実行には関係ありません。コンパイ ラには無視されるのですが , 人間があとで 見てわかりやすいように説明を書いておく ものです。 Java のコメントには 2 種類あります。 ・ / * で始まって * / で終わるもの。複数 行のコメントが書ける ・ / / で始まるもの。行末までコメントに 特集プログラミング入門 Java 言語入門講座イ 9

5. 月刊 C MAGAZINE 2001年4月号

ル , それ以外がバイナリファイルです。ワ ープロソフトで通常に保存すると , メモ帳 では読むことのできないバイナリファイル になります。またテキストファイルで保存 する旨を指定すれば , 文字などの装飾はな くなりますが , メモ帳で読むことができる テキストファイルになります。 Web プラウ ザが読み込む HTML ファイルはテキストフ ァイルですし , NOTEPAD. EXE などの実行 ファイルはバイナリファイルです。 ファイル名として使えない文字がありま す。それは半角の以下の文字です。 ファイル名として付けてはいけない名前 もいくつか存在します。これらは MS-DOS/ Wrndows で予約され , 内部で使われている ためです。それは , プリンタを表す PRN キーポードなどのコンソールを表す CON , RS -232C などの入出力装置を表す AUX(AUX 1 ~ A [ Ⅸ 4 も同等 ) などです。また , 同じディ レクトリ ( 次に説明します ) には , 複数の同 じファイル名は存在することができません。 ファイル名には , そのファイルがどのよ うな種類なのかがわかりやすくするための 拡張子というものがあります。それはファ イル名の ". " 以降の文字です。 BAT, COM, EXE は実行可能なファイルを表しています Fig. 2 ディレクトリの構造 APP サブディレクトリ ( ほかにも実行ファイルを表す拡張子があ ります ) 。テキストファイルに上記の拡張 子を付けてもかまいませんが , それで何か が起こるというわけではありませんし混乱 を招くので , やめたほうがいいでしよう。 代表的な拡張子を TabIe 1 にあげておきま す。これ以外にもまだたくさんあります。 W1ndows ではあまり関係ないことですが MS-DOS にはファイル名の文字数の制限が ありました。それは , 拡張子と . を含まない 部分は 8 文字まで , 拡張子は 3 文字までとい うものです。また , アルファベットは大文 字小文字の区別はありませんでしたが , 通 常はすべて大文字で表示されていました。 Windows では , それらの制限は緩和されま た , これらの制限に従ったファイルの痕跡 を見ることができます。 こまでを Fig. 1 にまとめます。 ディレクトリとルートディレクトリ ディレクトリとは , ファイルの入れ物で す。たとえばアプリケーションのファイル が入っているディレクトリや開発中のソー スファイルが入っているディレクトリなど の中に関連するファイルを入れます。 ディスクの中が階層構造なのはディレク トリの中にディレクトリを作ることができ ルートディレクトリ DATA サプディレクトリ README. TXT ファイル FILE サプティレクトリ DOC サプディレクトリ EDITOR MUS ℃ サブティレクトリサプディレクトリ ABC. FILE ファイル DOC サブディレクトリ 注意書 . TXT ファイル README. TXT README. TXT XYZ. EXE ファイル ファイル ファイル 必読 DOS の仕組み 特集プログラミング入門必読 DOS の仕組み 25 EXE を実行してね」 ' で記した " \ " 記号 ように表します。「 YAPPYFILEYDOCNXYZ. 少しまだるっこしく感じます。そこで次の を実行してね」となります。これでもまだ クトリの DOC ディレクトリにある XYZ. EXE ならば , 「 APP ディレクトリの FILE ディレ リから順にたどるように伝えます。 Fig. 2 このようなときには , ルートディレクト Z. EXE が複数存在していたら無理です。 と複雑な構成でファイルも何百とあり , XY リ・ファイル数なら可能でしようが , もっ と伝えますか ? Fig. 2 程度のディレクト に XYZ. EXE があるからそれを実行してね」 場所を伝えたらよいでしようか。「どこか す。さて , どのようにして XYZ. EXE のある を実行してほしくてディスクを人に渡しま たとします。ほかの人にこの中の XYZ. EXE Fig. 2 ような構成をしたディスクがあっ バス ここまでを Fig. 2 にまとめます。 は , ディレクトリという名称を使います。 ほうが少し広い意味に使われます。ここで います。ほば同じ意味ですが , フォルダの はディレクトリのことをフォルダと呼んで ィレクトリと呼びます。なお , Windows で リの中にあるディレクトリのことをサプデ ィレクトリと呼びます。また , ディレクト トリになるということで , 特別にルートデ そのドライプの根っこ ( ルート ) のディレク れると書きましたが , このディレクトリが 先ほどディスクの中は木の構造にたとえら とも表面で , すでにディレクトリの中です。 るはずです。この場所は C ドライプのもっ つかのディレクトリとファイルが表示され C ドライプの中に入ってみましよう。いく ドライプのアイコンをダブルクリックして 先ほどの " マイコンピュータ " の画面で C 管理しやすくできます。 いうように階層化して , さらにファイルを リ , Y アプリケーションのディレクトリと リの中に X アプリケーションのディレクト るためで , アプリケーションのディレクト

6. 月刊 C MAGAZINE 2001年4月号

るとプレイヤの負けとなります。 こで弾も 1 つのキャラクタと考えると , 画面上に表示するキャラクタの「移動」 , 「表 示」 , 「表示位置の座標値の増減」など , キ ャラクタに対する操作は , すべて共通化で きそうです。自機ではプレイヤによる操作 , つまり十字ボタンなどの操作に応じて表示 位置の座標値を増減する処理を行えばいい のですが , 敵機や弾の場合は , これをプレ イヤの代わりにキャラクタの性格 ( 戻って きたりとか敵に追尾したりなど ) に合わせ て , あらかじめ用意したコードやデータで 座標値を増減させることになります。座標 を変化させるところを 1 つの関数などでま とめておけば , どのキャラクタでも同じよ うな処理となるはずです。こう考えていく ことで , キャラクタに関する共通の処理を いくつかにまとめることができます。 敵機などは , 決められた位置である特定 の動きを見せます。いわゆる「ポスキャラ」 などは , ゲームを進めて最後のほうに出て くるものですし , 動きもほかのキャラクタ と相当違います。このような「いつ出てく るのか」 , 「どんな動きや攻撃をするキャラ クタなのか , そのキャラクタの種類」とい うことも管理することになりそうです。 「弾が当たった」 , 「敵機がぶつかった」な ど , キャラクタ同士がぶつかっているかど うかを調べる処理も必要です。これは「当 たり判定」などと呼ばれています。この処 ーゲームの進行 ム性に影響する部分でもあります。 てしまう」などといったことがおき , ゲー ずかに触れただけでゲームオーバーになっ 理がよくないと , 「弾がすり抜ける」 , 「わ 1 30 C MAGAZINE 2001 4 ますが , これを全部キャラクタごとに処理 うにあるデータやコードによって操作され にそれぞれ動いています。敵機は前述のよ これらのキャラクタは , 画面上では同時 しなければいけません。ある意味ではマル チタスク的な処理が必要となりそうです。 ちょっと頭を切り替えて , アニメーショ ンという視点でこのことを見てみます。テ レビアニメーションでは , 登場人物が好き に動いていますが , 元をただすと 1 枚の絵 を動かしたい方向に少しずつずらして描い たものを用意し , これを一定の速度でパラ パラと見せているだけです。目の残像効果 によって絵が動いているように見えるとい うおなじみのものです。 これはシューティングゲームにも応用で きます。つまり , あるタイミングごとに ・背景を少しだけスクロール ・キャラクタの位置を増減 ・キャラクタを描画 これを表示しているキャラクタだけ繰 り返す ということをすれば , みんな動いているよ うに見えそうです。このタイミングで表示 される 1 つ当たりの画面を「フレーム」 , タ イミングそのものの時間のことを「フレー ムレート」などといいます。 ゲームの進行には , このほかに当たり判 定によって得点やプレイヤの負けを決めた りする部分や , いわゆる「面管理」なども必 要になります。 ひとくちにシューティングゲームといっ ても , いろいろな処理があることがわかり ました。まとめると Fig. 2 のようになりま す。これらを WonderWitch 上で実現する方 法を考えてみましよう。 キャラクタの表示 どんなものでも絵が出せると楽しいもの です。そこで , 始めにシューティングゲー ムで使われるキャラクタを表示させること にします。 ・スプライト 背景とキャラクタの重ね合わせが必要に なるため , キャラクタの表示には「スプラ イト」を利用することになります。一般的 にスプライトというものは , 「キャラクタ のように画面と比較して小さな絵をまとめ て管理し , 背景となるものと合成して表示 する」機能のことをいいます。 WonderWitch ではハードウェアとしてス プライトの機能があり , 背景よりも前に表 示するのか , 後ろに表示するのかなども指 シューティングゲームで使われている手法 ・背景のスクロール ・スプライトを使ったキャラクタの描画と重ね合わせ 〇キャラクタ ・弾や敵機 , 自機の表示 ・プレイヤによる操作 , ボタンの押下判定 ・種類に応じた敵機と弾の移動 ・ゲームの進行に応じた敵機の出現 ・キャラクタ同士の衝突を調べる当たり判定 〇ゲーム本体 ・フレーム管理 ・得点計算 ・ゲーム終了の判断

7. 月刊 C MAGAZINE 2001年4月号

定できます。実際のプログラミング例につ いては本連載の第 1 回 ( 2000 年 12 月号 ) をご 覧ください。また , 使い方については , Fi g. 3 にまとめました。 重ね合わせの処理は , 画像に指定されて いる透明色 ( パレットの 0 番 , というように 決められている ) で塗りつぶすことで , そ の部分が透過してバックにある背景となり ます。マスクを作ったり , 論理演算をした ・・といった手間はいりません。 スプライトも画像データを 8X8 ドット単 位で扱います。どんなに大きなキャラクタ でも , この 8X8 ドットの大きさに分割し , キャラクタフォントとして扱うことになり ます。もし , こうした大きなキャラクタの 座標を移動させるときは , それぞれ分割し て登録したスプライトに対して行うことに なります。 ■アニメーション 表示するキャラクタがただの 1 枚の絵だ ったら , あまり臨場感がありません。そこ で前述のように , あるタイミングで絵を少 Fig. 3 スプライトの使い方 しずつ変化させることで , アニメーション させてみることにします。 画像はアニメーションさせるぶんだけ用 意します。キャラクタの場合 , 最初と最後 がつながるようにしておいたほうが無難で しよう。この 1 枚当たりの画像を「コマ」な どといいます。 WonderWitch では画面サイ ズが小さいので , それほど細かくアニメー ション ( コマ割り ) させても , あまり効果は ありません。適度に大きな動きをさせたほ うが効果的です 表示の差し替えは , 単純にキャラクタフ オントを書き換えるだけでも十分です。た だ , そのままでは画面書き換え中のようす が表示されることがあり , 画面のちらっき などの原因となることがあります。そこで , いわゆる垂直帰線待ちを行うことでこれを 防ぎます。 WonderWitch では , sys_wait ( 1 ) で待つほかに , sys_get_tick_count ( ) で得た 値が変化したかどうかで調べる方法があり ます。 アニメーションでは , あるコマを表示し たあと , 次のコマまである時間だけ待つ必 1 . font ー set ー colo 「 data ( ) などで画像データをキャラクタフォントへ登録 2. sprite-set-char() にキャラクタフォントの番号を与え , スプライトとキャラクタフォントを 結び付ける 3. sprite-set—range() で登録したスプライトの番号の最初と終わりを指定し , 表示を行うよう にする 4. sprite-set 」 ocation() でスプライトの表示位置を指定する for (i = 最初のスプライ土く最後のスプライ土十十 ) { sprite-set-location(), 表示座標の横位置 + ()i 宅キャラクタの横の大きさ ) * 8 ) , 表示座標の縦位置 + ( ( 土 / キャラクタの縦の大きさ ) * 8 5. 移動させるときは sp 「 ite ー set 」 ocation ( ) に 1 ドット単位で指定。相対座標で指定するときは , 下記のようにする fo て (i = 最初のスプライ土く最後のスプライ土十十 ) { adr = sprite—get—l ocation(i); sprite-set-location(i , 相対座標の横位置 + (adr & 0xff) , 相対座標の縦位置 + (adr > > 8 ) 遊ひ。レイピ 要があります。この「 1 コマ当たりの時間」 を待っことでアニメーションの速さを調整 しているのです。 遊びのレシピ fo 「 WonderWitch 1 31 これは後述するキャラクタの出現や移動に を「ゲーム時間」などということがあります。 で進んだか」を知ることができます。これ りカウンタを 1 つ進めると「ゲームがどこま 1 つのカウンタを用意し , 1 フレームあた ・ゲーム時間 う処理にします。 らいくつ過ぎたら次のフレームへ移るとい sys—get—tick—count ( ) の値を得て , そこか 中に 1 フレームぶんの処理を連ねておき , するには , ゲームが終わるまで続くループ WonderW1tch でこのフレーム処理を実現 に合わせて表示することになります。 ションの実現などもこの連続するフレーム 理を終わらせる必要があります。アニメー 単位時間当たり , つまり 1 フレーム中に処 ると , 表示されるすべてのものは , この 1 換える」作業が必要になります。逆に考え 決まった時間ごとにキャラクタなどを書き は , 滑らかな画像表示をするために「ある くのキャラクタが動いて表示される画面で アニメーションのコマもそうですが , 多 ・フレーム を中心にちょっと寄り道してみます。 す。それが時間処理です。前述のフレーム はキャラクタ管理以外にもう 1 つありま シューティングゲームでたいせつな処理 ある時間ごとに処理を行う ておきましよう。 方法を紹介する前に , 少しその処理を考え 理方法や流れを決めています。ほかの処理 は , 時間に関する処理があらゆるものの処 てきたようです。シューティングゲームで どうやら時間に関する処理が必要になっ

8. 月刊 C MAGAZINE 2001年4月号

Java programmingTips インスタンスごとにスレッドを使うので , ffread クラスを継承しています。そしてク ライアントに対してメッセージを送信する send ( ) メソッドです ( List 1- ⑩ ) 。これも synchronized にしています。 send ( ) メソッ ドの内部では , 改行文字を「 \ n 」に統一し たうえで BufferedWriter を使ってメッセー ジを送信し (List 1- ⑩ ) , 送信バッフアをフラ ッシュします ( List1- ⑩ ) 。一般的な端末ソ フトでは改行文字が「 \ n 」になっているこ とにご注意ください。 List 1- ⑩からはメッセージ受信スレッド から実行される run ( ) メソッドです。まず接 続したソケットを使って入出力ストリーム を作成します ( List 1- ⑩ ) 。このとき第 2 引数 でエンコーディングを指定しています。ス トリームを作ったら , 接続メッセージ表示 やハンドル名の入力を経て , メッセージ受 信待ちループに入ります ( List1- ⑩ ) 。ここで は BufferedReader を用いてメッセージを受 信し , ハンドル名を付加したあとに , 前述 の ChatServer クラスの broadcast() メソッド を呼び出して全クライアントにメッセージ を配信しています。 最後はクライアントとの接続が途絶えた ときに , ストリームやソケットを閉じる処 理です (List 1- ⑩ ) 。 トチャットクライアント telnet などの端末ソフトでは入力メッセ ージと受信メッセージが混ざって表示され てしまうため , チャットに使うにはやや不 便です。そこで , チャットクライアントを 作ってみました ( Fig. 3 ) 。サーバと対になる クライアントの作り方の参考にしてくださ 付録 CD-ROM に収録されている ChatClie nt.java を , javac ChatC lient. java でコンパイルしたあと , java ChatClient ホスト名ポート番号 工ンコーティンク で実行します。たとえば , チャットサーバ を前述のように動かしておいた場合 , サー バが動いているマシン上で , Fig. 3 チャットクライアント 、上 Ohat 0 lient VVelcome Java Chat Setver. Make sure tO use SJIS encoding Please enteryour handle name. OK. Thankyou foraccess, ひぐ 10 : 33 : 17 ひぐ logged れ 10 : 33 : 25 ペん logged in. 10 : 33 : 38 ひぐ】ネットワークゲーム 10 : 33 : 57 いん ] 蒸し風呂 10 : 34 : 04 ひぐ ] 論理学 10 : 34 : 10 パん ] 苦悶の表情 10 : 34 : 17 ひぐ ] 打たれ強さ 10 : 34 : 22 [ ペん ] 沙羅 10 : 34 : 25 ひぐ】湯たんま 10 : 34 : 28 ん】ポニーテール 10 : 34 : 32 ひルートディレクトリ 10 : 34 : 36 いん ] 輪転秤 10 : 34 、 49 ひぐ ] 槭の体 1 0 : 34 : 54 いん ] 六八車 10 : 35 : 02 ひぐ ] まじめこ仕事しよう・ 10 : 35.07 いん ] うん・ 先週は PSOI こハマってしまったことだしな・ 0 0 0 List チャットクライアント import java. 土0. * ー mpo てし java. net. *ー import java. awt. * ー import java. awt. event. *ー import javax. swing. * ー public class ChatClient extends JFrame implements Runnable ( / / ソケット Socket socket ー / / ログ表示領域 JTextArea ー og ー / / 入力領域 JTextField input; ノ / 工ンコーティング String enc; BufferedReader ての / / 入力用ストリーム BufferedWriter wti / / 出力用ストリーム / / ホスト string host; / / ポート int port ー / / アプリケーションのスタートアップ pub lic static void main ( string args [ ] ) (new ChatClient(args) ) . main( / / 使い方を表示して終了 static void usage( ) { System. ou し print ー n ( usage: java ChatClient HostName #port EUC/jIS/SJIS" System. eX土し(1リ 〃コンストラクタ ChatCIient(String args[ ] ) { / / GUI 構築 super("Java Chat Client" getContentPane( ) . setLayout(new BorderLayout( ) 房 getContentpane( ) . add(log=new JTextArea( ), BorderLayout.CENTER 、 log. setEditabIe(false); getContentPane( ) . add(input=new JTextField( ) , BorderLayout.SOUTH); setSize(600,400); setVi sib 厄 ( true ); / / イベント定義 addWindowListener(new WindowAdapter( ) { public VOid windowCIosing(WindowEvent e) { system. eX辻(0嶹 / / 送信処理 input.addActionIÅstener(new ÅctionListener( ) 。て public VOid actionPerformed(ActionEvent ev) string s=input. getText( input.setText("")$ try { 0 1 27 Java Programming Tips

9. 月刊 C MAGAZINE 2001年4月号

00 フログラミング入門 は , ディレクトリの区切りを表します。先 頭にある \ 記号は , ルートディレクトリを 表しています。また , Fig. 2 と同様の構成 をした C ドライプがあった場合は , C : %APP*F I LE*DOC*XYZ . EXE と表します。先頭の C : が C ドライプを表し ます。このように表現したファイル名を , フルバスファイル名 , ディレクトリまで ( フ ァイル名を指定しない ) を表現した場合は フルバス名と呼びます。 カレント PC には複数のドライプが存在できます。 ところが MS-DOS/Windows が一度に同時 に扱えるドライプは 1 つです。ドライプには 複数のディレクトリが存在できますが , MS -DOS/Windows が一度に同時に扱えるディ レクトリは 1 つです。工クスプローラでさま ざまなドライプのさまざまなディレクトリ をたくさん開けるのでそのようには感じな いかもしれませんが , 1 つのドライプの 1 つ のディレクトリだけを注目しているのです。 現在注目しているドライプをカレントドラ イプ , 現在注目しているディレクトリをカ レントディレクトリと呼びます。 MS-DOS や Windows 内部では , 上記のよ うなフルバスファイル名のうちでドライプ 名を省いた場合は , カレントドライプを指 定したことになります。同じようにディレ クトリ名を省いた場合は , カレントディレ クトリを指定したことになります。実際に はフルバスファイル名 ( もしくはフルバス 名 ) を表すときにディレクトリ名だけを省 くことはありません。 これで基礎ができたので , 最初に投げか けた , MS - DOS プロンプトで実行できた実 行ファイルと実行できなかった実行ファイ ルの謎を解明していきます。 ディレクトリ・ファイルが何百もあり , さらに XYZ. EXE が複数あったら , 他人が自 バスの設定 26 C MAGAZINE 2 1 4 分の思っている XYZ. EXE を見つけて実行で きるとは限りません。 MS-DOS/Windows で も同じです。 MS-DOS/Windows は融通が きかず , 指示されたことしかしません。ど こにあるかわからない XYZ. EXE を自動的に 見つけて実行することはしないのです。そ して MS-DOS/Windows はカレントをいつも 注目しています。ここまで書けば , 勘のい い方ならおわかりでしよう。フルバスファ イル名で XYZ. EXE を指定するか , カレント ディレクトリを XYZ. EXE のあるディレクト リに移動させればいいのです。 MS-DOS プロンプトで実行させるには , C : *APP%F I LE*DOC*XYZ . EXE と打ち込んで , キーを押します。最 初の例の CD-ROM ドライプにある LHASAOI 7. EXE を実行するには , CD-ROM ドライプ が D ドライプなら , D : *TOOLS*LHASA*LHASA 017 . EXE と打ち込みます。 LHASA017. EXE が CD-ROM に存在すると いうこともあり , いつも実行するわけでは ないので問題にはならないかもしれません。 しかし , XYZ. EXE がよく使うツールだとし たらどうでしよう ? なおここでの説明は , ートカットファイルを作って実行すれ シ - ヨ ばいい , という次元の話とはちょっと違う ということをご了承ください。 XYZ. EXE という実行ファイルがどのディ レクトリに存在するのかということを , MS- DOS/Windows に教えてあげます。この作 業を , パスを設定するなどといいます ( パ スを通すなどともいう ) 。 バスの設定方法 まずは Windows 95 / 98 です。 C ドライプ のルートディレクトリに AUTOEXEC. BAT というファイルがあります。これをエディ タ ( なければメモ帳 ) で開いてみましよう。 なおメモ帳でファイルを開くときの「開く」 ダイアログボックスでは , 最初は拡張子が IXT のものしか見えないようになっていま す。いちばん下の「ファイル名の種類 : 」で 「すべてのファイル」を選びましよう。 PATH=C : %APP*F I LEDOC てメモ帳を終了してください。 らなければ以下のように記述して , 保存し という 1 行は見つかりましたか ? PATH= AUTOEXEC. BAT ファイルに 見つか ロバティ ] メニューを選択します。「システ ビュータを右クリックして表示される [ プ ールを使います。デスクトップのマイコン と同様 , AUTOEXEC. BAT は存在せず , ッ 最後に Windows 2000 です。 Windows Me を実行することができます。 トディレクトリがどこであっても XYZ. EXE を再起動すればパスの指定ができ , カレン さらに亟ボタンをクリックして W ⅲ dows を追加して一ボタンをクリックします。 ー C : %APP*FILE*DOC の値」欄の最後に 示される「変数の編集」ウインドウの「変数 択して [ ] ボタンをクリックします。表 数」の列に PATH という項目があるので , 選 たら , [ 環境 ] タブを開きます。そこに「変 ム設定ユーティリティ」ウインドウが開い ィリティ ] メニューを選択します。「システ す。その [ ツール ] → [ システム設定ューテ と「ヘルプとサポート」ウインドウが開きま ステム情報 ] メニューを選択します。する → [ アクセサリ ] → [ システムツール ] → [ シ います。スタートボタンから [ プログラム ] WindowsMe に用意されているツールを使 ても使われていない可能性があります ) 。 には , AUTOEXEC. BAT がありません ( あっ 次に W1ndows Me です。 Windows Me っても XYZ. EXE を実行できます。 ができ , カレントディレクトリがどこであ Wmdows 95 / 98 を再起動すればパスの指定 ほかのパス名との区切りです。これで , ( セミコロン ) を忘れないでください。 ; は , て , フ回設定するパス名の前に PATH= ほかの / ヾスー C : %APP%FILE*DOC します。 見つかったならば , その行の最後に追加

10. 月刊 C MAGAZINE 2001年4月号

主人公のキャラクタでは , ちょっとぐら いかすった程度では当たったことにはなら ないようにしたり , 敵の場合は多少当たり 判定の範囲を広くとると弾が当たりやすく なります。こうしておくとゲームの難易度 をプレイヤにやさしいほうにちょっと下げ ることができます。 WonderWitch で表示する絵は 8X8 ドット という単位になってしまうので , それらを 考えて , 当たり判定の範囲の大きさをキャ ラクタの種類によって変えるようにしてお 1 / * その方向へ移動するよう自機の座標を加減する * / / * 方向ボタンが押されていたら , / * 用意をする / * あるボタンが押されていたら弾を撃ち出す / * ボタン判定 * / void gamelnput(void) / * プレイヤからの入力処理 * / / * VSYNC 待ち / * 自機、敵機のキャラクタの移動 / * 背景の組み立てとスクロール void gameDraw(void) / * 1 回ぶんの画面を組み立てて表示 * / シューティングゲームの骨格 LIST きます。 / * ループ本体 * / void gameLoop ( void ) / * ループ本体 * / flagyarareta を True に / * 敵機が何かにぶつかったら , 敵機の flagyarareta を True に / * 自機が何かにぶつかったら、自機の / * 当たり判定 * / void gameExecute(void) / * ゲーム処理 * / ーする * / ーする * / / * 1 回ぶんの画面を組み立てて表示 * / do { / * このループが 1 回動くことでゲームがひとつ進む * / ) 曲 i 厄い gameCheckEnd( ) / * ゲームを終了させるかどうか * / gameExecute( / * ゲーム処理本体 * / gamelnput( / * プレイヤからの入力処理 * / gameDraw( ■重なったあとの処理 機の弾にぶつかった」 , 「自機が敵機にぶつ する処理」を呼び出します。逆に「自機が敵 う条件だったら「敵機に応じた得点を加算 もし「敵機が自機の弾にぶつかった」とい れる変数から判断します。 前述したキャラクタの構造体データに含ま どの種類のキャラクタがぶつかったかは , ものヘ反映させることをします。 次はそれぞれに場面に応じて , ゲームその キャラクタ同士が重なったのであれば , 遊びのアヒ かった」などゲーム終了の条件となるもの であれば , そのための処理を呼び出します。 たいがいすぐには終わらず , 爆発シーンな どを表示してからゲーム終了となるはずで す。そこで「ゲーム全体の状態」を判断でき るフラグ用変数を作り , その変数へ「ゲー ム終了作業中」という意味の値を入れてお きます。表示が終わるのを待ったあとに のフラグを確認して , ゲーム終了の処理を プログラムの全貎 呼び出すようにします。 通信対戦ケープルが必要になりますが , 携 です。 WonderWitch のカートリッジ 2 っと 次回は通信対戦について取り上げる予定 b サイトで公開する予定です。 プログラムについては C MAGAZINE の We となれば幸いです。今回作成したサンプル 処理をしています。本稿がその理解の一助 の単純なゲームシステムとは裏腹に複雑な このように , シューティングゲームはそ 終わりに ます。 組み合わせることでゲームを実現していき これ以外はここまで解説してきた手法を 機や敵機を登録するようにしていきます。 めたバッフアを用意し , そのバッフアへ自 キャラクタは「今表示している」ものを集 などを行います。 中で「画面を組み立てて描画」 , 「入力処理」 meLo 叩 () にあるループの部分です。この フレーム 1 回ぶんの作業を行うのは , ga きます。 ます。ここへ解説してきた処理を加えてい ードの基本的な構造は List 1 のようになり ログラムにするときがきました。ソースコ こまで紹介してきた方法をまとめてプ 遊びのレシピ fo 「 WonderWitch ぞお楽しみに 帯ゲーム機らしい遊び方ができます。どう 1 35