Designing Games with Game Maker
version
5.0(
Mark Overmars 著
|
|
|
|
ゲーム・メーカーを使ったゲーム設計
日本語初版:平成15年10月
Alberto
Palacios Pawlovsky 訳
桐蔭横浜大学・工学部・電子情報工学科
目次
Chapter 1 自分のゲームを作りたいの?................................................................ 7
Chapter 2 インストール............................................................................................... 9
Chapter 3 登録.......................................................................................................... 11
Chapter 4 グローバル・アイデア(概要)................................................................ 13
Chapter 5 一つの例の見てみましょう.................................................................... 15
Chapter 6 ユーザー・インターフェース................................................................... 17
6.1 Fileメニュー.......................................................................................................... 17
6.2 Edit
メニュー......................................................................................................... 18
6.3 Addメニュー......................................................................................................... 18
6.4 Windowメニュー................................................................................................... 19
6.5 Helpメニュー........................................................................................................ 19
6.6 リソース・エクスプローラ...................................................................................... 19
Chapter 7 スプライトの定義.................................................................................... 21
Chapter 8 サウンドとミュージック........................................................................... 23
Chapter 9 バックグランド......................................................................................... 25
Chapter 10 オブジェクトの定義................................................................................. 27
Chapter 11 イベント..................................................................................................... 29
Chapter 12 アクション................................................................................................. 35
12.1 移動・アクション................................................................................................... 35
12.2 main1のアクション................................................................................................ 38
12.3 main2のアクション................................................................................................ 40
12.4 制御...................................................................................................................... 41
12.5 描画アクション..................................................................................................... 44
12.6 スコアー関連のアクション................................................................................... 45
12.7 コード関連のアクション....................................................................................... 47
12.8 式と変数の使用................................................................................................... 48
Chapter 13 ルームの作成.......................................................................................... 51
13.1 インスタンスの追加............................................................................................. 52
13.2 ルームの設定...................................................................................................... 52
13.3 バックグランドの設定.......................................................................................... 53
Chapter 14 ゲーム配布.............................................................................................. 55
Chapter 15 アドバンス・モード.................................................................................. 57
15.1 Fileメニュー.......................................................................................................... 57
15.2 Edit
メニュー......................................................................................................... 59
15.3 Addメニュー......................................................................................................... 59
Chapter 16 もう少しスプライトについて................................................................... 61
16.1 自分のスプライトを作成する............................................................................... 61
16.1.1 File メニュー...................................................................................................... 61
16.1.2 Editメニュー...................................................................................................... 62
16.1.3 Transformメニュー............................................................................................ 62
16.1.4 Imagesメニュー................................................................................................. 63
16.1.5 Animationメニュー............................................................................................ 63
16.1.6 ストリップ.......................................................................................................... 64
16.2 個々のサブイメージの編集................................................................................. 66
16.3 アドバンスなスプライトの設定............................................................................ 67
Chapter 17 もう少しサウンドとミュージックについて............................................. 69
Chapter 18 もう少しバックグランドについて........................................................... 71
Chapter 19 もう少しオブジェクトについて............................................................... 73
19.1 深さ....................................................................................................................... 73
19.2 パーシステント・オブジェクト............................................................................... 73
19.3 親オブジェクト...................................................................................................... 73
19.4 マスク................................................................................................................... 74
19.5 情報...................................................................................................................... 74
Chapter 20 もう少しルームについて........................................................................ 75
20.1 アドバンス・設定.................................................................................................. 75
20.2 タイレッドなバックグランドの作成....................................................................... 76
20.3 ビュー.................................................................................................................... 77
Chapter 21 パス........................................................................................................... 79
21.1 パスの定義.......................................................................................................... 79
21.2 オブジェクトにパスの割り当て方........................................................................ 80
21.3 パス・イベント....................................................................................................... 81
Chapter 22 タイム・ラインス................ エラー! ブックマークが定義されていません。
Chapter 23 スクリプト.................................................................................................. 85
Chapter 24 データ・ファイル....................................................................................... 89
Chapter 25 ゲーム情報.............................................................................................. 91
Chapter 26 ゲームのオプション................................................................................ 93
26.1 グラフィックス・オプション.................................................................................... 93
26.2 解像度.................................................................................................................. 94
26.3 キー・オプション................................................................................................... 95
26.4 ロード・オプション................................................................................................ 95
26.5 エラー・オプション................................................................................................ 96
26.6 情報のオプション................................................................................................. 96
Chapter 27 速度の考慮.............................................................................................. 97
Chapter 28 ゲーム・メーカー言語 (GML)................................................................ 99
28.1 プログラム............................................................................................................ 99
28.2 変数...................................................................................................................... 99
28.3 代入文................................................................................................................ 100
28.4 式........................................................................................................................ 100
28.5 その他の変数.................................................................................................... 101
28.6 他のインスタンスの変数を参照する................................................................ 101
28.7 配列.................................................................................................................... 103
28.8 If文..................................................................................................................... 103
28.9 Repeat文............................................................................................................. 103
28.10 While文............................................................................................................... 104
28.11 Do文................................................................................................................... 104
28.12 For文.................................................................................................................. 105
28.13 Switch statement................................................................................................... 105
28.14 Break文.............................................................................................................. 106
28.15 Continue statement............................................................................................... 106
28.16 Exit文.................................................................................................................. 106
28.17 関数.................................................................................................................... 106
28.18 スクリプト............................................................................................................ 107
28.19 With文................................................................................................................ 107
28.20 コメント................................................................................................................ 108
28.21 GMLの関数と変数............................................................................................ 109
Chapter 29 計算........................................................................................................ 111
29.1 定数.................................................................................................................... 111
29.2 実数値の関数.................................................................................................... 111
29.3 文字列を扱う関数.............................................................................................. 112
Chapter 30 GML: ゲームのプレイ......................................................................... 115
30.1 移動.................................................................................................................... 115
30.2 インスタンス....................................................................................................... 117
30.3 タイミング............................................................................................................ 119
30.4 ルームとスコアー............................................................................................... 120
30.5 イベントの生成................................................................................................... 121
30.6 その他の変数と関数......................................................................................... 123
Chapter 31 GML: ユーザーとのやり取り............................................................... 125
31.1 ジョイスティックのサポート................................................................................ 127
Chapter 32 GML: ゲームのグラフィクス............................................................... 129
32.1 ウインドウとカーソル......................................................................................... 129
32.2 スプライトとイメージ........................................................................................... 130
32.3 バックグランド.................................................................................................... 131
32.4 タイル.................................................................................................................. 132
32.5 描画用の関数.................................................................................................... 133
32.6 ビュー.................................................................................................................. 137
32.7 遷移効果............................................................................................................ 138
32.8 スクリーンの再描画........................................................................................... 138
Chapter 33 GML: サウンドとミュージック............................................................. 141
Chapter 34 GML: Splash画面、score表、他のポップ・アップ........................... 145
Chapter 35 GML: リソース....................................................................................... 149
35.1 スプライト.................................. エラー! ブックマークが定義されていません。
35.2 サウンド.............................................................................................................. 151
35.3 バックグランド.................................................................................................... 152
35.4 パス.................................................................................................................... 153
35.5 スクリプト............................................................................................................ 154
35.6 データ・ファイル.................................................................................................. 154
35.7 オブジェクト........................................................................................................ 154
35.8 ルーム................................................................................................................ 155
Chapter 36 GML: ファイル、登録、プログラムの実行........................................ 157
Chapter 37 GML:マルチプレイヤー・ゲーム........................................................ 161
37.1 接続を設定する................................................................................................. 161
37.2 セッションの作成、セッションへの参加............................................................ 162
37.3 プレイヤー.......................................................................................................... 163
37.4 共有データ......................................................................................................... 163
37.5 メッセージ........................................................................................................... 164
Chapter 38 GML:DLLの使用................................................................................ 167
コンピュータ・ゲームで遊ぶのはとても楽しいことです。しかし、それ以上楽しいことは、自分のゲームを設計して人がそれで遊んでもらうことです。残念ながら、コンピュータ・ゲームの作成は簡単な作業ではありません。現在の市販のコンピュータ・ゲームの開発は2,3年間、および10人から50人の設計チームを必要し、予算は億単位です。また、設計チームのメンバーはプロ(ソフトウェア、音楽、グラフィックの専門家)のものばかりです。
これは、自分のゲームが作れないことを意味するのでしょうか。幸いに、そうではありません。もちろん、自分のQuakeやAge of
Empiresのようなゲームを数週間で作成することはできません。そこまで狙わなくても、テトリスやパックマンやスペース・インベーダーのようなシンプルでとても楽しいゲームは簡単に作成できます。しかし、この場合でも、グラフィックや音声やユーザーとの対話を操るためにプログラミングの技能は欠かせません。しかし、そこでゲーム・メーカーが登場しました。ゲーム・メーカーはゲーム作りを簡単にするために作成されたものです。プログラミング知識は不要です。マウスのドラッグ・アンド・ドロップの使いやすいインターフェースが自分のゲームの作成を簡単にします。絵や画像やスプライト(動きのある画像)、サウンドなどを挿入し、使うことができます。ゲームの部品や主人公を定義して、その動作の指定が容易にできます。動きのあるバックグランドのインパクトのある画面の使用も可能です。また、フル制御のようなより高度なことを行いたい場合は、ゲーム・メーカーにはシンプルなプログラミング環境も用意されています。
ゲーム・メーカーのゲームは2次元のものです。だから、Quakeのような3Dゲームの作成はできません。しかし、気を落とさないで、Age of EmpiresやCommand & ConquerやDiablo等の有名なゲームは3Dのものに見えますが、2Dスプライト技術を使用したものです。しかも、2次元のゲーム作りはとても簡単で早いです。
ゲーム・メーカーの最も大きな特徴は、その使用が無料です。また、作成されるゲームには制限がありません。作者のロゴ表示等もないし、作成したゲームも販売できます。詳細についてラインセンスをご参考願います。
この本は、ゲーム・メーカーおよびこれを使用したゲーム作りについて述べています。しかし、ゲーム・メーカーを使用しても、ゲーム作成は平凡なことではありません。プレイの仕方やグラフィックスやサウンドやユーザーとのやりとりなどの多数の事柄を考慮に入れなければなりません。簡単なゲームの作成からスタートすれば、ゲーム作りはとても楽しいことが分かるでしょう。次のウエーブ・サイトも見ていただきたい。
また、その中のフォーラムには多数のゲームやアイデア、ヘルプ等が公開されています。この情報をうまく活用することで近い将来にあなたもマスター・ゲームの作者になるでしょう。楽しもう!
インストールは既に済んでいると思いますが、そうではない場合は、以下はインストールについて触れます。ただ単に、gmaker.exeを実行して、画面の指示に従ってください。インストール先はどこでもよろしいのですが、デフォルトの場所にした方がよいと思います。インストールが完了したら、起動メニューのprogramには、ゲーム・メーカーを起動するものやマニュアルなどアクセス可能にするGameMaker新項目が追加されます。
ゲーム・メーカーの初起動でシンプルかアドバンスかの選択モードを問いする画面が表示されます。経験の浅いか初心者の場合は、シンプル・モードをお勧めします(Noを選択)。このモードではオプションの一部分が表示されません。アドバンスモードにの切り替えはFileメニューでいつでも行えます。
インストール・フォルダー(デフォルトC:/Program
Files/Game_Maker5/)には、次のフォルダーがあります。
・
examples:例題用のゲームを含んでいて、チェックや試作に自由に使用できます。
・
lib:アクション関係のライブラリを格納します。他のアクションライブラリを使用したい場合はここにおいて下さい。
・
sprites:自分のゲームの作成に使用できる(動きのある)スプライトのコレクションです。ゲーム・メーカーのインストールで少数のものしかインストールされませんが、ゲーム・メーカーのサイト(http://www.gamemaker.nl/)からその他のリソース・パックをダウンロードができます。
・
backgrounds, sounds:同様なフォルダで、バックグランド(下敷きや壁紙のようなもの)画像、およびサウンドを含んでいます。
ゲーム・メーカーの使用には、モダンなPentiumのPC(パソコン)およびWindows 98、NT、2000、Me、XPあるいはこれらの最新のOSが必要です。スクリーンの解像度は最低800x600で、カラー階調は65000(16ビット)です。DirectXも必要です。ゲームを設計するときは少なくとも32MBが必要です。ゲームの実行に必要なメモリはゲームによって異なります。
ゲーム・メーカーの最も大きな特徴は、その使用が無料です。また、作成されるゲームには制限がありません。作者のロゴ表示等もないし、作成したゲームも販売できます。詳細についてラインセンスをご参考願います。しかし、登録をお勧め致します。登録すると作成者欄のロゴ表示が無くなりますし、登録者のためにゲーム・コンペティションも用意していく予定です。
登録費は15米国ドールか15ユーロです。登録の仕方は幾つかあります。最も簡単なのは、クレジット・カードを使用した暗号化されたオンライン登録、またはPayPal口座での登録です。もう一つの方法は、我々の銀行口座への振り込みです。さらに、キャッシュのお送りも可能です。その詳細は、
www.gamemaker.nl/registration.html
のサイトでご覧になれます。
登録を行うときは、上記のサイトを使用するか、HelpメニューのRegistrationを使って下さい。後者の場合は表示されるフォームの下にRegistrationのボタンがあり、これを押すと、該当のウェブ・ページに入りオプションを選択することができます。
登録後、電子メールで登録キーが送られます。上記のように、HelpメニューのRegistrationを選択して、フォームのEnter Keyを押して、送られた情報を該当欄に記入してOKを押してください。これでプログラム登録が完了です。
ゲーム・メーカーの機能などを詳細に触れる前に、その操作の基本的なアイデアを掴むために、まずこのプログラムの使用を体験しましょう。ゲーム・メーカーで作成されたゲームはルームといわれる幾つかの画面をもちます(ルームは平らのものですが、疑似3Dのグラフィクスが使用できます)。ルームにはゲームの主人公などを配置します。これらのものをゲーム・メーカーではオブジェクトといいます。古典的なオブジェクトには、壁、移動するボール、主人公、モンスターなどがあります。この中では、壁のようなものは静的で特に何もしません。しかし、その一方、主人公のように移動したり、物事(プレイヤーの操作:マウス、ジョイスティック、キーボード)や他のオブジェクトに反応したりするオブジェクトもあります。たとえば、主人公はモンスターにぶつかると死ぬというようなことが挙げられます。オブジェクトは、ゲーム・メーカーで作成されるゲームの最も重要なものです。これらについて少し触れておきましょう。
まず、オブジェクトが画面上に写るために外観に当たるイメージを要します。これらのイメージはスプライトという。スプライトは、一つのイメージだけでなく場合によっては、動きを表現するために幾つかのイメージで構成されています。こうすることによって、オブジェクトが動いていることや、ボールが転がっていることや、スペース船が爆発すること等に見せかけることができます。そして、ゲーム中にオブジェクトのスプライトを変えたりすることもできます(移動方向に合うものにスプライトを変える)。ゲーム・メーカーでは、自分のスプライトを作成することができ、あるいはロードする(読み込む)こともできます(例:アニメイテッドGIFなどから)。
オブジェクトに起こることをイベントといいます。イベントの発生に対してオブジェクトがアクションすることができ、数多くのイベントに対してオブジェクトに色々なアクションの指定ができます。たとえば、オブジェクトが生成されたときクリエション・イベントが発生します(同オブジェクトの重複が可能ですので、その一つの発生のときこのイベントが起こります)。他にも、ボールの作成のときに、そのイベントに動きを与えると、ボールが出現した後動き出します。二つのオブジェクトがぶつかるときは、コリーション(衝突)のイベントが発生し、(衝突した)ボールがストップしたり、方向を変えることにしたりすることができます。また、サウンドを流すこともできます。このために、ゲーム・メーカーではサウンドの定義ができます。プレイヤーがキーボードのキーを押すと、キーボード・イベントが発生し、オブジェクトは方向の変えるようなアクションをすることができます。これで、基本的なゲーム作りのアイデアを掴んだと思います。あなたが作成する各オブジェクトにイベント毎にアクションが指定でき、そのオブジェクトの動作を定義することができます。
オブジェクトの定義後、オブジェクトの活動が行われるルームの定義が来ます。ルームはレベル毎に使ったり、異なる場所の表示には使用します。ルームからルームへの移動に対応するアクションがあります。ルームはバックグランド(下敷き用の画像)をもちます。これは、単に色の指定した枠か画像の一つです。これらのバックグランドはゲーム・メーカーで作成でき、ファイルからロードすることもできます(バックグランドの役割が多数にわたるのですが、ここではゲームをきれいにするものを考えてください)。そのあと、オブジェクトをルームに配置します。同じオブジェクトを複数使って、異なる場所に配置することができます。このようにすれば、壁オブジェクトを一つ定義して、ルームのあちこちに使用できます。同じモンスター・オブジェクトも多数使用できます。ただし、この場合はその動作が同じでなければなりません。
これで、ゲームを実行するための準備は終わりです。最初のルームが表示され、オブジェクトが出現し、クリエション・イベントに対応するアクションが行われます。オブジェクトがコリーション・イベントによってお互いに反応したり、またはプレイヤーのキーボード・イベントやマウス・イベント等に反応します。
結局、次の事柄(通常リソースという)が重要な役割を果たします。
実は、パス、スクリプト、データ・ファイル、およびタイム・ラインと呼ばれるリソースもあります。これらは複雑なゲームに必要です。ゲーム・メーカーがアドバンス・モードのときのみ、これらのリソースが表示されます。これらのリソースは後のアドバンズ章で説明します。
ここでまず簡単な例を用いて作成の過程をみて見ましょう。ゲーム・メーカーがシンプル・モードで起動されたと仮定します。まず第1ステップでは、作りたいゲームを説明します(必ずこれを先にやっておいてください。最終的に時間の省略につながります)。ここで作るゲームはとても簡単です。一つのボールは周辺の壁にぶつかりながら移動します。プレイヤーがボールを追ってマウスでその上にクリックすることを目的にします。成功した場合は、1点を収得します。
この説明で分かるようにボールと壁の二つのオブジェクトが必要です。スプライトもボール用と壁用の二つ必要です。最後に、ボールをマウスでクリックしたとき、サウンドが聞こえるようにします。また、一つのルームだけ使用します(自分自身でこのゲームを作りたくない場合は、touchtheball.gmdの名前でExamplesフォルダからロードすることができます)。
まずスプライトを作っておきましょう。Add(追加)メニューからAdd Spriteを選択しましょう(ツール・バーの該当ボタンを使用してもよい)。フォーム(小さなウインドウ)が現れ、Nameの欄にwallをタイプイン(記入)します。フォームのLoad Spriteボタンを押して壁に合うイメージを選択します。そうしたら、フォームを閉じてください。同様にして、ball名のボールのスプライトを作ってください。
次に、サウンドを作りましょう。Addメニューから今度Add Soundを選択します。前のと異なるフォームが現れます。サウンドに名を付けて、Load Soundでサウンドを選択して下さい。選択のとき、プレイ・ボタンでサウンドが再生できますので、気に入ったものを選びましょう。そうしたら、フォームを閉じてください。
次のステップは、二つのオブジェクトの作りです。まず、壁のオブジェクトを作りましょう。再び、AddメニューからAdd Objectを選択します。ここまで出てきたフォームよりはるかに複雑なフォームが開いてきます。その左側にオブジェクトの一般的な情報が表示されます。オブジェクトに(wall)の名前を付けて、スプライト欄のドロップ・ダウン・メニューから壁のスプライトを選んで下さい。壁は固体であるため、Solidのボックスにチェックを入れます。ここまでと同じようにもう一つのオブジェクトを作成して、ballの名前を与えて、そのスプライトを指定して下さい。ボールは「固体」にしません。ボールが動くため、その動作を定義します。真ん中当たり何も入っていないイベント・リストがあります。その下にAdd Eventボタンがあります。このボタンを押すと、選択できるイベントのリストが表示されます。その中のcreation(クリエション)イベントを選択します。このイベントがイベント・リストに追加され、これに対応させられるアクションはフォームの一番右の端にグループ毎に出ています。moveグループから八つの赤矢印ボタンをその左隣の白枠(アクション・リストという)にドラッグして下さい。これでボールのオブジェクトは指定された方向に移動できるようになります。アクションのアイコンをアクション・リストにドラッグすると、詳細設定用のフォームが表示されます。このフォームで移動方向等の設定ができます。周辺の八つの矢印をクリックして選択して下さい。こうすることで、オブジェクトはその八つの方向の中から一つをランダムに選んで動きます。移動速度は8となっていますのでそのままにします。この設定のフォーム(ダイアログという)を閉じます。この設定でボールが生成された時点から動き出します。次に、ボールが壁にぶつかるときの動作を定義します。このため再びAdd Eventボタンを押して、コリーション・イベント(ぶつかる矢印のイベント)のドロップ・メニューから壁のオブジェクト(wall)を選択します。このイベントのために、弾む(bounce:バウンス)のアクションが必要です(アクションの上にマウスを載せると簡単な説明が表示されます)。最後に、ユーザーが左のボタンをボールの上にクリックしたときの動作を定義しなければなりません。キーのイベント(コリーションのすぐ下)を選択して、マウスの左ボタンを選択します。このイベントに対しては幾つかのアクションを指定します。最初のアクションはmain1のグループにあるサウンドをプレイするものです。もう一つはscoreグループのスコアー(点数)を更新するものです。また、ヒットの後ボールを他の場所に移動させるアクションです(このアクションはクリエション・イベントで使用したものと同じです)。サウンド・アクションに対応するサウンドを選択します。スコアー・アクションの値を1にして、Relative(相対)ボックスをチェックします。これで現在のスコアーには1が加算されます(設定に誤りがあった場合はアクションをダブル・クリックして再設定を行ってください)。
これでオブジェクトの設定が完了します。残りは、ルームの定義です。再びAddメニューで新しいルームを追加してください。開いてくる画面の右には空のルームが表示されます。その左にタッブ別でバックグランドの設定、ルームの幅と高さのような広域的な特性の設定、ルーム内にインスタンスの配置設定があります。左下にオブジェクト欄があり、ポップアップ・メニューでオブジェクトを選択することができます。オブジェクトを選択した状態で、そのオブジェクトを右のルームにマウスの左クリックで配置することができます。また、右クリックでオブジェクトが削除できます。wallオブジェクトを用いてルームの周辺に壁を作ってください。最後にルームに1個か2個のボールを配置してください。これで準備完了です。
それでは、ゲームをテストしてみましょう。Runのボタンを押して起こることを観察しましょう。誤りがない場合は、ボールが移動します。ボールの上にクリックしてみて下さい。ゲームをストップするにはEscのキーが使えます。これで更新・改善などが可能です。
おめでとう、君の最初のゲーム作成が終わりです。以下ではゲーム・メーカーについてもう少し学んで行きます。
ゲーム・メーカーを起動するときは次の画面が現れます。
(実は、この画面はゲーム・メーカーのシンプル・モードの画面ですアドバンス・モードにはその他の項目が表示されます。詳細は第14章でご覧下さい。)画面の左にはゲームのリソースが出ています。上から、スプライト、サウンド、バックグランド、オブジェクトおよびルームがあり、次いでゲームの情報とゲームのオプションが並んでいます。一番上に、ワープロなどでよく見かけるメニューとその下にあるツールバーが見られます。この章では、メニューの項目やボタンなどを説明します。その他の章ではこれらの幾つかをさらに詳細に説明します。以下の説明でも分かるのですが、同様な操作がメニュー項目の選択でも、ボタンでも、リソース上のマウスの右クリックでも可能です。
Fileメニューで通常の「ファイルを開く」や「保存」などがありますが、特別なものには、
・
New:新しいゲームを作成するときこのコマンドを使います。もし、そのとき開いているゲームが更新された場合はそのゲームを保存するか否かが問われます。ツ−ル・バーの白い紙のようなボタンでも同様のことができます。
・
Open:ゲームを開きます。ゲーム・メーカーのファイルは.gmd拡張子をもっています。ツール・バーの開いているフォルダーはこの機能を持つボタンです。また、ゲームをゲーム・メーカーのウインドウ上に引っ張ればゲームを開くことができます。
・
Recent Files:この項目で最近使用したファイルを再び開くことができます。
・ Save:現在の名前でゲームの設計ファイルを保存します。名前が付けられていないとき、名前が要求されます。ファイルが更新されたときのみこの項目が有向です。この項目用のボタンもあります。
・ Save As:別名でゲームの設計ファイルを保存します。この項目でファイル名が要求されます。
・ Create Executable:他人に配布できるゲームのバーションを作るときはこれを使います。この項目の使用で独立に使用できる(スタンド・アロン)ゲームが作成されます。実行可能な形式のゲームが作成されます。ゲーム配布について第14章でより詳細に述べます。
・ Advance Mode:この項目を選択しますと、ゲーム・メーカーはシンプル・モードとアドバンス・モードとの間の切り替えを行います。アドバンス・モードで他の選択やリソースが使用可能になります。
・
Exit:自明でしょう。これを選択しますとゲーム・メーカーが終了します。現在開かれているゲームが更新されていれば、そのセーブが行うか否かが問われます。
編集メニューは現在選択されているリソース(オブジェクト、スプライト、サウンド等)またリソースのグループに関連のあるコマンドを含んでいます。リソースのタイプによって使えないコマンドがあります。
・
Insert resource:現在選択されているリソースの前に同タイプのものを新作します。挿入されるリソースの特徴(プロパティ)を設定するためのフォームがが開いてきます。以下の章でその詳細について述べます。
・ Duplicate:現在のリソースをコピーして追加します。フォームが現れ、リソースが変更できます。
・ Delete:選択されているリソース(またはグループ)を削除します。これは元に戻すことができないため、注意しましょう。もちろん、該当する注意が表示されます。
・ Rename:リソースに新しい名前を付きます。リソースのプロパティ・フォームでもこれが行えます。また、リソースを選択してその名前をクリックすれば、同じことができます。
・ Properties:プロパティを編集するためのフォームを表示させるにはこのコマンドを使います。プロパティ・フォームはメイン・フォーム内に表示されます。つまり、幾つかのが同時に編集できます。プロパティ編集がリソースの上にダブルクリックでも可能です。
これらのコマンドを次の別の方法でも与えられます。リソースかリソース・グループ上に右クリックすると、該当のポップアップメニューが表示されます。
各タイプのリソースをこのメニューで追加することができます。これらの各々にはツール・バーのボタンもキー・ショットカットもあります。
メイン・フォームのプロパティ・ウインドウを扱うためのコマンドはこのメニューにあります。
・
Cascade:ウインドウのすべてが見えるようにカスケードに並べます
・ Arrange Icons:アイコン化されたウインドウ・プロパティを整理します(メイン・フォームをリサイズするとき便利)
・ Close All:変更を保存するかを伺いながら、すべてのプロパティ・ウインドウを閉じます
ヘルプに関連の役立つコマンドには次のものがあります。
・
Contents:この資料のオンライン・バーションにアクセスできます。
・ How to use help:ヘルプの使用についてのヘルプ情報が表示されます。
・ Registration:ゲーム・メーカーは無料で使用することができるが、登録をお薦めします。登録するとナッグ・画面が消え、ゲーム・メーカーの開発に貢献できるようになります。この項目で登録の仕方に関する情報が表示されます。登録後、登録のキーを用いて登録情報の記入が可能です。
・ Web site:ゲーム・メーカーのウエーブ・サイトに接続します。そこで最新情報やゲームのコレクションやリソースなどが公開されています。このサイトを一ヶ月に一回見ていただきたいです。
・ Forum:ゲーム・メーカーの情報交換のフォーラムに接続します。そこで質問したり、情報を得たりすることなどができます。
・ About Game Maker:ゲーム・メーカーのバーションについて情報を表示します。
メイン画面の左にはリソース・エクスプローラが出ています。ツリーのような階層でゲームのリソースが見られます。ウインドウのエクスプローラと同様なものです。項目の前の四角にプラス(+)があるとき、それをクリックすれば項目内のリソースが見られます。マイナス(−)に変わった四角を再びクリックすれば項目のみ表示されます。項目内のリソースをワン・クリックで選択した後、その名前が変えられます。しかし、項目名が変えられません。リソース上をダブル・クリックすると、そのプロパティを変更することができます。右ボタンのクリックでもEditメニューのコマンドが起動できます。ドラッグで項目やグループの位置が変えられます。もちろん、妥当なところに移動しないとだめです(駄目な例:サウンドをスプライトに移動する)。
スプライトは、ゲームのオブジェクトの外観です。スプライトは、ドロー・ソフトで作成された一つのイメージか、あるいは動きを表現するイメージの集まりです。たとえば、次のイメージは右に移動するパックマン用のスプライトです。
ゲームを作るときは、まずゲーム用のスプライトを集めます。ゲーム・メーカーのサイトでは通常のスプライトとアニメイテッド(動きのある)スプライト両方が提供されています。その他のスプライトはインターネットで探すことができます。通常アニメイテッドgifのものが多いです。
スプライトを追加するときは、AddのメニューからAdd Sprite の項目を使用します。また、ツール・バーの該当ボタンを使います。このとき、次のフォームが現れます。
一番上にスプライトの名前を記入します。スプライト(他のリソースも)すべてが名前をもっています。できるだけスプライトの役割を分かりやすくする名前を与えましょう。また、すべてのリソースには異なる名前をもたせましょう。決まりではないが、英字で始まる英数字、アンダー・バー( _ )からなるもののみをスプライト(他のリソース)の名付けに使いましょう。スペース(空白)を極力に使わないで下さい。これは、特にコードを用いるときは重要となります。
スプライトをロードするためにLoad Spriteのボタンをクリックします。標準のダイアログが表示され、そこでロードしたいスプライトを指定します。ゲーム・メーカーは幾つかの種類のグラフィクス・ファイルをロードすることができます。アニメイテッドgif型ファイルをロードするときは、このファイルのサーブ・イメージがスプライトを構成します。スプライトがロードされると最初のイメージが右の枠に表示されます。多数のイメージがある場合は、矢印のキーでこれらを眺めることができます。
Transparentのチェックボックスは、スプライトのバックグランドが透明に設定するかを表します。ほとんどのスプライトのバックグランドは透明です。このバックグランド色はイメージの一番左下のピックセルで決まります。このため、その他のピクセルがこの色を持っていないことを確認しなければなりません(gifイメージが自分の透明色を定義しますが、これはゲーム・メーカーでは使用しません)。
Edit
Spriteのボタンでスプライトの編集もでき、新しいスプライトの作成もできます。作成や編集についての詳細については第14章に述べます。
ほとんどのゲームはサウンド効果およびバックグランド・ミュージックを使用します。役に立つ幾つかのサウンドはゲーム・メーカーのサイトにあります。インターネットでその他数多くのサウンドが手に入れられます。
ゲームにサウンド・リソースを追加するときは、AddメニューのAdd Soundの項目を使用します。または、ツール・バーの該当ボタンを使います。この項目の選択で次のフォームが現れます。
サウンドをロードするためにLoad Soundのボタンを押します。ファイル選択用のダイアログが表示され、サウンド・ファイルの選択ができます。サウンド・ファイルはタイプがwave型およびmidi型二つあります(MP3ファイルについては第17章を参照)。Waveファイルは短いサウンド効果に用います。このファイルは、大きなメモリを使用するが、迅速に再生されます。サウンド効果にこのタイプのファイルを使用しましょう。Midiファイルは異なる形でミュージックを表現します。このため、waveファイルより小さなメモリを使用します。しかし、その用途はバックグランド・インストルメンタル・ミュージックに限られています。また、サウンド効果(waveサウンド)と異なって、ある時点で一つのmidiサウンドしか再生できません。
ミュージック・ファイルをロードすると、その種類と時間の長さが表示されます。プレイ・ボタンでサウンドの再生ができます。Save Soundを使えば、現在のサウンドをファイルに保存することができます。このボタンが重要はないが、損失した元のサウンドのときに必要になります。
三番目の基本的なリソース・タイプはバックグランドです。通常、バックグランドは、ゲームのルームの下敷きに使用できる大きなイメージです。ほとんどの場合は、タイルのようにマス目を埋めるようなものです。この場合は、画面はパターンで埋めることができます。タイルの幾つかがゲーム・メーカーのサイトにあります。インターネットでその他数多くのものがあります。
ゲームにバックグランド・リソースを追加するとき、AddメニューのAdd Background項目を選択します。また、ツール・バーの該当ボタンを押します。この項目を使用すると、次のフォームが表示されます。
バックグランド・イメージをロードするには、Load Backgroundのボタンを押します。ゲーム・メーカーは色々なイメージのフォーマートをサポートします。ただし、アニメイテッド・イメージが使用できません。Transparentのチェックボックスでバックグランドの(半)透明度が指定できますが、通常バックグランドではこれをチェックしません。使用したとき、透明色はイメージの一番左下のピクセルの色に設定されます。
Edit Backgroundのボタンでバックグランドの変更、あるいは新作成ができます。詳細について第18章をご覧ください。
ここまで、ゲームにはイメージやサウンド等を追加できても、これら自身は何もしません。そこで、ここではゲーム・メーカーの最も重要リソースであるオブジェクトについて述べます。オブジェクトは、ゲームの「役」であり、動作するものです。オブジェクトを見えるものにするために外観としてスプライトが割り当てられます。オブジェクトはイベントに反応できるために動作するものになっています。バックグランドを除けばゲーム内に見えるものはすべてオブジェクトです(明確に言うと、オブジェクトのインスタンス(オブジェクトの一つの出現)です)。キャラクターや、モンスターや、ボールや、壁等は皆オブジェクトです。もちろん、ゲームの場面を制御するような見えないオブジェクトもあります。
スプライトとオブジェクトの違いをよく理解しましょう。スプライトは、動作しない、ただ単に(アニメイテッド)イメージです。オブジェクトの外観はスプライトですが、オブジェクトが動作可能なものです。オブジェクト無しでゲームが作れません!
オブジェクトとインスタンスの違いも理解していただきたいです。オブジェクトはモンスターのようなゲームのエンティティ(主役など)を定義します。ゲームには、このオブジェクトの多数のインスタンス(出現)があり得ます。インスタンスについて語るときは、オブジェクトの特定のインスタンスのことを意味します。オブジェクトについて語るときは、すべてのインスタンスのことを意味します。
ゲームにオブジェクトを追加するために、AddのメニューからAdd Objectを選択します。すると、次のウインドウが現れます。
これは少々複雑です。左にはオブジェクトの一般的な情報があります。真ん中にオブジェクトに起こり得るイベント・リストがあります。詳細について次の章を見てください。右には、オブジェクトの行えるアクションがあります。これについては第12章に述べます
いつもの通りオブジェクトにも名前を与えてください。名前を与えた後、オブジェクトのスプライトを指定します。このため、スプライトの欄に左クリックするか、その欄の隣にあるメニュー・ボタンを使用します。すると、使用できるスプライトのメニューが現れます。そこからオブジェクトに対応させたいスプライトを選びます。スプライト欄の下に二つのチェックボックスがあります。Solidの名札のものは、壁のような固体を指します。固体であるものとの衝突と、固体でないものとの衝突とは、その扱いは違います。この詳細について次の章を見てください。Visibleは見えるものを意味します。明らかに、ほとんどのオブジェクトは可視です。しかし、場合によっては透明のものが便利です。たとえば、モンスターの通り道に使用できます。透明のオブジェクトは他のオブジェクトにぶつかるとき、およびイベントに反応します。
ゲーム・メーカーはイベント・ドリブンというアプローチを用いています。つまり、いずれの場合でもオブジェクトのインスタンスはイベント(起こったことを知らせるメッセージのようなもの)をゲットします。インスタンスはこのメッセージに反応してアクションを行います。オブジェクト毎に、どのようなイベントにどのように反応してアクションするのを設定しなければなりません。複雑に聞こえるが、実は簡単に行えます。まず、ほとんどのイベントに対してはオブジェクトが何も反応しなくててもよいのケースが多いです。対象になるイベントに対しては、ドラッグ・アンド・ドロップ操作で該当するアクションを指定することが容易にできます。
オブジェクトのプロパティ・ウインドウ(下図を参照)の真ん中にオブジェクトが反応しなければならないイベント・リストがあるいます。このリストにAdd Eventのボタンでイベントを追加することができます。このボタンを押しますと、選択できるイベントが現れます。項目によってサブメニューの選択も可能になります。たとえば、キー・ボードのイベントでは対象のキーを選択しなければなりません。これらは異なるイベントです。この次には、完全なリストと説明を述べます。図の暗くなっているイベントは現在編集中のものです。対象のイベントを変えたいときは、イベントの上に(左)クリックします。その右に小さなアイコンで表示されているのは、このイベントに対応するアクションです。ウインドウの一番右にはこれらのアクションはタッブ付きページで分類されています。次の章ですべてのアクションについて述べ、これらが何をするかを説明します。イベントとアクションの間にアクション・リストがあります。このリストには現在のイベントのとき行うべきのアクションが表示されます。アクションを追加するときは、ウインドウの右からアクションをマウスでドラッグしてこのリストに引っ張ります。リストに簡単な説明と一緒に並べられます。アクションを追加しますと、その設定が要求されます。これについても次章で述べます。幾つかのアクションを追加すると、図のような状況になります。
その他のイベントに同様にアクションを追加することができます。イベントを選択するとき、そのイベントを左クリックで選びます(ボタンが暗くなります)。そして、そのイベントにアクションを追加します。
リストにあるアクションの位置がドラッグ・アンド・ドロップで変えられます。<Ctrl>キーを押したままアクションをドラッグすると、そのアクションがコピーされます。オブジェクト同士のアクション・リスト間のドラッグ・アンド・ドロップも可能です。アクションの上にマウスを右クリックすると、メニューが現れ、アクションの削除(<Del>キーでも可能)や、コピーやペストなどが施行できます。マウスをアクションの上に移動して止めると、アクションの説明が表示されます。アクションの詳細については次の章で述べます。
現在のイベントと関連のアクションすべてを削除するには、Deleteボタンを使用します(アクションのないイベントは、オブジェクト・プロパティを閉じるときに自動的に削除されます)。イベントを変えたいときは、Changeボタンを押して、他のイベントを選択します(ただし、既に定義されているイベントを再び選択することができません)。
上記に説明したようにイベントを追加するときは、Add Eventを押します。このボタンを押すと、次のポップ・アップ・フォームが現れます。
ここから、追加したいイベントを選びます。イベントによっては、更にサーブ・メニューを表示するものがあります。以下ではこれらのイベントを説明します(通常、この中から少数しか使わないことを覚えましょう)。
Createイベント
このイベントはオブジェクトが生成されるときに発生します。通常、オブジェクトに動かさせるためかそのインスタンスの変数を設定するために用います。
Destroyイベント
オブジェクトが破壊されるとき、このイベントが発生します。厳密にいうと、インスタンスが破壊される寸前にこのイベントが発生します。つまり、このイベントが発生するときは、まだ対象のインスタンスが存在しています。このイベントがそんなに使われないが、他のオブジェクトの生成やスコアーの変更に使用されます。
Alarmイベント
各インスタンスは8つのアラーム・クロックが使えます。これらのアラームは幾つかのアクションでスタートさせることができます(次章を参照)。スタートされるとアラームのクロックは0までステップのカウント・ダウンを始めます。0になると、アラーム・イベントが発生します。アラーム・クロックのアクションを設定するために、まずアラーム・クロックをメニューで選択します。アラーム・クロックはとても便利です。色々な物事が発生するように設定できます。たとえば、モンスターに20ステップ毎に方向をアラーム・クロックで変えさせます(このとき、イベントの何れかのアクションが再びアラーム・クロックを設定しなければなりません)。
Stepイベント
ステップ・イベントはゲームのステップ毎に発生します。このイベントに常に行われるアクションが設定できます。たとえば、一つのオブジェクトがもう一つに付いていくことのために、後者の方向を前者に追跡するように設定できます。しかし、これを使うには気を付けましょう。数多くのインスタンスをもつオブジェクトのステップ・イベントに複雑なアクションをおくと、ゲームが遅くなるおそれがあります。厳密に言うと、三つのステップ・イベントがあります。通常、デフォルトのステップしか使いませんが、メニューを用いれば開始ステップのイベント、および終了ステップ・イベントも選択できます。開始ステップのイベントは、各ステップの開始時に実行され、他のイベントの前に実行されます。通常のデフォルトのステップ・イベントは、インスタンスが新位置に配置される前に実行されます。終了ステップのイベントでは、ステップの終わり、つまり画像の再描きの前に実行されます。このイベントは、オブジェクトの方向にあわせてそのスプライトの変更に使います。
Collisionイベント
二つのインスタンスが衝突する(そのスプライトが重なる)と、コリーション・イベントが発生します。厳密に言うと、各インスタンスに一つの衝突、つまり二つのコリーション・イベントが生じます。インスタンスはこのイベントに反応できます。このために、イベントのメニューからコリーションに反応するオブジェクトを選択して、リストにそのアクションをおきます。
インスタンスが固体のものに、およびそうでないものにぶつかるときに起こることは異なります。まず、コリーション・イベントにアクションがないと何も起こりません。インスタンスは、ぶつかったものは固体であっても移動を続きます。コリーション・イベントにアクションがあると、次のことが起こります。
他方のオブジェクトは固体であれば、インスタンスが衝突前の位置に戻ります。そして、イベントが実行されます。最後にインスタンスは新しい位置に移動されます。つまり、イベントで方向が変えられることであれば、インスタンスが壁にぶつかると、壁にはねて方向を変えます。方向を変えてもぶつかるものがいれば、事実上インスタンスが現在の位置に止まります。
他方のオブジェクトは固体でないときは、インスタンスは衝突前の位置に後退しません。現在の位置でイベントは実行されます。また、コリーションの最チェックもありません。よく考えると、これは当然のことです。他方のオブジェクトは固体ではないためその上に通ります。イベントはこれが行われていることを知らせます。
コリーション・イベントの使用は多数です。たとえば、インスタンスは壁にはねたり、ものを弾丸で壊したりすることなどができます。
Keyboardイベント
プレイヤーがキーを押すと、該当オブジェクトのすべてのインスタンスにキーボードイベントが起こります。キー毎にイベントがあります。キー・イベントのメニューでキーを選んで、リストにそのキーに割り当てたいアクションをドラッグします。もちろん、通常少数のオブジェクトに少数のキー・イベントを割り当てます。キーが押されている限りステップ毎に一つのキー・イベントが生じます。特別なキー・イベントが二つあります。一つは<No key>です。これはステップ毎にいずれのキーが押されていなければ生じます。もう一つは、<Any key> といい、いずれのキーが押されたときに発生します。ところで、プレイヤーが多数のキーを同時に押すと、各々のキーに対応するイベントが発生します。なお、テンキーのキーに対応するイベントは、<NumLock>が押されているときだけ有効です。
Mouseイベント
インスタンスのマウス・イベントは、マウスのカーソルがインスタンスのスプライトの上にあるときに発生します。押されるボタンによって、右、左、真ん中のボタン、あるいはボタン無しのイベントがあります。これらのイベントはマウスがインスタンスの上にある限り各ステップに生じます。マウスのボタンを押すとき、またそのときにのみ該当のイベントが生じます。同様に、マウスのボタンを解放するときにのみ該当イベントが生じます。プレイヤーがインスタンスのないところにマウスを押してもイベントは起こりません。それでも、時々いずれのマウス・クリックに反応しなくてはならないことがあります。このとき、広域的な(グロバール)プレス(押す)とリリース(解放する)イベントを用います。二つの特別なマウス・イベントがあります。インスタンスに入る(スパライトの上に入る)ときに生じるマウス・エンター・イベントはその一つです。もう一つは、インスタンスから出る(そのスプライトから離れる)ときに生じるマウス・リブ・イベントです。これらのイベントは、通常イメージを交換するためかサウンドを鳴らすには使います。最後に、ジョイスティックに関連のイベントがあります。四方向のイベントがあります(中間的動きでは、つまり斜めのような動きでは該当両方のイベントが生じます)。最高でジョイスティックの8つのボタンのイベントも定義できます。これはプライマリのジョイスティックにでもセコンダリのジョイスティックにでも使用できます。
Otherイベント
ゲームに役立つ他の幾つかのイベントがあります。それらは、このメニューにあります。次のイベントはここに出ています。
・
Outside:インスタンスがルームを出たとき発生します。通常これを利用してインスタンスを破壊します。
・ Boundary: インスタンスがルームの境界にあるとき、発生します。
・ Game start:このイベントはゲームのスタートに発生します。これは、(後述の)ルーム・スタートの前、およびインスタンスの生成の後に起こります。通常、このイベントは一つのコントローラ・オブジェクトにだけ定義され、バックグランド・ミュージックの再生や変数の初期化やデータのロードに用います。
・ Game end:このイベントはゲーム終了時にすべてのインスタンスに起こります。通常、一つのオブジェクトしかこのイベントを定義しません。あるデータをファイルに保存する等に用います。
・ Room start:これはルームがスタートするとき、そのすべてのインスタンスに起こります。クリエーション・イベントの後に起こります。
・ Room end:ルームが終了するとき、そのすべてのインスタンスに起こります。
・ No more lives:ゲーム・メーカーは組み込みのライブ・システムをもっています。ライブの数の設定や更新用のアクションがあります。ライブの数が0か0以下になると、このイベントが生じます。これは、ゲームの最スタート、あるいは終了させるときに使用します。
・ No more health:ゲーム・メーカーには組み込みのヘルス(健康)システムをもっています。ヘルス状態の設定や更新用のアクションがあります。ヘルスが0か0以下になると、このイベントが発生します。通常、これはゲームの最スタート、あるいライブの数を減らすときに使用します。
・ End of animation:アニメーションは、前に示したように幾つかのイメージで構成され、最後のイメージの後に再び最初のイメージが来ます。ちょうど、そのときにこのイベントが発生します。たとえば、このイベントはアニメーションを変えるかインスタンスを破壊するには使用できます。
・ End of path:このイベントはインスタンスがパスを沿って追跡して、そのパスの終点に辿ったときに発生します。これについて第21章をみてください。
・ User defined:この種類の8つのイベントがあります。これらのイベントはコードで呼ばない限り決して起こりません。
Drawイベント
インスタンスは可視のとき、ゲームの各ステップに自分のスプライトをスクリーンに表示します。このイベントでアクションを指定すると、スプライトが表示されないで、その代わり指定されたアクションが実行されます。これは、スプライトの代わり他のものを表示するには用いられます。または、スプライトの引数の変更に使用します。ドローイング・イベントに専用化されたアクションがいくつあります。このイベントはオブジェクトが可視のときのみ実行されます。もちろん、描き方と関係ないでコリーション・イベントの発生がインスタンスのスプライトのみに基づいています。
Key Pressイベント
このイベントはキー・ボードのイベントと同様ですが、発生するのは一回のみ、キーが押されるときのみです。アクションを一回だけ起こさせたいときにこれは便利です。
Key Releaseイベント
このイベントはキー・ボードのイベントと同様ですが、発生するのは一回のみ、キーを解放するときのみです。
色々な場面でゲーム・メーカがどの順序でイベントを処理することが理解する必要があります。この処理順序は次の通りです。
発生、破壊、またはその該当のことが発生するとき。
アクションはゲーム・メーカーで起こる物事です。アクションはオブジェクトのイベントに置かれます。イベントが発生すれば、そのアクションが起動されます。数多くのアクションがあり、それぞれの使い方を理解する必要があります。この章では基本的なアクションのすべてについて述べます。他のアクションはライブラリ(アクションの集まり)の形で提供することができます。これらはゲーム・メーカーの機能を拡張します。ウエブ・サイトにアクセスして追加できるアクション・ライブラリについて確認しましょう。
オブジェクトのプロパティ・フォームの右には、アクションがタッブ付きのページで分類されています。アクションのセットが7つです。セットがタッブのクリックで選択できます。アクションの上にマウスを止めるとアクションの機能について簡潔な説明が表示されます。
繰り返してみましょう。イベントにアクションを付けるには、該当のタッブ・ページからアクションをリストにドラッグします。リスト内の順序を変えるには移動したいアクションをドラッグします。<Ctrl> キーを押したまま一つのアクションをドラッグするとそのアクションがコピーされます(オブジェクト同士のリスト間でもこれは可能です)。アクションを削除するときには、マウスの右クリックを用います(<Del>も使えます)。マウスの右クリックでもコピーやペストもできます。
アクションをリストにドロップすると、ほとんどの場合はアクションの設定用のウインドウが現れます。多数のアクションには2種類のパラメーターがあります。ウインドウの上部にアクションの対象になるインスタンスを指定することができます。デフォルトは、(オブジェクトのインスタンス)自分自身です。ほとんどの場合は、デフォルトの設定を使用します。コリーション・イベントの場合は、他方のインスタンスにアクションを適用できます。たとえば、他方のインスタンスを破壊することができます。また、アクションを特定のオブジェクトのすべてのインスタンスに適用することが選択できます。これで、たとえばすべての赤ボールを青ボールに変換することができます。もう一つのパラメーターはチェック・ボックスRelativeにあります。このボックスをチェックすると、設定で記入する値は現在値に対して相対値になります。これで、たとえば現在のスコアーを変えずに、これに何かを増加したりすることができます。その他のパラメーターについては後述します。パラメーターの変更はアクジョン上のダブル・クリックで行えます。
最初のアクション・セットはオブジェクトの移動(動き)についてです。そのために次のアクションがあります。
Start moving in a direction
インスタンスにある方向へ動かせるために、このアクションを用います。方向を設定ウインドウの矢印で指定します。矢印の真ん中にあるボタンで動きを止めます。動きのスピードの設定も必要です。このスピードは、ピクセル数/ステップ で与えます。デフォルト値は8です。できるだけ否定値を使わないでください。多数方向が同時に指定できます。この場合は、ランダムに方向が選ばれます。このようにモンスターに左右に動かせます。
Set direction and speed of motion
方向と速度を設定するための二番目の方法です(青い矢印のもので)。この設定では、より精密な方向が設定できます。これは0〜360の角度で与えます。0は右を、90度は上を意味します。方向は反時計回りになります。ランダムな設定はrandom(360)の記入で実現できます。後述で分かるように、randomは指定の数字より小さいランダム数を生成します。設定画面にはRelativeのチェック・ボックスがあり、チェックされると、指定された値は現在の値に加えられます。たとえば、インスタンスが上に移動している場合は、設定で左が加えられると、インスタンスは北西に動き出します。
Set the horizontal speed
インスタンスのスピードは垂直の成分と水平の成分で構成されます。このアクションでは水平の速度を変えます。肯定の水平スピードは右方向のものになります。否定のは左方向になります。垂直のスピードは変わりません。相対(relative)を使うと肯定値で加速、否定値で減速の設定が可能です。
Set the vertical speed
上述と同様にこのアクションでは、インスタンスの垂直速度を変えます。
Move towards a point
このアクションでも移動の設定が可能です。目的位置と速度を設定すると、インスタンスはその位置に向かって指定された速度で動き出します(その位置に止まらないことに注意!)。たとえば、弾丸を宇宙船の位置に飛ばせたいときは、spaceship.x、およびspaceship.yを位置として使えます(このような変数について後で述べます)。相対(Relative)のボックスをチェックすると、方向は現在の方向に対して設定されます(スピードに適用されません。つまり、指定された速度でインスタンスが移動します)。
Set a path for the instance
(アドバンス・モードだけで有効)このアクションは、インスタンスをあるパスを通るように指定できます。パスを指定し、パス上のスタート位置(0:パスのスタート点、1:パスの終了点)、移動速度も指定します。第21章のパスについての説明をご覧下さい。
Set the gravity
このアクションでオブジェクトの引力を設定することができます。方向(0〜360度)とスピードを指定すると、これらの値はステップ毎にインスタンスのそれぞれの現在値に加えられます。通常、小さな増加分しか必要はないです(例:0.01)。古典的な方向は270度(下)方向です。相対(Relative)のボックスをチェックすると、引力の速度と方向が増加されます。自然と違って、物事に異なる引力方向を与えることができます。
Set the friction
摩擦はインスタンスの動きを遅くするものです。摩擦量を設定すると、各ステップにこの摩擦量が速度からその値がゼロになるまで引かれます。通常小さな値です(例:0.01)。
Jump to a given position
このアクションを用いると、インスタンスをある特定の場所に移動することができます。x,yの座標を指定しますと、インスタンスとそのリファレンス・ポイントはそこに置かれます。相対(Relative)ボックスをチェックすると、現在の位置に対する移動が行われます。このアクションはインスタンスを連続的に移動するにはよく用いられます。各ステップに位置を少々増加します。
Jump to the start position
このアクションでインスタンスをインスタンスの生成時の位置に戻します。
Jump to a random position
このアクションはインスタンスをランダムに生成された位置に移動します。固体にぶつからない位置しか選択されません。スナピングの設置もできます。肯定のスナピングを指定すると、x,yの座標値はその倍数になります。これは、ゲームにセルを使った場合は、インスタンスをセルに沿って並ばせるために使えます。垂直と水平の別々のスナピングが指定できます。
Snap to grid
このアクションでインスタンスの位置をグリッドにフィットさせます。横と縦のスナピングの値(グリッドのセル・サイズ)が設定できます。これはインスタンスをグリッド内に置かせるには便利です。
Reverse horizontal direction
このアクションでインスタンスの横の移動方向を逆にします。これは、たとえばインスタンスは垂直の壁にぶつかったときに使えます。
Reverse vertical direction
このアクションでインスタンスの縦の移動方向を逆にします。これは、たとえばインスタンスは水平の壁にぶつかったときに使えます。
Move to contact position
このアクションで他のオブジェクトに接触するまでインスタンスをある方向に動かすことができる。現在の位置に衝突があった場合は、インスタンスが移動されません。その代わりに、インスタンスが衝突前の位置に戻されます。移動方向だけでなく、最大の移動距離も指定できます。インスタンスが落ちているとき、他のものに接触するまでの最大距離を指定できます。また、固体のオブジェクトかすべてのオブジェクトを対象にするかが指定できます。通常、このアクションを衝突イベントに置き、衝突に関わる他のインスタンスに対して、該当のインスタンスを確実に停止させるために使います。
Bounce against objects
このアクションを他方のオブジェクトとの衝突イベントに置くと、該当のインスタンスがそのオブジェクトにぶつかるとき、自然にはねて離れます。厳密(preci-se)というパラメーターをfalseに設定すると、垂直と水平の壁にしか対応しません。厳密(precise)をtrueにすると、斜面(もしくは曲線状の)壁も対象になります。しかし、処理が遅くなります。すべてのオブジェクトかあるいは固体オブジェクトかが選択できます。はね方は多数のプロパティに依存しているため、完璧なものではありません。しかし、ほとんどの場合は十分によい効果をもたらします。
次のアクションは、サウンド、ルーム、及びオブジェクトのインスタンスの生成、変更、破壊に関するものです。
Create an instance of an object
このアクションでオブジェクトのインスタンスを生成することができます。生成するオブジェクトとその位置を指定します。相対(Relative)ボックスをチェックすると、新インスタンスの位置は現在のインスタンスの位置に相対的なものになります。ゲーム中にインスタンスの生成ができるのはとても便利です。宇宙船が弾丸を生成したり、爆弾が爆発を生成したりすることができます。ゲームによって、コントローラが設けられ、そのコントローラが時々モンスターや他のオブジェクトを生成します。新インスタンスにはクリエーション・イベントが施されます。
Change the instance
このアクションで現在のインスタンスを他のオブジェクトのインスタンスに変換することができます。たとえば、爆弾のインスタンスを爆発のインスタンスに変えられます。元の移動方向や変数の値などの設定は変わりません。現行のインスタンスにデストロイ(破壊)・イベントを施すか、および新オブジェクトにクリエーション・イベントを施すかが指定できます。
Destroy the instance
このアクションで現在のインスタンスを破壊します。デストロイ・イベントはこのインスタンスに施されます。
Destroy instances at a position
このアクションで特定の座標を含むバウンディング・ボックスのインスタンスをすべて破壊します。これは、爆弾を爆発させるときには、便利です。相対(Relati-ve)ボックスをチェックすると、指定の位置は現在の位置に対して相対的に計算されます。
Change the sprite
インスタンスのスプライトを変えるときにこのアクションを使います。新スプライトを指定します。スケール係数(ファクター)も指定できます。その値(倍率)は1のとき、スケール(サイズ変更)無しを意味します。この値は0以上でなければなりません。スプライトをスケーリングしますと、描画作業は遅くなります。スプライトの変更はとても重要なものです。たとえば、オブジェクトの移動方向によってそのスプライトを変えたくなることが多いです。これは方向毎にスプライトを作れば、実現できます。キーボード・イベント内の矢印のキーで移動方向とスプライトを設定します。
Play a sound
このアクションでサウンド・リソースを再生します。サウンドの指定および再生回数が指定できます。デフォルトは一回であり、永遠に(ループ)の再生も選択できます。多数のwave型のサウンドが同時に再生できますが、midi型のものの再生は一つしかできません。このタイプのサウンドを生成すると、現在のmidi型のサウンドの再生が止まります。サウンドが多数のバッファをもたない限り、サウンドの一つのインスタンスしか再生できません(第17章を参照)。このため、再生中のサウンドが指定された場合は、まずこのサウンドが止められ、そして先頭から再び再生されます。
Stop a sound
このアクションは指定のサウンドを止めます。サウンドの多数のインスタンスが再生中の場合は、すべてが止まります。
If a sound is playing
指定されたサウンドが再生中であればリストの次のアクションが施行されますが、再生中でなければそのアクションが飛ばされ、施行されません。否定の条件も選べます。つまり、指定のサウンドが再生中ではないとき、リストの次のアクションを施行します。たとえば、あるバックグランド音楽が再生中か否かをテストして、新しいバックグランド音楽を流すことができます。このようなチェックを行うための情報については第34章を参照して下さい。
Go to the previous room
前のルームに移動します。遷移効果のタイプを指定することもできます。色々試しましょう。最初のルームにいるときにこれを使うと、エラーが起こります。
Go to the next room
次のルームに移動します。遷移効果のタイプを指定することができます。
Restart the current room
現在のルームはリスタートされます。遷移効果を指定します。
Go to a different room
このアクションで特定のルームに移動することができます。ルームと遷移効果を指定します。
If previous room exists
このアクションで前のルームが存在するか否かをチェックします。存在するときは、リストの次のアクションが施行されます。通常、前のルームに移動する前にこのアクションを使用します。
If next room exists
このアクションで次のルームが存在するか否かをチェックします。存在するときは、リストの次のアクションが施行されます。通常、次のルームに移動する前にこのアクションを使用します。.
ここでタイミング、ユーザーへのメッセージ、ゲーム全体に関するアクションがあります。
Set an alarm clock
このアクションでインスタンスの8つのアラームの内一つを設定することができます。ステップ数とアラームクロックを指定します。指定されたステップ数の後、インスタンスがアラーム・イベントを受けます。相対(Relative)のチェック・ボックスで値を増加したり減少したりすることもできます。アラーム・クロックの値を0以下に設定しますと、そのアラームクロックが無効になり、イベントが生成されません。
Sleep for a while
このアクションで特定のシーンを停止することができます。これはゲームのある段階の始まりかその終わりか、またはプレイヤーにメッセージを表示するときに使います。スリープ時間をミリ秒単位で指定します。また、スリープする前に最新の状況を反映するすスクリーンを描画するか否かを指定することができます。
Set a time line
(アドバンス・モードのときのみ有効)このアクションでオブジェクトのインスタンスの特定タイム・ラインを設定することができます。タイム・ラインを指定して、タイム・ライン内のその開始位置を指定します(0はスタートです)。このアクションでNo Time Lineを値として指定するとあるタイム・ラインを終了させることができます。
Set the time line position
(アドバンス・モードのときのみ有効)このアクションで現在のタイム・ラインの位置を変えることができます。これを使えば、タイム・ラインの一部分を飛ばしたり、もしくは特定の部分を繰り返したりするとができます。ループのタイムラインを実現するにはこのアクションを現在のタイムラインの最後に位置を0にするこのアクションを置きます。何かが起こるまで待つためにこのアクションが使用できます。このため、アクションをテストして、否定の場合はタイム・ラインの位置を−1に相対的設定する。
Display a message
このアクションでダイアログ・ボックスにメッセージを表示することができます。メッセージの作成だけが必要です。メッセージ内に#の記号を使用すると、改行として見なされます(この記号をテキストに記入するには「\#」を使います)。メッセージはクオテーションまたはダブル・クオテーションで始まると、式として見なされます。これについて後述を参照されたい(このアクションはゲームが排他的モードで実行されているときは無効です。第26章を参照)。
Show the game information
このアクションでゲームの情報ウインドウをポップ・アップします。ゲーム情報の作成については第25章を参照してください(このアクションもゲームが排他的モードで実行されているときは無効です)。
Restart the game
このアクションでゲームを最初からリスタートさせます。
End the game
このアクションでゲームを終了させます。
Save the game
このアクションでゲームの現在の状態を保存することができます。保持用のファイル名を指定します(そのファイルはゲームのワーキング・ディレクトリに生成されます)。ゲームのロードは次に示すアクションで行えます。
Load the game
ゲームの状態をファイルから読み込みます。ファイル名を指定します。必ず同じゲームのファイルであることと、そのゲームの生成に同じゲーム・メーカーのバーションが使われたことを確かめましょう。これが一致しないと、エラーが発生します(厳密にいうと、現在のステップの終了時にゲームがロードされます。このため、現在のゲームの現在のアクションの後にある幾つかのアクションが施行されます)。
他のアクションの施行を制御する色々なアクションがあります。これらは、ほとんど問いをします。たとえば、ある場所は空かを聞いたりします。答えは「はい」(true)であれば、リスト内の次のアクションが実行され、「いいえ」の場合は次のアクションが無視されます。一つ以上のアクションを判定の対象にしたいときは、これらは一つのブロックに置きます。このため、グループの先頭にスタート・ブロックを、その末尾にエンド・ブロックを置きます。答えは「いいえ」に対応するブロックも同様に構成できます。古典的な問いの構成は次の頁の図に示します。
この例では、現在のインスタンスのためのある場所は衝突フリーであるかどうかを問います。コリーションの無い場所であれば、問の答えは「はい」となり、インスタンスがある方向に移動します。答えは「いいえ」のとき、インスタンスが指定された位置に飛び移ります。
すべての問いにはNOTというラベルの枠があります。この枠にチェックを入れると、反転した結果が採用されます。つまり、「はい」を「いいえ」となり、「いいえ」を「はい」と見なされます。これでは、問の答えは「いいえ」のとき、あるアクションを施行することができます。
数多くの問いは、その対象をオブジェクトのすべてのインスタンスに指定することができます。この場合は、結果が真(true)になるのは、すべてのインスタンスに対して真であるときだけです。たとえば、すべてのボールの右の場所は空いているかどうかをチェックすることができます。
次の問およびそれに関連されたアクションがあります(これらのアクションは他のアクションと区別しやすくするために独特のアイコンとバックグランド色をもっています)。
If a position is collision free
この問いは、現在のインスタンスが特定の位置に置かれたとき、他のオブジェクトとコリーションしないと、「真」を返します。位置を「絶対」(absolute)か、あるいは「相対」(relative)に指定できます。また、固体のオブジェクトのみか、すべてのオブジェクトを対象にすることも指定できます。このアクションは現在のインスタンスが特定の位置に移動できるかどうかをチェックするために用いられます。
If there is a collision at a position
これは、先のアクションの反対のものです。現在のインスタンスが特定の位置に置かれたとき、他のオブジェクトとコリーションすると、「真」を返します(このアクションでも固体のオブジェクトのみか、すべてのオブジェクトを対象にすることが指定できます)。
If there is an object at a position
この問いは、現在のインスタンスが指定された位置で指定されたオブジェクトのインスタンスに合うと、「真」(true)を返します。
If the number of instances is a value
オブジェクトと数を指定します。オブジェクトのインスタンス数は指定された数に一致するとき、この問いは「真」(true)を返します。一致しないとき、「偽」(false)を返します。大小関係のチェックを指定することもできます。通常、このようなチェックはオブジェクトの数はすべて使い尽くしたかの調べに使います。ほとんどの場合は、これはレベルかゲームの終了を指します。
If a dice lands on one
サイコロの面数を指定します。出た面が一のとき、このアクションが「真」(true)を返し、次のアクションが施されます。これはゲームにランダムな「行動」をもたせるには使います。このアクションを用いれば、各ステップにある確率で爆弾を生成したり、移動方向を変えたりすることができます。サイコロの面数が多ければその確率が小さくなります。実数も使えます。たとえば、面数を1.5に設定すると、2/3の確率で該当のアクションが施行されます。1より小さい値を使うのは意味がありません。
If the user answers yes to a question
問いを指定します。これは「はい」と「いいえ」のボタンをもつダイアログでプレイヤーに表示されます。プレイヤーが「はい」を選んだとき、問いは「真」を返します。このアクションは排他的モードで使用できません。そのとき、問いはいつも「はい」を返します。
If an expression is true
これは最も一般的な問いです。式を記入します。式の値は「真」(値の場合は0.5以上のもの)となると、このアクションの次のアクションが実行されます。式について後述の文を参考にしてください。
If a mouse button is pressed
指定されたマウスのボタンが押されると、このアクションが「真」を返します。通常ステップ・イベントに用いられます。マウス・ボタンが押されたかをチェックして、「真」の場合は、マウスのクリック位置にインスタンスを移動することができます(この場合は、座標mouse_x およびmouse_yのjump to a given positionのアクションを使用します)。
If instance is aligned with grid
インスタンスの位置がグリッドに沿っているとき、この問いは「真」(true)を返します。縦と横のグリッドの小間の大きさを指定します。このアクションはとても便利です。たとえば、グリッドに沿って曲がらないとその操作が許せないときにこれを使います。
Else
ある問いの答えは「偽」の場合、このアクションの後に実行される部分が来ます。
Start of block
アクションのブロックの始まりを示します。
End of block
アクションのブロックの終わりを示します。
Repeat next action
このアクションは、指定された数で次のアクションまたはアクションのブロックを繰り返し実行します。数だけを指定します。
Exit the current event
このアクションがあるとイベントのその他のアクションがもう実行されません。これは特に問いの後に使います。たとえば、ある位置はフリーであると、やることはないためイベントを終了します。この例ではその次にあるアクションはコリーションが起こるときのみ施行されます。
描画アクションはドローイング・イベントだけで有効です。他には無視されます。スプライトやバックグランド以外を描くのは遅いです。このためこれを必要なときにだけ使いましょう。
Draw a sprite image
スプライト、その位置(相対か絶対か)、およびサブイメージを指定します(サブイメージ番号は0からです)。現在のサブイメージを用いたいときはその番号を-1にします。
Draw a background image
バックグランド、その位置(相対か絶対か)、およびイメージをタイルで画面上に表示するか否かを指定します。
Draw a rectangle
現在のインスタンスの位置(相対か絶対か)に対して描画する長方形の互いに対角にある二つの点の座標を指定します。
Draw an ellipse
現在のインスタンスの位置(相対か絶対か)に対して楕円を囲む長方形の互いに対角にある二つの点の座標を指定します。
Draw a line
現在のインスタンスの位置(相対か絶対か)に対して線の両端の座標を指定します。
Draw a text
テキストとその位置を指定します。テキストに#の記号を使用すると、改行として見なされます(この記号をテキストに記入するには「\#」を使います)。このように多行数のテキストを作成することができます。テキストはクオテーションまたはダブル・クオテーションで始まると、式として見なされます。たとえば、次のように書くと、
'X: ' + string(x)
インスタンスのx座標値を表示します(xの変数はx座標値を保持し、string()の関数はその値を文字列に変化します。上記では+は先頭の文字列とstring()で得た文字列を合併します)。
Set
the colors
長方形および楕円を塗りつける色を設定します。また、線、長方形および楕円の周辺の線の色を設定します。
Set a font for drawing text
その時点以降テキストに使われるフォントを設定します。
Change fullscreen mode
このアクションで通常のウインドウサイズからフル・ウインドウまたその逆にスクリーンを設定することができます。その切り替えか、通常のウインドウ・サイズかフル・ウインドウかが指定できます(このアクションは排他的モードで無効です)。
ほとんどのゲームにプレイヤーが何らかのスコアーをもちます。また、数多くのゲームにはプレイヤーに幾つかのライブが与えられます。更に、プレイヤーがあるヘルスももちます。次に示すアクションはプレイヤーのスコアー、ライブ数、ヘルスの管理を容易にします。
Set the score
ゲーム・メーカーはスコアーの仕組みをもっています。このスコアーは、ウインドウのカプション(上部)に表示されます。このアクションでスコアを変更します。新スコアを指定するだけです。指定の値をスコアーに加えたいときは、Relative(相対)ボックスをチェックしましょう。
If score has a value
この問いでスコアーが特定の値に達成したかをチェックすることができます。その値を指定し、スコアーの値がそれより小さいか大きいか等しいかを指定します。
Draw the value of score
このアクションでスコアーの値をスクリーンの特定の場所に表示することができます。その位置とスコアーの前に置くカプションを与えます。スコアーが現在のフォントで表示されます。このアクションはオブジェクトのドローウイングにしか使えません。
Clear the highscore table
このアクションはスコアー表を削除します。
Display the highscore table
ゲーム毎に最高の10個のスコアーが保持されます。このアクションはトップ・スコアーのリストを表示します。現在のスコアーはトップ・テンの中にあれば、このスコアーが挿入され、プレイヤーが自分の名前を記入することができます。スコアー表の表示を色々な形、色、使用フォントなどに設定することができます。(このアクションは排他的モードで動作しません)。
Set the number of lives
ゲーム・メーカーはライブ(命管理)・システムをもっています。このアクションでは残りの命数を変更することができます。通常、最初にこの数を3のような値にしてゲームの進み具合を見ながらこれを減らしたり増加したりします。初期値を減らしたり、増やしたりするにはRelative(相対)ボックスの選択が必要です。命の数が0(又は0以下)になると、「no more lives」イベントが生成されます。
If lives is a value
この問いでライブ数が特定の値に達成したかをチェックすることができます。その値を指定し、ライブ数の値がそれより小さいか大きいか等しいかを指定します。
Draw the number of lives
このアクションでライブ数の値をスクリーンの特定の場所に表示することができます。その位置とライブ数の前に置くカプションを与えます。ライブ数が現在のフォントで表示されます。このアクションはオブジェクトのドローウイングにしか使えません。
Draw the lives as image
ライブ数の値を表示するよりその数をイメージで表した方が良いです。このアクションはこれを可能にします。その位置と使用するイメージを指定すると、そこでライブ数をイメージで表示されます。このアクションはオブジェクトのドローウイングにしか使えません。
Set the health
ゲーム・メーカーはヘルス(健康状態)・システムをもっています。このアクションではヘルスを変更することができます。100という値は最高の健康状態と見なされています。0は不健康です。更新用の値を与えます。通常、ヘルスを減らしたり、増やしたりすることをします。このとき、Relative(相対)ボックスの選択が必要です。ヘルスが0(又は0以下)になると、「out of health」イベントが生成されます。
If health is a value
この問いでヘルスが特定の値に達成したかをチェックすることができます。その値を指定し、ヘルスの値がそれより小さいか大きいか等しいかを指定します。
Draw the health bar
このアクションでヘルスがヘルス・バーの形で表示できます。ヘルスが100の場合は、フール・バーが表示されます。0の場合はバーは空です。バーの位置、サイズ、色、及びその背景色を指定します。
Set the window caption information
通常、ウインドウのカプション(上部)にルームの番号とスコアーが表示されます。このアクションではこれを変えることができます。このアクションでスコアー、ライブ数、およびヘルスの表示・非表示、およびそれぞれのカプションが指定できます。
最後に、特にコードにかかわるアクションが幾つかあります。
Execute a script
(アドバンス・モードのときのみ有効)このアクションでゲームに追加したスクリプトを実行することができます。スクリプトとその引数(5つまで)を指定します。スクリプトについて第21章をご覧ください。
Execute a piece of code
このアクションを追加すると、コードの入力用のフォームが現れてきます。これはスクリプトを定義するときと同様です(第21章を参照)。主な違いは、対象のインスタンスが指定できることにあります。このアクションを小さなコードに使いましょう。大きなコードの場合はスクリプトの使用をお勧めします。
Set the value of a variable
ゲームに色々な組み込み変数があります。このアクションでこれらの値が変えられます。また、自分の変数を宣言して初期化することもできます。変数の名前とその値を指定します。Relative(相対)のボックスをチェックすると、変数の現在値に指定した値が加えられます。もちろん、これは変数は既に値をもつときだけ有効です。変数について後述の文を参照しましょう。変数について後述の文を参照しましょう。
If a variable has a value
このアクションで特定の変数の値をチェックすることができます。変数の値は指定した値に一致比すると、返される値は「真」となり、一致しないと「偽」が返される。大小関係も調べることができます。実際に、このアクションでは2つの式をを比較することができます。
Call the inherited event
(アドバンス・モードのときのみ有効)このアクションは、対象のオブジェクトが親オブジェクトをもつときだけ有効です(第19章を参照)。親オブジェクトの該当イベントを呼ぶアクションです。
Comment
このアクションでコメント・ラインをアクション・リストに追加することができます。その行はイタリック・フォントで表示されます。これはイベントを実行するときには特に何もしません。これを付けることによってイベントのやっていることを覚えるには助けになります。
数多くのアクションの設定には引数の値も指定しなければなりません。数字だけでなく、式で値を与えることができます。たとえば、32*32のような式で値を与えることができます。実は複雑な式も使えます。たとえば、水平の速度を倍にしたい場合は、これは2*hspeedのように設定できます。ここで、hspeedは水平のスピードを表す変数です。数多くの変数がありますが、次に示すのは最も重要なものです。
x インスタンスのx座標
y インスタンスのy座標
hspeed 水平の速度(ピクセル/ステップ)
vspeed 垂直の速度(ピクセル/ステップ)
direction 度単位の現在の移動方向(0〜360)
speed 現在の方向での速度
visibleオブジェクトが可視(1)か透明か(0)を表す
image_scale イメージのスケール率(1はスケール無し)
image_single この変数は現在のスプライトのどれのサブイメージを表示すべきのを指定します(番号は0からです)。−1(デフォルト設定)に設定すると、ループでサブイメージが一つずつ表示されます。デフォルト以外の設定では指定されたサブイメージしか描画されません。
image_speed この変数はサブ・イメージの表示速度を指定します。デフォルト値は1です。これより大きい値を指定すると、指定された速度に合わせるために幾つかのイメージが飛ばされます。1未満の値を指定すると、イメージの切り替えは遅くなります。
score 現在のスコアーの値
lives 現在のライブ(命)数
health 現在のヘルス (0-100)
mouse_x マウスのx座標
mouse_y マウスのy座標
これらの変数の値が変数設定のアクションで変えられます。設定(初期化)すれば、自分の変数も使えます(相対の設定を使わないでください。まだ有効なオプションではない)。変数を設定すると、式でも使えます。自作した変数はインスタンスの局所的(ロカル)な変数です。つまり各インスタンスはこの変数のコピーをもっています。グローバルな(共用、広域的)変数を定義するために変数名の前に「global.」を付けて下さい。
変数の前にオブジェクト名と「.」を付ければ、他のオブジェクトの変数を参照することもできます。たとえば、ボールはコインの位置に移動させたいときは、その位置を(coin.x , coin.y)のように指定すればよい。コリーション・イベントのとき、他方(other)のオブジェクトの位置がother.xのように扱えます。条件付き式では大小関係の表す「<」、「>」などが使えます。
式には関数も使えます。たとえば、random(10)の関数は10以下の実数を生成します。これを用いれば、速度をランダムに設定することができます。数多くの他の関数もあります。式および関数について第28章以降を参照しましょう。
ここまでオブジェクトを定義してその行動をイベントとアクションで定義してきました。ここでゲームのルームあるいはレベルを作成します。いずれのゲームは少なくとも一つのルームを必要とします。これらのルームにオブジェクトを配置します。ゲームがスタートすると、最初のルームが表示され、そのオブジェクトがクリエーション・イベントで指定したアクションで行動し始めます。
ルームを作成するときには、色々な選択があります。プロパティの設定とオブジェクトのインスタンスの追加の他に、バックグランドの追加、ビューの定義、およびタイルの読み込みが可能です。これらのオプションについては第20章で述べます。この章では基本設定であるインスタンスの追加、およびバックグランド・イメージの設定についてのみ述べます。
ルームを作成するときAddメニューからAdd Roomを選びます。すると、次のフォームが表示されます。
左上には3つのタブがあります(アドバンス・モードではこれらは5つになります)。「objects」のタブでオブジェクトのインスタンスをルームに追加します。「settings」のタブでルームの幾つかの設定が指定できます。「backgrounds」のタブでルームのバックグランド・イメージが設定できます。
Viewsタブでルームの一部だけを示すビューを定義することができます。Tilesタブでルームにタイルを追加することができます。
ルームの設計フォームの右にルームのレイアウトがみられます。初期状態では空で、バックグランドに灰色のマス目が写っています。
インスタンスをルームに追加するために、まずobjectsのタブを選択します。左側の下部にあるオブジェクト選択用のメニューボタンを押して、追加したいインスタンスのオブジェクトを選択します。オブジェクトの外観であるイメージが表示されている場合は、イメージをクリックすればそのオブジェクトの追加が可能になります。メニュー・ボタンでオブジェクト名を選択すると、そのイメージがすぐその上の枠に表示されます(イメージ上には座標の線は引かれています。これはイメージがルーム上のグリッドに配置されたときのマス目に対する位置と大きさを示すものです)。左クリックで右側にあるルーム領域上をクリックすると、そこに選択したインスタンスがグリッドに沿って配置されます(後述ではグリッドの設定が変えられますが、インスタンスの配置を行うときは<Alt>キーを押すと、自由配置になります)。右クリックでインスタンスの削除ができます。このようにルームの中身を設定します。配置を行うときはマウスを押したままにすると、通過されるところに該当のインスタンスが配置か、あるいは削除されます。
ここまで分かると思いますが、インスタンスを重なると下のものが消えます。通常これは狙いのですが、望ましくない場合もあります。これを避けるために、左にあるDelete underlying のチェック・ボックスのチェックマークを外します。積み重なるインスタンスを扱うには他の有効な三つの組み合わせがあります。インスタンスの位置に<Ctrl>キーを押したまま右クリックすると、その位置にある一番下のインスタンスがトップに引き上げられます。インスタンスの位置に< Alt >キーを押したまま右クリックすると、その位置にある一番上のインスタンスが一番下に移動されます。これはインスタンスの順序を変えるには使います。最後に、<Shift>キーを押したまま右クリックするとその位置のインスタンスがすべて削除されます。
左側には四つの便利なボタンがあります。Clearボタンですべてのインスタンスがルームから削除できます。Shiftボタンですべてのインスタンスを数ピクセル分移動することができます。左か、あるいは上に移動するときは否定の数を用います。これはルームを拡大するに便利です(これもインスタンスをルーム外に置くために使えます。これは時々便利です)。最後の2つのボタンでインスタンスをXかY方向で整列することができます。インスタンスが少々重なっているときは便利です。
各ルームが幾つかの設定があり、これらがsettingsタブで変えられます。ここでは最も重要な設置だけについて述べます。
ルームのそれぞれが名前をもっています。できるだけ意味のある名前を与えましょう。ルームがカプション(タイトル名)ももっています。このカプションはウインドウのカプションに表示されます。ルームの高さおよび幅(大きさ)はピクセル数で設定します。ゲームのスピードも設定できます。これは一秒あたりのステップ数で与えられます。スピードが早ければ移動などがスムースに行われます。しかし、高速なコンピュータが要求されます。
settingsタブの下部にはグリッドのサイズを設定するための欄があります。Showのボタンでグリッドの表示を有効にすることができます(ここでバックグランド等の表示有無も指定できます。作業中ではルームの幾つかのものを一時的に隠すには便利です)。
backgroundのタブでバックグランドのイメージを設定します。実は、多数のバックグランドが指定できます。次のフォームが表示されます。
フォームのトップにバックグランドの色が見えます。クリックすれば色が変えられます。この色はイメージを使わないときに役に立ちます。イメージを使うときは一番左にあるDraw background colorのチェックを外してください。イメージを使って外さないと処理時間だけ無駄になります。
左には8つのバックグランドのリストが見えます。それぞれを定義することができますが、通常一つか二つしか使いません。バックグランドを定義するときは、まずリストからそのバックグランドを選びます。次いで、チェックボックスVisible when room startsを選択します。選択しないと、表示されません。定義が終わればその名前は太字でリストに表示されます。定義作業の次にはイメージをメニューから選びます。色々な設定ができます。まず、バックグランドはルームを縦のタイルもしくは横のタイルで埋めるかを指定することができます。バックグランドの位置も指定できます(これはタイリングに影響を与えます)。最後に、バックグランドにスコロリングの動きが横方向か縦横の速度で与えられます。
もう一つのForeground imageというラベルのチェックボックスがあります。これをチェックすると、バックグランドをフォアグランドになり、最前面に表示されます。もちろん、使用可能にするために半透明のものとして使います。
ここまでみてきた情報ではゲームを作成することができます。ゲームを作成すると、他人に見て遊んでもらいたいですね。ゲームの配布を自由に行ってください。売っても構いません。詳細については、ライセンスを見てください。
基本配布方法は三つあります。一番簡単なのは、ゲームの*.gmdファイルを配布することです。しかし、この場合は、相手はゲーム・メーカーをもたなければなりません(ゲーム・メーカーを作成したゲームと一緒に配布してはいけません)。この配布では相手はゲームを変更することもできます。
第二の方法は、スタンド・アロンの(実行可能な)バーションを作成することです。このため、FileメニューのCreate Executableの項目を選択します。すると、フォームが現れ、ゲームの実行ファイル名が要求されます。名前を記入して、OKボタンを押すと、誰にでも配布できるスタンド・アロンのゲームができあがります。オプション・フォームでスタンド・アロンのゲームのアイコンを設定することができます(他の必要なファイルはスタンド・アロン・ゲームの含むフォルダにコピーして置いてください)。このフォルダで配布できます(圧縮してからでも)。
最後の三つ目の方法は、インストラーを作成することです。インターネットで色々なフリーのインストーラーがあります。この方法でもスタンド・アロンのバーションを作成して、インストーラにインストールを任せます。やり方は、使うインストーラーに依存します。
ここまでゲーム・メーカーのシンプルな特徴だけみてきました。しかし、その他色々なことができます。その他の特徴を利用できるためにゲーム・メーカーをアドバンス・モードで起動しなければなりません。その切り替えは簡単です。FileメニューからAdvance modeを選択して下さい(その効果をみるために、ゲーム・メーカーをリスタートするか現在のゲームを保存して再ロードするかの何れの一つが必要です)。
ゲーム・メーカーをアドバンス・モードで起動すると次の画面が現れます。
ここでは、シンプル・モードの項目が表示されますが、リソースやボタンやメニューの項目が増えます。また、次の章に示すようにリソースには更に幾つかのオプションが使用可能になります。以下ではその他のメニュー項目について説明します。
ファイル・メニューには次の項目が追加されます。
・ Import scripts:ファイルから役立つスクリプトを読み込むには使用します。第21章には、またこれについて述べます。
・ Export scripts:自分で作成したスクリプトをファイルにセーブには使用します。これについても第21章で触れます。
・ Merge Game:この命令(項目)を使えば、他のゲームのリソース(スプライト、サウンド、オブジェクト、ルーム、など)を現在のゲームに統合することができます。これは再利用の部分を作成するには便利です(たとえば、メニュー・システムなど)。この場合はすべてのリソース、インスタンス、およびタイルは新しいIDをもつようになることに注意しましょう。合併するファイルにあるものは異なる名目をもつようにしましょう。そうでないと、色々な問題が起こります。
・ Preferences:これで色々なゲーム・メーカーの環境設定が可能です。設定の変更は記憶されます。次の設定が可能です。
Editメニューには次の新たなコマンドがあります。
・ Insert group: リソースはグループ化することができます。大きなゲームを作るときはこれはとても便利です。たとえば、一つのオブジェクトに関するサウンドを一つのグループに集めることができます。または、ゲームのあるレベルで使用されるオブジェクトを一緒にすることもできます。このコマンドで現在のリソースタイプにグループを作ります。その名前が要求されます。グループ内にグループが作れます。後述に記すようにリソースをこれらのグループにドラッグすることができます。
・ Find Resource:このコマンドでリソースの名前を記入して、該当のプロパティ・フォームを開くことができます。
・ Show Object Information:このコマンドでゲームのすべてのオブジェクトのオバービューが得られます。
これらのコマンドを別のもう一つの方法でも与えられます。リソースかリソース・グループ上に右クリックすると、該当のポップアップメニューが表示されます。
各タイプのリソースをこのメニューで追加することができます。これらの各々にはツール・バーのボタンもキー・ショットカットもあります。
ここまでスプライトをファイルから読み込みました。しかし、ゲーム・メーカーではこれらを作成したり変更したりすることができます。これを行うために、スプライトのプロパティ・ウインドウをスプライトのダブルクリックで開きましょう(新規作成でも可能)。次いで、Edit Spriteのボタンを押します。スプライトを構成するサブイメージがもう一つのフォームに現れます。
開かれるフォームは次のようなものになります。
右にはスプライトを構成するイメージが見えます。ゲーム・メーカーではサブイメージすべてが同じ大きさでなければなりません。サブイメージの左にアニメイテッド・スプライトが再生されます。再生されないとき、Show Previewのボックスをチェックして下さい。プレビューの下に再生速度およびバックグランド色の変える欄およびボタンがあります。プレビューでアニメーションがゲームに使われたときの様子が確認できます(このスピードは実際のスピードではないことに注意しましょう。ゲームでのスピードはルームで設定した再生速度に依存します)。
スプライト・エディターのコマンドでスプライトを作成したり変えたりすることができます。これらのコマンドはすべてメニューによって提供されています(幾つかのコマンドに対するボタンもツールバーにあります)。その中には単一のイメージにしか適用できないものがあります。これらを使うときはまずサブイメージをマウスで選択します。
このメニューにはスプライトのロードおよびセーブに関連のコマンドがあります。
このメニューには、現在選択されているスプライトに関連のコマンドがあります。スプライトをカットしてクリップボードに保存したり、クリップボードからイメージをペストしたり、現在のスプライトをクリアしたり、削除したり、左右に移動したりすることもできます。また、ゲーム・メーカーにあるペインティング・プログラムで一つのイメージの編集も可能です(後述文を参照)。
このメニューではイメージの変更(変形・変質)が行えます。
このメニューではイメージを対象に色々な操作ができます。
目的のスプライトが出来上がるまでこれらのコマンドを色々試さなければなりません。
このメニューで現在のアニメーションに基づいて新しいアニメーションが作れます。目的の効果を得るために色々なオプションを試みなければなりません。また、出来上がったアニメーションをセーブしてから現在のものに加えることもできます。さらに、イメージを削除したり追加したりすることもできます。簡潔にこれらの使用について述べます。
特に、最後の二つのコマンドは強力なものです。たとえば、オブジェクトを爆発させるには、幾つかのコピーと幾つかの空フレームを追加します。次いで、これらは爆発のアニメーションとオバーレイします。または、爆発にモーフィングさせます。練習すれば、インパクトのあるスプライトが作れます。
上記に示したように、スプライトは通常アニメイテッドGIFファイルかストリップとして保存されます。ストリップはイメージを並べて保存する大きなビットマップです。唯一の問題は、各々のサブイメージの大きさがこのイメージに保存されていないことです。また、インターネットで手に入れるストリップの中には多数のスプライトを保存するものもあります。たとえば、次のストリップ・ファイルの一部分には四つのアニメーションが入っています。
このようなファイルからスプライトを指定するために、FileメニューからCreate from Stripか、またはAdd from Stripを選択します。
該当のストリップ・イメージ・ファイルを指定すると、次のフォームが現れます。
ウインドウの右には選択したストライプの一部分が見えます。左に対象のサブイメージを設定するパラメーターが幾つ指定できます。表示される長方形は選択されているイメージを囲みます。次のパラメーターが設定できます。
正しいイメージ・セットを選んでから、スプライトを作成するためにOKを押します。他人の作ったイメージを使う前にその人の許可を得るか、あるいはイメージがフリーであることを確かめましょう。
各サブイメージも編集できます。このため、サブイメージを選択して、EditメニューからEdit Imageを選びます。これは、下に示すゲーム・メーカーの小さなペインティング・イメージング(Image Editor)プログラムを起動させます。
このプログラムは小さな変更や修正を行うためのもので、新しいイメージを作成するために作られていません。それが目的であれば、専用のドローイング・プログラムを使用して、コピー・ペストでゲーム・メーカーにイメージを入れましょう。
フォームはイメージを真ん中のスペースに表示し、左に基本ドローイング・ボタンを表示します。このボタンでズーム・インかズーム・アウトしたり、ピクセルを描画したり、線を引いたり、長方形を描いたり、テキストを書いたりすることができます。色はマウスの左および右のボタンの使用に依存します。ドローイング・ツールの幾つかに線の幅や可視度のような特徴を設定することができます。また、ある色のすべてのピクセルを別の色に変えるボタンもあります。これは、特に透明性に用いるバックグランド色の変更に便利です。ツール・バーにはイメージのすべてのピクセルを左右か上下に移動するためのボタンがあります。また、イメージがズーム・イン化されたときグリッドの使用も指定できます(最低4倍ズームが必要です)。
フォームの右上に選択する色のための二つの枠があります(一つはマウスの左ボタンで選び、もう一つは右ボタンで選びます)。色変更の仕方が4つあります。まず、16個の基本色からマウスのボタン(右か左)で一つの色が選べます。基本色の上にスプライトの一番左下のピクセルを示すボックスがあります。スプライトが透明のときこの色は透明色として使用されます。この色を使うと、イメージの一部分を透明にすることができます。選択した色でイメージをクリックするのは、もう一つの方法です。この方法ではより数多くの色が選べます。ボタンを押したままにすると選択している色が見えます。第三の方法は、マウスの左クリックで左と右のボックスをクリックすることです。すると、カラー・ダイアログが現れ、そこから色が選べます。最後に、左にあるドロッパー・ツールでイメージをクリックして色をそこにコピーする方法があります。
メニューには、スプライト・エディタにもあるイメージの変形・変質用コマンドがあります。しかし、この場合は現在のイメージにしか適用できません(多数イメージのスプライトのとき、サイズ変更や、ストレッチ等のコマンドが不能です)。イメージをビットマップ・ファイルとして保存できます。Imageメニューには次の二つのコマンドもあります。
イメージの一部分を選ぶためのツールなどがありません。また、ファンシな描画ルーチンもありません。そのようなものを使いたいときはペインティング・プログラムを使ってください(ウインドウのペインティング・プログラムでもよい)。一番簡単なやり方では、対象のイメージをコピーして、ペインティング・プログラムで編集した後再びコピー・ペストでゲーム・メーカーに戻します。
アドバンス・モードでスプライト・プロパティ・フォームにはアドバンス・オプションがあり、ここでそれらについて述べます。
まず、衝突をチェックするためのオプションがあります。二つのインスタンスが合うと、コリーション・イベントが発生します。コリーションは次のようにチェックされます。各スプライトはバウンディング・ボックスをもっています。このボックスは透明でないすべてのサブイメージを囲めます。バウンディング・ボックスが重なると該当サブイメージのそれぞれのピクセルは重なるかがチェックされます。これはメモリと前処理を必要します。このような厳密なチェックが不要の場合は、Precise collision checkingボックスのチェックを外してください。このとき、バウンディング・ボックスのチェックのみ行われます。バウンディング・ボックスを小さくすることもできます。これは滅多に使用しませんが、バウンディング・ボックスを小さくしてスプライトの周辺の部分がコリーションに無視されるようにしたい場合には使います。
スプライトがビデオ・メモリと標準(メイン)メモリの2カ所に格納できます。ビデオ・メモリは通常グラフィクス・カードにあるため高速です。スプライトの多数のインスタンスがある場合は、多分ビデオ・メモリに保存するでしょう。しかし、ビデオ・カードによってビデオ・メモリのサイズは小さく限られています。このため、大きなスプライトはビデオ・メモリに保存しないようにしましょう。
幾つかのスプライトは一つか二つのレベルにしか使わない場合があります。この場合はスプライトをメモリにすっと保存するのは無駄なことです。このとき、Load only on use(使用時のみロード)のボックスをチェックします。これでスプライトは使用のときにロードされます。ルームの終了時に削除されてメモリが解放されます。大きなゲームの場合はロードされるスプライトおよびビデオ・メモリに保持するスプライトの管理は重要なことです(コードでもスプライトをロードしたり削除したりすることもできます)。
最後に、スプライトのオリジンを指定することができます。これはスプライトの位置に一致するポイントです。インスタンスを特定の場所に置くときはスプライトのオリジンがそこに置かれます。デフォルトのオリジンはスプライトの左上の角の位置です。しかし、スプライトの中心や他のポイントを使った方がよい場合があります。スプライト外のポイントも選べます。スプライトにクリックすることでもオリジンを設定することができます(イメージ上にオリジンが示されているときのみ)。
サウンドを付けるときは、その他の幾つかの特徴を設定することができます。これらにはアドバンス・モードのときのみ表示されます。
いずれのタイプのサウンド・ファイルを使用のときにのみロードするように指定できます。しかし、これはmidi型のファイルのデフォルトで、wave型ファイルのデフォルトではありません。該当ボックスをチェックすると、サウンドはゲームがスタートするときメモリにロードされません。必要なときにロードされます。これは軽いヒックアップ(hick-up)を起こしますが、メモリのセーブが大きくて、ゲームのロードが早いです。また、ルームの終わりにサウンドが捨てられ、メモリが解放されます。また、必要なときに再ロードされます。これは短いサウンド効果に使用しないで、バックグランド・ミュージックあるいはたまにしか再生されないサウンドに使いましょう。
Wave型ファイルの場合は、そのバッファ数を指定することができます。これはサウンドが同時に再生できる数を表します。たとえば、爆発のサウンドを用いるとき、しかも同時に幾つかを再生しなければならないときはこの数を大きくしなければなりません。しかし、バッファ数と共に必要なメモリの領域が大きくなります(これはサウンドカードによります)。
サウンドはサウンド効果のために準備されるかどうかも指定できます。これらのパニングおよび音量変更のような効果はコードでしか使えません。サウンド効果用のサウンドはより多くの資源を要求します。
ゲーム・メーカーにはサウンド・エディターがありません。しかし、環境設定で外部のエディターを指定することができます。設定が行われていれば、Edit Soundのボタンを押すことができ、現在のサウンドを編集することができます(編集中にゲーム・メーカーの設計ウインドウが隠され、サウンド・エディターを閉じると、再び表示されます)。
waveファイルとmidiファイルの他にはmp3型のファイルがあります。これらは縮小されたwaveファイルです。これらは、サウンド・ファイルを選択するとき表示されないがゲーム・メーカーで使用できます。このため、まずすべてのファイルを示すようにオープン・ファイルのダイアログで選びます。次いで、ファイルを選びます。しかし、短所があるので、気を付けましょう。まず、解凍しなければなりませんので処理時間がかかり、ゲームが遅くなります。ファイル・サイズが小さいが、必要なメモリは小さくはありません。また、すべての機械で再生できることは限りません。そのため、作ったゲームは幾つかの機械で実行できなくなります。できるだけこれらのファイルをそのまま使用しないで、waveファイルに変換してから使いましょう。どうしても使用したいときはバックグランドミュージックとして使いましょう。
ファイルからのローディングだけでなく自分のバックグランドも作れます。このために、Edit Backgroundのボタンを押します。小さなペインティング・プログラムが起動され、このプログラムでバックグランドを生成したり変えたりすることができます。このプログラムは高度なものではないので、よりアドバンス・ツールが使いたいときはペイント用のプログラムを使いましょう。このプログラムは16.2節で説明されています。その中でとても有利なオプションが一つあります。ImageメニューにはGradient Fillの項目があります。これを用いればとてもきれいなグラディエントをもつバックグランドが作成できます。
アドバンス・モードではバックグランド・プロパティ・フォームにアドバンスなオプションがあります。
通常、バックグランドはビデオ・メモリに保存されます。バックグランドの画像が小さいとき問題がないが、ビデオ・メモリが小さいため大きなバックグランドの場合は通常のメモリの使用が望ましいです。通常メモリの使用でビデオ扱いが少々遅くなります。通常メモリを使うためにUse video memoryボックスのチェックを外してください。
また、デフォルトのバックグランドが必要に応じてルーム終了時に捨てられます。これは大きなメモリのセービングにつながりますが、ルームの始まりが少々遅くになったり、ルーム途中のバックグランド入れ替えに小さなヒックアップが起こったりします。これを避けたいときは、Load only on useのボックスのチェックを外してください。
アドバンス・モードでオブジェクトを作成すると、よりアドバンスな設定が変えられます。
まず、オブジェクトのインスタンスの深さ(Depth)を設定することができます。インスタンスがスクリーンに描画されるときはその深さの順にしたがって表示されます。インスタンスは深さが高いと先に描画されます。深さの小さいインスタンスが最後に表示されます。同じ深さのインスタンスは生成の順で表示されます。あるオブジェクトをその他のオブジェクトの前に置きたいときは、その深さを否定数にしましょう。逆の場合は、大きな肯定値の深さを与えましょう。ゲーム中にもdepthの変数を用いればインスタンスの深さが変えられます。
第二は、オブジェクトをパーシステントにすることができます。このタイプのオブジェクトがルームからルームへ移動するとき残ります。消えるのは破壊されるときだけです。このように設定すると、オブジェクトを最初のルームに置けばすべてのルームに残ります。これは主人公がルームからルームへ移動するようなゲームにはとても便利です。パーシステント・オブジェクトの使用が強力な手段ですが、エラーを起こしやすいものです。
各オブジェクトは親がもてます。親がいると、その親の特徴を継承します。つまり、親の特殊なタイプのものになります。たとえば、ball1、ball2、ball3および ball4異なるスプライトをもつ四つのボールに同じ動作を設定したいとき、ball1を他の三つの親にして使います。すると、ball1だけのイベントを設定すればよいです。他の三つは親から同じ動作を受け付けます。これは大きな手間を減らします。
オブジェクトは数多くの特徴を他のオブジェクトと共同してその他は多少だけ異なる場合もよくあります。たとえば、一つのモンスターが上下で動きもう一つは左右で移動します。動き以外動作が同じです。このケースでは、ほとんどのイベントは同じになるが、一つか二つだけ異なります。この場合でも一方を他方の親にします。しかし、子供のオブジェクトに幾つかのイベントを別途設定します。これらのイベントは親のイベントを上書きします。このため、子供で共通のイベントが発生したとき親のアクションではなく子供のアクションが施されます。親の継承のイベントも実行したいときは、子供から該当のアクションで呼んで用います。このような場合は、たとえばball0の基本オブジェクトを作り、デフォルト動作をもたせるが、ゲームに使用しません。実際に使用するオブジェクトはこのオブジェクトを親にすることがよく使われる手段です。
親オブジェクトは親をもつことができます(サイクルが許せません)。このようにオブジェクトの階層が作れます。この特徴を使えばゲームに構造をもつことができます。できるだけこの仕組みを学んで使ってもらいたいです。
親オブジェクトのもう一つの使い方があります。親オブジェクトがコリーションイベントも継承します。これは一つの例で説明します。まず、四つのフロアー(表面、床)・オブジェクトがあると仮定しましょう。ボールがフロアーにぶつかると、方向を変えます。これはボールのコリーション・イベントに設定しなければなりません。四つの異なるフロアーがあるため、コードを四つの異なるコリーション・イベントに置かなければなりません。しかし、一つのフロアーを他の三つのフロアーの親にすると、このフロアーとのコリーション・イベントだけ設定すればよいです。他のフロアーのコリーションはこれを継承し、同様に動作します。これは、大きなコピー作業の節約につながります。
上記に説明したように、オブジェクトを使用すると、その子孫も使用されます。これは、アクションで特定のインスタンスにそのアクションが適用されるときにも有効です。これもwith()文をコードで使用するときにも同様です(後述を参照)。また、このことはinstance_position、instance_numberの関数を呼び出すときにも有効です。さらに、オブジェクトの変数を参照するときにも有効です。たとえば、上記のball1.speedを10に設定すると、その設定はball2、ball3、およびball4にも有効です。
二つのインスタンスが衝突すると、コリーション・イベントが生じます。二つのインスタンスが交わるかを判断するためにそのスプライトを使います。ほとんどのケースにはこれはよいですが、衝突を異なる形で決めたいことがあります。たとえば、イソメトリックなゲームにはオブジェクトに3D(3次元)外観をもたせるために高さをもっています。しかし、コリーションには、スプライトのベースだけが使いたい。これは、コリーション用のスプライトを作成すれば実現できます。このスプライトをオブジェクトのコリーション・マスクといいます。
Show Informationのボタンで該当のオブジェクトの情報がすべて表示されます。これは印刷が可能です。これは、オブジェクトのアクションとイベントについて知りたいときに特に便利です。
ゲーム・メーカーのルームが数多くのオプションがあります。第13章で最も重要なもののみをみてきました。この章ではその他のオプションについて述べます。
Settingsタブでみていないものが二つあります。まず、Persistentのチェック・ボックスがあります。通常、ルームから出て、その後再びそのルームに戻るときは、ルームは初期状態で再開始されます。ゲームに色々レベルがあるときは問題がないが、RPG(Roll Play Game)の場合は、これは望ましくない特徴です。このタイプのゲームのとき、ルームが出た状態のままでないとだめです。ルームのPersistentのチェック・ボックスをチェックすると、ルームの状態が保持されます。ゲームをリスタートしない限りルームは初期状態に戻りません。これはオブジェクトにも適用されるが、別の設定でオブジェクトをパシステントにすると、オブジェクトのインスタンスはルームに残らなくて次のルームに移動されます(第19章を参照)。
第二は、Creation codeのボタンがあります。これでプログラムの一部分をGMLで記入することができます(後章を参照)。このプログラムがルームの開始時に実行されます。これは、たとえばルームの幾つかの変数の初期化やインスタンスの生成等を行うには便利です。他のルームに移動ときに起こることが理解すると便利です。
・
まず、(出る)ルームのすべてのインスタンスにルーム終了のイベントが発生します。ノン・パシステントインスタンスが取り除かれます(ただし、破壊イベントが発生しません)。
・
次に、前のルームのパシステント・インスタンスが移動先のルームに追加されます。
・
新インスタンスが生成され、クリエーション・イベントが発生します(ルームがパシステントでないとき、まだは訪ねられていないとき)。
・
ルームが最初のルームの場合は、すべてのインスタンスのゲーム・スタート・イベントが発生します。
・
次いで、ルームの生成コードが実行されます。
・
最後に、すべてのインスタンスのスタ−ト・ルーム・イベントが発生します。
このように、たとえばルーム・スタート・イベントはルームの生成コードで設定された変数の値を使ったり、この生成コードで(移動先)ルームの(新とパシステント)インスタンスを参照したりすることができます。
もう一つのオプションがあります。環境設定でそのオプションが有効であれば、インスタンス上の右クリックでメニューを表示させることができ、その項目でインスタンスを削除したり、深さでその表示順序を変えたり、コードを作成したりすることができる。このコードはルームがスタートするときに、インスタンスのクリエーション・イベントの前実行されます。これはインスタンスの設定行うときに便利です。
タイレッドなバックグランドも作成できます。これらの使用ニーズは、数多くのゲームにとても美しいバックグランドが使いたいことにあります。たとえば、迷路ゲームの壁が美しくマッチングすることが必要です。また、プラタフォーム・ゲームにはプラタフォームや、木等が美しく見せたいです。ゲーム・メーカーでは色々なオブジェクトを定義してルームを構成することができます。しかし、これは大きな仕事であり、たくさんの資源を使用し、ゲームを遅くします。たとえば、きれいな壁の迷路ゲームを作成には15種類に近い異なる壁類のものが必要です。
壁のような静的なオブジェクトがバックグランドに描画することが数の多くのゲームに使われている技です。バックグランドに描くと、この場合はゲームの役は壁にぶつかったことはどうやって分かると疑問に思うでしょう。トリックは、次の通りです。きれいな(壁の含む)バックグランドを一つ使い、壁のオブジェクトもう一つ用意してバックグランドの壁の位置に配置してからこのオブジェクトを透明にします。すると、ゲームのとき、きれいなバックグランドだけ写り、ゲームの他のオブジェクトがちゃんと壁などに反応します。
このテクニックは動きのないまたは変形しないいずれのものに使用できます(アニメイテッドオブジェクトに適用できません)。プラタフォーム・ゲームには通常バックグランドが一つと壁オブジェクトが一つだけ必要になりますが、芝生を、または木の枝を歩くようなきれいなバックグランドがゲームに使えます。
ルームに幾つかのタイルを追加するために、まずタイルの含むバックグランドをゲームに追加しなければなりません。少数がゲーム・メーカーと一緒に提供されています。タイルを半透明にしたいときは、バックグランドイメージを必ず透明にしておいて下さい。
タイレッドなバックグランドを作成するために、ルームの定義時にTilesタブを押します。すると、次のフォームが現れます(実はこのフォームに既に幾つかのタイルが追加しました)。
左上に使うタイルのセットが見えます。セットを選択するために、その下のメニュー・ボタンで該当のバックグランドが選択できます。タイル・セットの下のもので幾つかの設定が変えられます。タイルの高さと幅、およびタイル間の距離(通常0か1)を設定することができます。
バックグランド・イメージにタイルを置くために、まず左上からタイルを選択して、右のルームの目的位置に左クリックします。タイル配置はインスタンスの配置と全く同じです。配置位置にあったタイルは通常削除されます。下にあるものを削除したくない場合は、Delete underlyingのチェック・マークを外して配置操作を行います。右ボタンでタイルを削除します。マウスの右クリックでもタイルが削除できます。左には、すべてのタイルを削除するボタンもそれらをシフトするボタンもあります。
左にあるForeground tilesボックスをチェックすると、配置されるタイルは最前面に描画されます。これは色々な用等があります。チェックしたまま削除を行うと最前面にあるものだけ消去されます。
タイルの使用は強力な特徴であるため、できる限りこれを使いましょう。オブジェクトの使用より高速で、タイルが一度だけ保存されますので、小さな容量しか要求しない大きなルームを使用することができます。
最後に、Viewsのタブがあります。これは、ルームの幾つかの部分がスクリーンの色々なところにドローイングできるようにする仕組みです。ビューの使用は多様です。まず、ゲームによってルームの一部分だけを見せたい場合があります。ほとんどのプラタフォーム・ゲームではルームのビューは主人公に会わせて変わります。プレイヤーが二人の場合は、各プレイヤーを別々の画面に見せたいことがよくあります。もう一つの使用では、画面の一部分は主人公に付いて変わりますが、もう一方は、固定(ステータスのような画面)です。このようなことはゲーム・メーカーでは容易に実現できます。Viewsのタブを押すと、この左にある画面が現れます。
画面の上部にEnable the use of viewsのボックスがあります。ビューを使うためにこのボックスをチェックします。その下に、定義できる8つのビューがリストに表示されます。まず、ビューはルームがスタートするとき表示するか否かを指定します。必ず、少なくとも一つのビューを示すように設定してください。表示可能なビューはその名前が太字でリストに出ます。次に、ビューに表示するルームの領域(面積)を指定します。一番左上の位置、幅、および高さを設定します。その下の欄で、スクリーン上のビューの位置を指定します。
上記に説明したように、ビューに特定のオブジェクトを追跡させたいことが度々あります。対象のオブジェクトを一番下にある欄で指定します。オブジェクトが多数のインスタンスをもつ場合は、最初のインスタンスだけ追跡されます(コードで特定のインスタンスを指定することができます)。通常、ある程度ビュー変更無しでキャラクターが移動できなければなりません。キャラクターがビューの境に近づくと、ビューが変わるはずです。オブジェクトの回りに写る範囲を指定することができます。また、ビューの変更速度も指定できます。これは、キャラクターがスクリーンの外を歩いてしまうが、ゲームのプレイがよりスムースに行われます。ビューが一瞬に変更させたいときは−1を使います。
よりアドバンスなゲームにはインスタンスに特定のパス(経路)を辿らせたいことがある。これは、タイマー付きイベントやコード等で可能ですが、困難な作業です。パス・リソースがそれより容易な手段です。アイデアが簡単です。パスをその経路の描画で定義します。次に、該当オブジェクトの生成イベントにオブジェクトが経路を通るようなアクションを加えます。この章はこれを詳細に説明します。現在の仕組みは簡単なものです。将来のバーションでより高度なものになるでしょう。
パスをゲームに追加するためにAddメニューのAdd Pathを選択します。すると、次のフォームが現れます(この画面例では既にパスが描画されています)。
左上にパス名を記入するための欄があります。すぐその下にパスを定義する座標値の対があります。各点が位置を示す値と速度(sp)の値があります。位置は絶対的なものではありません。後述に示すようにインスタンスが最初の位置からスタートして経路を通ります。速度は次のように解釈します。100の速度はインスタンスの現行の速度を表します。それより小さい値は減速を意味します。100以上の値は加速で、現行の速度に対するパーセントを表します。速度は点と点の間のそれぞれに対応する速度の中間値を使います。つまり、ある速度の点から異なる速度の点に至るまで速度が少しずつ変わります。
点を追加したいときはAddボタンを押します。すると、位置と速度を設定できます。リストの点をクリックすると、その値が変更できます。現在の点の前にもう一つの点を追加するときは、Insertボタンを押します。点の削除はDeleteボタンで行えます。Clearボタンでパス全体を消去することができます。
フォームの右に実際のパスが表示されます。マウスでもパスを変更することが可能です。その領域に左クリックすると、パスの変更が可能となります。現行の点にクリックするとドラッグでその位置が変えられます。<Shift>キーを押しながら左クリックで点を追加することができます。最後に、右クリックで点が削除できます(ただし、このような操作で速度が変えられません)。
パスの辿り方に二通りで影響を与えることが可能です。第一は、パスの接続線で形を変えます。直線(Straight lines)か、あるいはソフトな線(Smooth curve)を選ぶことができます。第二は、最後の点に辿り着いた(action at the end)ときにどうするかが指定できます。オプションが幾つかあります。最も使用されるのは最初の点に移動して経路を完成させることです。動きをパスの終点に停止させることもでき、パスの始点にジャンプすることもでき、終点から逆方向にパスを辿らせることもできます。最後のオプションが現在の位置からパスを再スタートします。通常、このオプションを使うと、パスが消えるようになります。最初の五つのやりとりが示されますが、パスがその後続きます。
パスをオブジェクトのインスタンスに割り当てるために、そのインスタンスの一つのイベントにパス・アクションを加えることができます。たとえば、クリエーション・イベントに追加できます。パス・アクションのドロップ・ダウン・メニューで使用するパスを指定します。アクションの設定で他の二つの値が指定できます。パスの実行速度がその一つです(通常の速度設定と同様なものです)。この速度はパスを定義するときに基準となる速度です。もう一つのは、パスのスタート点の指定です。0の値はスタート点を意味します(通常のケース)。1の値は終点を指します。つまり、再スタート前の点です。たとえば、逆戻りのときは方向を変える時にその値は0.5になります。
スクリプト、またはコードを使うとより高度なパスの実行制御ができます。これに影響を与えるのは四つの変数です。path_indexの変数はパスのインデックスを表します。path_positionの変数はパス上の現在位置を表します(上記に説明したように0と1の間の値です)。この変数の値は、インスタンスの動きと共に変わります。速度は通常のspeed変数で表します。方向の示すdirection変数は自動的にパスの辿るときの方向を示すように変更されます。たとえば、この変数を使えば該当のサブイメージを選択することができます。path_scaleの変数でパスをスケールすることができます。1の値は現行のサイズを意味します。1より大きい値はパスを拡大し、1以下の値はパスを縮小します。逆時計回りの度数でpath_orientationの変数はパスの実行時の方向を指定します(時計逆回りの角度で)。つまり、左右の向きだけでなく上下の方向でもパスを辿ることが可能になります。
インスタンスはパスを辿っているときに他のインスタンスと衝突すると、何か起こるでしょうか。まず、衝突のイベントが発生し、実行されます。他のインスタンスが固体であればパスのインスタンスが止まります(衝突イベントが定義されている場合)。しかし、path_positionの変数はパスを辿り続けます。ですから、いつかにある方向のパスについたときにはその方向にインスタンスが再び動きだします。
上記に説明したように、インスタンスが終点に辿り着いたときどうするかを指定することができます。このときはEnd of Pathイベントが起こります。このイベントはOther(その他の)イベントのところにあります。ここにもアクションを割り当てることができます。たとえば、そのときインスタンスを破壊したり、新しい(異なる)パスを辿らせたりすることが可能です。
数多くのゲームに色々な事柄が特定の時刻に起こらなければなりません。アラーム・イベントを使えば、これが実現できますが、複雑なゲームでは困難な作業になります。タイム・ライン・リソースはこれを解決するためのものです。タイム・ラインでどのアクションが何時に起こるかを指定することができます。他のイベントに使用できるアクションすべてが使用可能です。タイム・ラインを作成すると、その後それをインスタンスに指定することができます。指定されたインスタンスがタイム・ラインに従ってアクションを起こします。これを一つの例で説明しましょう。ガードマンを作成したいと仮定しましょう。このガードマンが20ステップ間に左に、そして10ステップに上に、次いで20ステップに右に、最後に10ステップに下に動いて止まるものとします。これは、タイム・ラインを作って、このタイム・ラインのスタートの後に左に移動するためのアクションを指定、ステップ20に移動は上に設定、ステップ30に移動は右に、ステップ50に移動は下に、ステップ60に止まるように設定して、ガードマンに割り当てれば実現できます。ゲーム全体を制御するためにタイム・ラインを用いることができます。このため、まず透明のコントローラーを作成します。次いで、(たとえば)敵を特定の間隔で生成するタイムラインを作成します。最後に、これをコントローラーに割り当てる。タイム・ラインを使用すると、強力な手段であることが分かるだろう。
タイム・ラインを作成するときは、AddメニューからAdd Time Lineを選択します。すると、次のフォームが現れます。
オブジェクトのプロパティ・フォームに似ています。フォームの左にタイム・ラインの名目を設定します。そこにもタイム・ライン編集用の幾つのボタンがあります。その右に、ステップ単位の時刻のリストがあります。各時刻にアクションを割り当てることができます。一番右に通常のアクション・タブ集があります。
自己クリストに新たな時刻を追加するために、Addのボタンを押します。その次に、タイム・ラインのスタートからのステップ数を指定します。オブジェクトのイベント・リストに行ったようにその時刻にアクションを割り当てることができます。選択した時刻をDeleteボタンで削除することができます。Changeボタンで時刻が編集できます。Clearボタンがタイム・ライン全体を削除します。
最後に、特別なボタンが2つあります。Mergeボタンである間隔内の時刻を一つにすることができます。Shiftボタンである間隔内の時刻すべてを幾つかのステップで移動することができます。ただし、否定の時刻を作ってしまうと、その時刻のアクションが実行されません。
タイム・ラインに関連の2つのアクションがあります。
Set a time line
このアクションでインスタンスの特定におタイムラインを設定します。タイム・ラインおよびそのスタート位置を指定します(0はタイム・ラインのスタートを指します)。また、このアクションのNo Time Lineの選択でタイム・ラインを終わらせることができます。
Set the time line position
このアクションでタイム・ライン内の現在の位置を変えることができます(絶対的にか、あるいは相対的に)。これを用いれば、タイム・ラインの特定の部分を飛ばしたり、繰り返して使用したりすることができます。ループ型のタイム・ラインを使用したいときは、タイム・ラインの最後の時刻にこのアクションでタイム・ラインを前頭から再スタートさせます。特定の出来事を待つこともできます。テスト・アクションを使用して、偽のとき、タイムラインを相対的に−1に設定します。
ゲーム・メーカーにはビルトイン(組み込み)プログラミング言語があります。ゲーム・メーカーになれてよりフルに使いたいときこの言語を学んでください。詳細な説明は第28章にあります。この言語の使い方は二通りあります。第一は、スクリプトが作成できます。スクリプトは、名前をもつ短いコード(命令のまとまり)です。リソース・ツリーに表示され、ファイルにセーブしたり、ファイルからロード(読み出し)したりすることのできるものです。スクリプトは、ライブラリを構成してゲーム・メーカーの機能拡張に使えます。第二の使い方では、イベントにコード・アクションを付けてそこにコードを記入することができます。コード・アクションの追加はスクリプトの追加とほぼ同じですが、コード・アクションは名前をもたないし、引数が使えません。また、対象オブジェクトを指定するための欄をもっています。コード入力は両方の使い方には同様ですので、この章ではスクリプトを中心に説明を行います。
上記に説明したようにスクリプトは、GMLのプログラミング言語のコード(命令のまとまり)で、特定のタスク(仕事)を行うコードです。スクリプトは幾つかの引数をもつことができます。イベント内でスクリプトを実行したいときはスクリプト・アクションを使用することができます。このアクションで対象のスクリプトと最大5つまでの引数を指定します(コードからもスクリプトが実行でき、このとき引数の数は16個までとなります)。スクリプトが値を返すこともできますので、関数のように他のアクションで値を提供するものとして使えます。
ゲームにスクリプトを追加するときは、AddメニューのAdd Scriptを選択します。すると、次のフォームが現れます(この例では、既に二つの引数を掛けて、その結果を返す小さなスクリプトが書いてあります)。
(これはゲーム・メーカーの組み込みエディタです。環境設定で他のエディタの使用が可能です)。トップの右には、スクリプトの名前欄があります。下の枠にはスクリプトを記入します。スクリプトのセーブやロードやコピー・ペスト用の幾つかのボタンもあります(マウスの右クリックで他のコマンドが使用できます)。
・
多数の「元に戻す」、「繰り返し」があり、キー毎またはグループで使用できます(設定は環境設定で変更できます)。
・
自動インデントで文章が前の行のと合わせられます(これも環境設定で変更できます)。
・
自動タッビングで前の行の空白でない位置までタブが可能です(これも環境設定で変更できます)。
・
<Ctrl> I で選択した行をインデント、<Shift><Ctrl> I でアンインデントすることができます。
・
カットとペスト
・
検索と置き換え
・
<Ctrl>とアップ、ダウン、ページ・アップ、ページ・ダウンでカーソルの位置を変えずにスクロールすることができます。
・
F4でカーソルの位置にあるスクリプト若しくはリソースが開けます(ただし、この機能はスクリプトのみで有効です。コードアクションで機能しません)。
・
スクリプトをテキスト・ファイルとして保存することができます。
また、スクリプトが正しいかどうかをテストするためのボタンもあります。すべてテストされないが、文法および使用されている関数の存在がチェックされます。
気が付いたと思いますが、スクリプトの文は色々な色で表示されています。エディターはオブジェクトや、組み込み変数、関数等について既に情報を集めております。この色分け表示はミズ発見などに非常に役に立ちます。ミス・タイプや要約語を変数名にの誤使用などがすぐに目で発見できます。しかし、この色分け表示は少々遅いです。ファイル・メニューの(preferences)初期設定でこれをオフにすることができます。そこでも使用色の設定もできます(設定に誤った場合は、F12を2回押してください。これでオン・オフの切り替えができます)。また、スクリプトおよびコードに使用のフォントを変更することができます。
ゲーム・メーカーの機能を拡張するにはスクリプトはとても有効です。しかし、スクリプトを正確に作らなければなりません。スクリプトをライブラリに保存してゲームに追加することができます。ライブラリをインポートするとき、ファイル・メニューのImport scripts項目を使います。スクリプトをライブラリとしてセーブするとき、Export scriptsの項目を使います。スクリプト・ライブラリはテキスト・ファイルです(ただし、拡張子は.gmlです)。特別な構造をもっていますので、直接に編集しないでください。役に立つ幾つかのライブラリは提供されています(無駄な時間を省くために、インポート後使用しないスクリプトを削除してください)。
スクリプトの作成がミズし易い作業です。必ず、テスト・ボタンを使用してください。エラーがあるとき、これが知らされ、エラー・タイプとその位置が表示されます。より厳密なチェックを行いたいときは、ゲームをデバッグ・モードで実行することができます。このとき、次に示す色々な情報を表示するフォームが現れ、色々な値を監視することができます。Runメニューで一時的にゲームを停止することができます。また、同メニューでステップ毎に実行が可能です。さらに、ゲームのリスタートもできます。Watchメニューで式の値を観察することができます。Addを使えば、ゲームの各ステップに表示したい値の式を記入することができます。このようにゲームが正常に実行されているかどうかチェックできます。数多くの式を同時に観察することができます。また、ゲームに訂正を加えた後でも使用した式を再使用のために保存することができます。このフォームのToolsメニューに他の情報を観察するために色々な項目があります。ゲームのすべてのインスタンスのリストをみることができます。すべての広域な(グロバール)変数(実は最も重要なもの)の値もみることができます。また、インスタンスの局所的な(ロカル)変数の値も観察できます(このためオブジェクト名、あるいはインスタンスのidを使います)。
コードから送られるメッセージもshow_debug_message(str)関数でみることができます。最後に、ゲームにコマンド(命令)を与えたり、実行速度を変えたりすることができます。複雑なゲームを作るときはこれらのデバッグオプションをマスターしましょう。
高度なゲームには他の補助ファイルを使用しなければなりません。その中には、たとえば、特徴を定義するファイル、ゲーム中にロードしたいバックグランドやスプライトを含むファイル、ムービー・ファイル、DLLファイル(後述を参照),若しくは自分のフォントなどがあります。これらのファイルがゲームと一緒に配布できますが、ゲームに組み込んだ方がよいでしょう。このために、データ・ファイルのリソースが使用できます。データ・ファイルのリソースは、ただ単にファイルの内容を保存します。ゲームの開始時にこのファイルはディスクに書き込まれ、ゲームで使用可能になります。
データ・ファイルを追加するためにAddメニューからAdd data Fileを選択します。次のフォームが現れます。
このリソースにも名前を与えることができます。該当ファイルをリソースに割り当てるためにLoad Data Fileのボタンを使います。保存名も選択できます(ここでは、パスの指定は許されません)。その次に、ゲーム開始時に該当ファイルどう使うかを指定します。
最後に、3つのオプションがあります。
エスポートを行うときはエラーがあってもゲームが実行されます。しかし、このとき該当のファイルかフォントか使用不能になります。
データ・ファイルは大きなメモリを閉めるが、エスポートが高速です。
よくできているゲームは、必ずプレイヤーにゲームの遊び方について情報を提供します。この情報は、プレイヤーがゲーム中に<F1> キーを押したとき表示されます。この情報を作成するために、スクリーンの左にあるリソース・ツリーのGame Informationをダブル・クリックします。小さなビルトインのエディターが起動され、ゲーム情報が編集できます。色々なフォントや、色や、スタイルを選択することができます。バックグランド色の選択も可能です。
Formatメニューには、Mimic Main Formという面白いオプションがあります。このオプションをチェックすると、ヘルプのフォームはゲームのフォームに合わせられ、その位置とサイズのものになります。つまり、ヘルプはゲームのウインドウに表示されているような効果が得られます。適切なバックグランド色を選べば、ヘルプの表示はとてもよくなります(ヘルプの下にユーザがEscキーでゲームに戻ることを記入しましょう)。
情報を短くて、正確に書きましょう。ここにもあなた、作者の名前も書きましょう。提供されている例題ゲームにはこの情報ファイルがあり、ゲームの作成についても触れています。
よりきれいな資料を作りたいときは、たとえばワードを使いましょう。作成後コピー・ペストでゲーム情報のエディター・ウインドウに入れましょう。
ゲームに変えられる色々なオプションがあります。リソース・ツリーのGame Options項目をダブル・クリックすると、これらのオプションが表示されます。オプションがタブ持ちのページ毎に分類されています。
このタブでゲームのグラフィカルな外観に関連のオプションを設定することができます。これらの設定がゲームの表示を左右するので必ずこれらのオプションをチェックしておきましょう。異なるユーザが異なる機械を使用しますので、できるだけこれらの設定を色々な機種で動作確認しましょう。
Start in fullscreen mode
これをチェックすると、ゲームはスクリーン全体を使います。チェックされないと、ウインドウで実行されます。
Scale
percentage in windowed mode
ウインドウ・モードでのスケールを設定します。100の値はスケールなしを意味します。スプライトとルームが小さいときにこのオプションを使います。スケーリングは遅いのですが、グラフィック・カードはこの作業が容易にできます。スケーリング・ダウンはとても遅いので、100以下の値の使用を避けましょう。
Scale percentage in fullscreen mode
フル・スクリーン・モードのスケールを設定します。100の値はスケールなしを意味します。0の値は最大のスケール率を意味します。スケーリングは遅いのですが、グラフィック・カードはこれが容易にできます。スケーリング・ダウンはとても遅いので、100以下の値の使用を避けましょう。
Only
scale when there is hardware support
このオプションをチェックすると、該当のハードウェアが設置されているときのみスケーリングが行われます。これを使っても、グラフィック・カードによって該当のサポートがないにもかかわらずサポートのあるように指定してしまうことがあります。
Don’t
draw a border in windowed mode
ウインドウエッド・モードでチェックされると、ゲームのウインドウはボーダーもカプション・バーももちません。
Don’t
show the buttons in the window caption
ウインドウエッド・モードでチェックされると、ウインドウのカプションは縮小用および閉じる用のボタンを表示しません。
Wait for vertical blank before drawing
コンピュータのスクリーンは一秒に何回もリフレッシュされます(通常50回〜100回)。リフレッシュの後に垂直のブランクが起こり、その間にスクリーンには何も起こりません。スクリーンを頻繁に描画すると、前のイメージの一部と後のイメージの一部が重なって見えて、ビジュアル効果が悪くなります。次のフレームを描画する前に垂直ブランクを待てばこの問題が無くなります。この策の欠点はプログラムが垂直ブランクをまつと、プログラム自身(その実行)が遅くなります。
Display the cursor
マウス・ポインターを表示するか否かを指定します。オフにすると、処理が早く、画面がきれいに見えます(ゲーム・メーカーでは自分のカーソル・オブジェクトも作れます)。
Display the caption in fullscreen mode
チェックされると、フル・スクリーンのモードではトップの左の白いボックスにルームのカプション、スコアー、およびライブ数が表示されます。これをオフにすることができます。通常これらの情報を自分でルーム内に配置・表示すると、よりきれいにできあがります。
Freeze the game when the form looses focus
チェックされると、プレイヤーが前面に(他のアプリケーション等の)フォームを出したとき、ゲームが一時停止します。ゲーム・ウインドウに戻ったときにゲームの実行が再び再開されます。
このタブでゲーム実行時にの解像度を設定することができる。
Set the resolution of the screen
スクリーンは特定の解像度をもっています。これは、3つの値で設定されます。その第一は、垂直と水平のピクセル数です。第二は、色を表現するためのビット数です。最後は、スクリーンのリフレッシュ頻度です。通常、ゲーム・メーカーがこれらの設定を変えません。つまり、コンピュータの設定を使用します。しかし、場合によってはこれは低いレベルのグラフィックス効果になってしまいます。たとえば、ゲームのルームが小さいとき、しかもユーザーの解像度が高い場合は、ゲームの画面は小さくなります。これは、フール・スクリーン・モード使用とスケイリングで解決できますが、実行が遅くなる可能性があります。より良い方法は、ゲーム・メーカーにスクリーンの解像度を変えさせることです。ゲーム・メーカーが後にこれを元通りにします。これを行うために、このオプションをチェックして下さい。これと他のオプションの設定も可能になります。まず、カラーの深さを指定することができます(16か32。通常16は最適です。ウインドウ98では32を指定しても、16ビット・モードでゲームが実行されます)。第二は、スクリーン・サイズが指定できます(320x240、640x480、800x600、1024x768、1280x1024、あるいは1600x1200)。ここで注意しなければならいことがあります。小さいスクリーン(例:320x240)を選択すると、ウインドウは、その他のアプリケーションのウインドウべてをこのサイズに合わせます。場合によっては、これは問題になるでしょう。これを避けるために、排他的モードを使用しましょう。最高サイズの2つを使うときも注意が必要です。これらのサイズはすべてのコンピュータで使用できません。最後に、周波数(リフレッシュ頻度)を指定することができます(デフォルト、60、70、85、100)。最高値より高い値を指定すると、デフォルトの値が使用されます。次のオプションも使用できます。
Use exclusive graphics mode
排他的モードでゲームはスクリーンの制御を行います。他のアプリケーションはスクリーンが使用できません。これは、グラフィックスを高速にし、特別な効果を有効にします(ガンマ設定等)。適切な設定のスクリーンが使用されることを保証したいときはこの排他的モードを使いましょう。しかし、使用時に注意しなければなりません。このモードでは他のスクリーンが表示されません。つまり、ゲームではメッセージか問いかを表示するアクション、スコアー表示、ゲーム情報等が使用できません。また、エラーも表示されません。通常、このモードでの非常状態でゲームが終了し、コンピュータの再スタートが要求されます。このモードを使う前にゲームはエラー無しで実行できることを確認しましょう。さらに、このモードを使用すると、デバッグモードが使用不能です。
Let <Esc> end the game
チェックされると、Escキーが押されると、ゲームが終了します。アドバンス・ゲームはゲームを終了する前に(セーブ等の)処理を行うため、これは望ましくない特徴です。この場合は、このオプションを外したままにして、Escキーにはアクションを与えてください(ウインドウの×にクリックすると、Escキー・イベントが発生します)。
Let <F1> show the game information
チェックされると、F1キーが押されたとき、ゲームの情報が表示されます(排他的モード以外のときのみ)。
Let <F4> switch between screen modes
チェックされると、F4でフル・スクリーンとウインドウ・モードの切り替えが行われます(排他的モード以外のときのみ)。
Let <F5> and <F6> load and save the game
チェックされると、F5キーでプレイヤーの現在のゲーム状態がセーブでき、F6で最後にセーブしたゲームのロードができます。
ゲームをロードするときに起こるべきことがこれらのオプションで指定できます。まず、ローディング・イメージを指定することができます。第二は、イメージの下にローディング・バーを表示するかどうかが指定できます。この設定では、ローディング・バーなし、デフォルトのローディング・バー使用、またはローディング・バーのバックグランドとフォアーグランドのイメージのいずれか一つ選ぶことができます(最後のでは両方のイメージの指定が必要です)。第二は、ゲームのアイコンが指定できます。使用可能なアイコンは16色、32×32のものだけです。これ以外の特徴のものを設定すると警告が現れます。
最後に、第三のではゲームの唯一のid番号が変えられます。このidはスコアー・リストおよびゲーム・ファイルの保存に用いられます。ゲームの新バーションを作成するときは、古い得点リストを参照したくないときこの番号を変えましょう。
エラー報告に関連のオプションをこれで設定できます。
Display
error messages
チェックすると、エラー・メッセージがプレイヤーに表示されます(排他的モードのとき以外)。ゲームのファイナル・バーションではこれを外しましょう。
Write
error messages to file game_errors.log
チェックされると、すべてのエラー・メッセージがゲーム・フォルダのgame_errors.logに書き込まれます。
Abort
on all error messages
通常、エラーが致命的か無視できるのかの何れの一つです。このオプションをチェックすると、すべてのエラーが致命的であると見なされ、ゲームは終了されます。ゲームの最終バーションでこのオプションを使いましょう。
Treat
unitialized variables as 0
初期化されていない変数の使用はよくある誤りの一つです。これは避けにくいことです。このオプションをチェックすると初期化されていない変数はエラーを起こさなく、ゼロに設定されたように扱われます。しかし、これを使うと、タイピング・ミスを発見できなくなります。
ここではゲームの制作者、ゲームのバーション、また他の情報を指定することができます。また、最新の更新日も記述します。これは他数人でゲームを開発するときは便利です。ゲームの実行時にこの情報にはアクセスすることができません。
複雑なゲームを作成しているなら、高速に実行できるようにしたいでしょう。ゲーム・メーカーはできるだけ高速にゲームを実行できるようにするが、大きな部分はゲーム設計に依存します。また、メモリをたくさん使用するゲームを簡単に作ります。この章ではゲームを小さくし、若しくはゲームを高速にする幾つかのヒントについて述べます。
まず、よく使うスプライトおよびバックグランドについて考えてください。アニメイテッド・スプライトは多くのメモリを占めるし、多数のスプライトの描画はたくさんの時間がかかります。このため、できるだけスプライトを小さくしましょう。スプライトの周辺にある透明領域を削除しましょう(スプライト・エディターにはそのコマンドがあります)。ビデオ・メモリに保存するスプライトと使用時にロードするものを真剣に選びましょう。バックグランド・イメージにも同様な配慮が必要です。特に大きなバックグランドはビデオに保存しないで、使用時にロードしましょう。バックグランドを使用のときバックグランド色をオフにしましょう。
フル・スクリーン・モードあるいは排他的モードを使用するときはルーム(ウインドウ)・サイズはスクリーン・サイズより大きくならないように設定しましょう。ほとんどのグラフィクス・カードはスケール・アップがよくできるがスケール・ダウンは遅いです。スプライト以外に他のものの描画を避けましょう。これはとっても遅いです。どうしても必要であれば、それらを引き続きに描画させましょう。最後に、できる限りカーソルをオフにしましょう。カーソルの表示はグラフィクスを遅くします。ビューの数にも気を付けましょう。ビュー毎にルームが再描画されるからです。
グラフィクスの他に速度に影響を与えるものもあります。インスタンス数をできるだけ小さくしましょう。特に、インスタンスが要らなくなったときすぐに削除しましょう(例:ルームを出たインスタンス)。特に、インスタンスのステップ・イベント、またはその描画イベントに多数の仕事の実行を避けましょう。ほとんどの場合は、数多くのことをステップ毎にチェックしなくてもよいです。コードの実行はインタプリタで行うため、やや遅いです。また、幾つかのアクションおよび関数の実行が時間がかかります。特に、すべてのインスタンスをチェックするものは遅いです(たとえば、弾むアクション)。
コリーション・イベントの処理をどこで行うかについてよく考えましょう。通常、二つの選択があります。コリーション・イベントのないオブジェクトは処理が早いです。このため、インスタンス数の少ないオブジェクトで処理しましょう。
大きなサウンド・ファイルを扱うときは気を付けましょう。大きなメモリを占めるし、圧縮も悪いです。サウンドを見てサンプリング・ダウンできるかを検討しましょう。
最後に、数多くの人がプレーできるゲームを作りたいとき、小さな機械でも必ずゲームのテストを行いましょう。
前に述べたようにゲーム・メーカーにはビルトインのプログラミング言語があります。このプログラミング言語ではアクションより柔軟な操作と制御が得られます。以下ではこの言語をGML(Game Maker Language)と読んで使います。色々な場所にはこの言語で書かれたプログラムが使えます。まず、スクリプトの定義に使います。スクリプトはGMLのプログラムです。第二は、イベントにコード・アクションを加えるときに使います。コード・アクションにはGMLのプログラムを提供しなければなりません。第三は、ルームのクリエーションコードに使用されます。最後に、アクション内の値を設定しなければならいとき、GMLで書かれた式が使えます。式は完全プログラムではないが、値を生成するコードの一部分です。
この章ではGMLのプログラムの基本構成について述べます。GMLのプログラムを使いたいときには、二つのことに注意しなければなりません。まず、すべてのリソース(スプライトや、オブジェクトや、サウンド等の)名に文字で始まり、文字、数字および下線「_」しかから成らない名前を使わなければなりません。このような名前を使わないとプログラムから参照したりすることができなくなります。また、名前にはself、other、global、またはallを使ってはいけません。GMLではこれらの語は特別な意味を持っています。さらに、下に示す予約語が使えません。
プログラムはブロックで構成されています。ブロックは、「{}と「」」で囲まれた一つ以上の文(statement)からなっています。文を「;」で区切って書きます。このため、いずれのプログラムも構成が次のようになっています。
{
<statement>;
<statement>;
…
}
色々な文があり、これらについて次に述べます。
他のプログラミング言語と同様にGMLは変数を用います。変数は、メモリの場所であり、値を格納します。変数は名前を持ち、変数を参照するときはその名前を用います。変数は実数か文字列の値を格納します。他の言語と異なり、GMLでは変数の宣言は不要です。数多くの変数は既に定義され、組み込み(ビルトイン)変数として扱います。マウスの位置を示すmouse_xとmouse_yのようなグローバル(広域的)なものがあります。また、プログラムの実行でオブジェクトのインスタンスに局所的に使われ、xとyのようにインスタンスの位置を示す変数もあります。変数は名前を持ち、その名前は文字で始まり、文字、数字および下線「_」しかからならないものでなければなりません(最大文字数は64個です)。新しい変数を用いると、現在のインスタンスに局所的で、他のインスタンスのプログラムでは参照できません(同オブジェクトのインスタンスでも使用不能)。しかし、下に説明するように他のインスタンスの変数の参照を可能にすることができます。
代入文は式の値を変数に与えます。代入文は次の書式をもっています。
<variable> = <expression>;
代入だけでなく、変数に自分自身とある値を+=で足したり、-=で引いたり、*=で掛けたり、/=で割ったりすることができます。また、ビット演算子で、|=、&=、および ^=を使用できます。
式は、実数(3.4等)や、「‘」あるいは「“」で囲まれた文字列(’hello’または”hello”等)や、複雑な式などのものです。式のために次の2進(真偽の値しかとれない)演算子があります(優先順位で)。
次の単一演算子もあります。
値として、数字や、変数や、値を返す関数などが使えます。サブ式が大カッコで囲めます。すべての演算子は実数に適用できます。比較は文字列にも使えます。プラス「+」は文字列の結合に使います(通常の言語と異なり、GMLではブール項目すべてが評価されます)。
Example
幾つかの参考になる代入文の例を次に示します。
{
x = 23;
str = 'hello world';
y += 5;
x *= y;
x = y
<< 2;
x = 23*((2+4) / sin(y));
str = 'hello' + " world";
b = (x < 5) && !(x==2 || x==4);
}
新しい変数がその変数に値を与えることで生成されます(宣言は不要です)。変数名を使うと、変数は現在のオブジェクトのインスタンスと一緒に格納されます。このため、他のオブジェクト(インスタンス)の使用時には使えません。変数名の前に対象のオブジェクト名とドット「.」を用いれば、他のオブジェクトの変数を読んだり、設定したりすることもできます。
すべてのオブジェクトのインスタンスから参照できるグローバル変数を生成するには、変数名の前にglobal.を付けます。たとえば、そのような変数を次のように書けます。
{
if (global.doit)
{
// do something
global.doit = false;
}
}
時々、スクリプト内か現行のコード内の変数のみが望ましい。このような変数はメモリを節約し、同一名の衝突に起因する問題を排除します。これもグロバル変数より高速です。これを得るために、キ−・ワードvarを用いて、変数をコードの先頭に宣言します。その宣言が次のようなものになります。
var <varname1>,<varname2>,<varname3>, …
たとえば、次のようなものが書けます。
{
var xx,yy;
xx = x+10;
yy = y+10;
instance_create(xx,yy,ball);
}
上記に説明したように現在のインスタンスに変数を次のように設定することができます。
x = 3;
しかし、場合によっては他のインスタンスの変数を参照したいことがあります。たとえば、ボールすべてを止めたいことがあります。または、主人公を特定の場所に移動させたいことや、コリーションのとき他方のインスタンスのスプライトを設定したいケースなどがあります。これは、対象の変数名の前にオブジェクト名とドットを付ければ実現できます。たとえば、次のように書けます。
ball.speed = 0;
これはすべてのボールのスピードを変えます。幾つかの特別なオブジェクトがあります。
これらを用いれば、たとえば次のような文が使えます。
other.sprite_index = sprite5;
all.speed = 0;
global.message = 'A good result';
global.x = ball.x;
上記の最後の文は多数のボールのある場合はどうなるかを疑問に思うのでしょうか。実は、最初のボールのxの値がグローバル変数に代入されます。
しかし、ある特定のボールの速度を指定したいときはどうすればよいのでしょうか。これは、少々難しいことです。ルームにオブジェクトのインスタンスを配置するときはマウスがインスタンスの上に置くとそのインスタンスのidが表示されます。このidは値が100000以上のものです。その番号がドットの左に使えます。しかし、気を付けましょう。ドットは数字の小数点と見なされてしまいます。これを避けるために次に示すように番号を格好で囲んでください。たとえば、100032のボールを対象にするときは次のように書けます。
(100032).speed = 0;
プログラムにインスタンスを生成するとその呼び出しはインスタンスのidを返します。このため、次のようなプログラムは有効です。
{
nnn = instance_create(100,100,ball);
nnn.speed = 8;
}
上記のコードは、一つのボールを作成して、そのスピードを設定します。最初の文(命令)でインスタンスのidを変数に代入して、その後ドットの前に使いました。これは正しいことです。厳密に説明しますと、ドットが実は演算子です。ドットの左に値を、その右に変数(アドレス)を使用します。この演算で指定されたオブジェクトまたはインスタンスの変数のアドレスを返します。すべてのオブジェクト名、および上記の特別なオブジェクトは値を代表していますので、通常の値として扱えます。たとえば、次のプログラムも有効です。
{
obj[0] = ball;
obj[1] = flag;
obj[0].alarm[4] = 12;
obj[1].id.x = 12;
}
最後の文は次のように解釈できます。最初のフラッグのidをもって、そのidのインスタンスのx座標を12にします。
オブジェクト名、特別なオブジェクト、およびインスタンスのidを幾つかの関数でも使えます。
GMLでは1次元配列および2次元配列が使えます。1次元配列の場合は、インデックスを中カッコで囲み、2次元配列の場合は、中カッコ内の二つの番号をカンマで区切ります。このようにインデックスを使うと、配列は生成されます。配列のインデックスは0から始まります。大きな配列を用いると、大きなメモリを占めますので気を付けましょう。負のインデックスは使用不能です。本システムでは、インデックスの最大値は、32000であり、総合の最大の大きさは1000000です。たとえば次のようなコードを作成することができます。
{
a[0] = 1;
i = 1;
while (i < 10) { a[i] = 2*a[i-1]; i += 1;}
b[4,6] = 32;
}
if文は次の書式があります。
if (<expression>) <statement>
または、
if (<expression>) <statement> else <statement>
上記の文(statement)はブロック(複合文)でもよいです。カッコ内の式が評価され、その(丸めた)値が0以下の場合は、偽(false)と見なされ、elseの後の文が実行されます。それ以外は、式の結果は真(true)と見なされ、条件の後の文が実行されます。大カッコをできるだけ使いましょう。つまり、次のような書式をお勧めします。
if (<expression>)
{
<statement>
}
else
{
<statement>
}
例
次のプログラムはオブジェクトをスクリーンの中心の方に移動します。
{
if (x<200) {x += 4} else {x -= 4};
}
repeat文は次の書式があります。
repeat (<expression>) <statement>
文(statement)は式で得られた(概数の)値(回数)にしたがって、繰り返して実行されます。
例
次のプログラムは五つのボールをランダムに生成された位置に生成します。
{
repeat (5) instance_create(random(400),random(400),ball);
}
while
文は次の書式があります。
while (<expression>) <statement>
カッコ内の式が真である限り文(複合文)が繰り返し実行されます。Whileを使うときに気を付けましょう。注意しないと、永遠に繰り返されるものを作成してしまい、ゲームがユーザーの入力に反応しなくなります。
例
次のプログラムは現在のオブジェクトを空いている場所への移動を試みます(ランダムにオブジェクトを移動することと同様なものです)。
{
while (!place_free(x,y))
{
x = random(room_width);
y = random(room_height);
}
}
do文は次の書式があります。
do <statement> until (<expression>)
カッコ内の式が真となるまで、文(複合文)が繰り返し実行されます。文は少なくもと1回実行されます。doを使うときに気を付けて使いましょう。注意しないと、永遠に繰り返されるものを作成してしまい、ゲームがユーザーの入力に反応しなくなります。
例
次のプログラムは現在のオブジェクトを空いている場所への移動を試みます(ランダムにオブジェクトを移動することと同様なものです)。
{
do
{
x = random(room_width);
y = random(room_height);
}
until (place_free(x,y))
}
for文は次の書式があります。
for (<statement1> ; <expression> ; <statement2>) <statement3>
次のように説明できます。最初の文(statement1)が実行されます。その次に式(expression)が評価されます。真であれば、三番目の文(statement3)が実行され、2番目の文(statement2)が実行されます。その後、再び式が評価されます。これは式が偽になるまで繰り返して行われます。
これは複雑と思いますが、次のように解釈しましょう。最初の文はループを初期化します。式はループから脱出するか否かをチェックします。第二の文は次のループの式のチェックに繋ぐものです。
ある範囲内で繰り返しのカウンタの役割を果たすものとしてよく使います。
例
次のプログラムは1〜10の値で長さ10の配列を初期化します。
{
for (i=0; i<9; i+=1) list[i] = i+1;
}
色々な場面で、アクションを特定の値に依存させ、選択したいときがあります。これは、幾つかのif文の組み合わせで実現できますが、switch文の使用でより容易に実現できます。Switch文は次の書式があります。
switch (<expression>)
{
case <expression1>: <statement1>; … ; break;
case <expression2>: <statement2>; … ; break;
…
default: <statement>; …
}
これは、次のように機能します。まず、switchの式が評価されます。その値はcaseの各々の式の値と比較されます。一致する値以降、break文まですべての命令は実行されます。一致する値が存在しない場合は、defaultの文が実行されます(default文は必須ではありません)。共通の実行文のcase文も構成できます。Break文も必須ではありません。Caseの文の後にbreakがない場合は実行は次のcaseの文に続きます。
例
次のプログラムはキーの押されることに反応します。
switch (keyboard_key)
{
case vk_left:
case vk_numpad4:
x -= 4; break;
case vk_right:
case vk_numpad6:
x += 4; break;
}
break文は次の書式があります。
break
forループ、whileループ、repeatループ、switch文、
あるいは with文に使いますと、ループか文を終了します。ループ外に使用しますと、プログラムが終了されます(ゲームは終了されません)。
continue文は次の書式があります。
continue
forループ、whileループ、repeatループ、あるいは with文に使いますと、ループかwith文の次の繰り返しの文の実行に移ります。
exit文は次の書式があります。
exit
この文は、ただ単にプログラムを終了させます(ゲームを終了させません。このため、game_end();が必要です。以下を参照)。
関数は、関数名に続くカンマで区切られたゼロ以上の引数からなるものです。
<function>(<arg1>,<arg2>,…)
関数は2種類があります。第一は、ゲームの有りとあり得る側面の制御に用いるシステムで提供される数多くの組み込み関数です。第二は、ゲームで定義するスクリプトは関数として使えます。
関数が引数が無くてもこれらを囲むカッコを必ず使用します。通常、関数は値を返しますので、式に用いられます。その他の関数はただ単にコマンドを実行します。関数は代入文の左に使用できません。たとえば、
instance_nearest(x,y,obj).speed
= 0
は書けませんが、
(instance_nearest(x,y,obj)).speed
= 0
のように書くべきです。
スクリプトを作成するときは、引数へのアクセスが望ましいです(スクリプト・アクション使用のときも、プログラム(または他のスクリプトあるいは同スクリプト)からスクリプトを関数として呼ぶときも、これが望ましいです)。引数の値は、argument0,
argument1,…,argument15の変数に格納されます。つまり、16個の引数まで用いることができます(ただし、アクションからスクリプトを呼ぶときは最初の5つしか使えません)。Argument[0]のように呼び出すこともできます。
スクリプトは値が返えせるため、式にも使えます。このとき、次のreturn文を使います。
return <expression>
スクリプトの実行はreturn文で終了します。
例
この例は引数の二乗を計算するスクリプトの定義を示します。
{
return (argument0*argument0);
}
スクリプトをコードから呼び出すときは、関数を呼ぶときと同様にその呼び出しを行います。つまり、スクリプト名の後に括弧で囲んだ引数を指定します。
上記に示したように、他のインスタンスの変数を読んだり、更新したりすることができます。しかし、場合によっては、インスタンスを対象にそれ以上の操作をしたい場合があります。たとえば、すべてのボールを8ピクセル分下の方へ動かしたいことを考えましょう。次のコードで実現できると考えられます。
ball.y = ball.y + 8;
しかし、これは間違いです。等式の右側では、最初のボールのy座標だけを取得して、それに8を加えます。この値は左のすべてのボールのy座標として代入されます。結果は、すべてのボールは同じy座標を得るだけです。次の文でも
ball.y += 8;
同様なことが行われます。上記の代入文の簡略版だけです。目的の操作を実現するために次のwith文が大いに役立ちます。この文の一般的書式は次のようになります。
with (<expression>) <statement>
式(expression)では一つ以上のインスタンスを指します。このためインスタンスのid、オブジェクト名(オブジェクトのすべてのインスタンスを対象にしたいとき)、特別なオブジェクト(all、self、other、noone)を用います。文(statement)は指定された各インスタンスに、現在のインスタンス(self)のように実行されます。このため、すべてのボールを8ピクセル分移動するために次のように書けます。
with (ball) y += 8;
複数文を同時に実行したいときは、大カッコで囲みましょう。たとえば、すべてのボールをランダムに計算された位置に移動させたいときは次の文が使えます。
with (ball)
{
x = random(room_width);
y = random(room_height);
}
この複数文では指定されたインスタンスはselfインスタンスのように扱われます。また、現在のインスタンスはその中では他方のもの(other)として見なされます。このため、すべてのボールを現在のボールの位置に移動させたいときは、次のように書けます。
with (ball)
{
x = other.x;
y = other.y;
}
with文の使用は強力です。もう少しその応用例を見ましょう。すべてのボールを破壊するために次のように書きます。
with (ball) instance_destroy();
爆弾が爆発して、しかもその近辺にあるインスタンスを破壊したいときは次のコードが使えます。
with (all)
{
if (distance_to_object(other) < 50) instance_destroy();
}
プログラムにコメントを付けることができます。「//」の後に書かれるものは無視され、内部では改行の目印として扱われます。多数の行をコメント・アウトしたいときは、該当の行を/*と*/で囲みます(これを使うと、コロリング(文の類による色づけ)は働くなることがあります。この場合はF12を押して色づけのやり直しを行いましょう)。
GMLは数多くの組み込み(ビルトイン)関数と変数があります。これらではゲームのどんな部分も制御することができます。各アクションに対応する関数がありますので、コードだけを使いたいときはアクションは不要です。しかし、アクションで制御できない側面が関数ならできます。このため、アドバンス・ゲームの作成を考えているのなら、可能なことについて理解するために、これからのすべての章を読むことをお勧めします。これらの関数と変数はアクションに値を与えるためにも使えます。ですから、コードの使用や、スクリプトの作成を考慮していなくてもその情報が大いに役に立ちます。
以下では次の決まりことがあります。「*」(米印)でマークされている変数は読み出し専用です。つまり、値の変更が不能です。変数名に[0..n]が付いているときは、変数は配列です。その範囲は与えられたインデックスで定められます。
ゲーム・メーカーには色々な計算を行うための関数があります。ここでその完全なリストを示します。
次の定数があります。
true 1に等しい
false 0に等しい
pi 3.1415…に等しい
実数を扱う関数には次のものがあります。
random(x) 0〜xまでの間ランダムに生成された数を返します。返される値はいつもxより小さい値です。
abs(x) xの絶対値を返します。
sign(x) xの符号(-1か1)を返します。
round(x) xは一番近い整数値に変換されます。
floor(x) xのフロアーを返します。つまり、xはxより小さくて一番近い整数に変換されます。
ceil(x) xのセイリングを返します。つまり、xはxより大きくて一番近い整数に変換されます。
frac(x) xの小数部を返します。
sqrt(x) xの平方根を返します(xは肯定のみです)。
sqr(x) x*xの値を返します。
power(x,n) xのn乗を返します。
exp(x) eのx乗を返します。
ln(x) xの自然対数の値を返します。
log2(x) 2基数のxの対数値を返します。
log10(x) 10基数のxの対数値を返します。
logn(n,x) n基数のxの対数値を返します。
sin(x) x のサイン(正弦)の値を返します(ラジアン単位で)。
cos(x) x のコサイン(余弦)の値を返します(ラジアン単位で)。
tan(x) x のタンジェント(正接)の値を返します(ラジアン単位で)。
arcsin(x) xのサインの逆関数の値を返します。
arccos(x) xのコサインの逆関数の値を返します。
arctan(x) xのタンジェントの逆関数の値を返します。
arctan2(y,x) (y/x)のタンジェントの逆関数の値を計算して、角度を該当の座標で返します。
degtorad(x) 度をラジアンに変換します。
radtodeg(x) ラジアンを度に変換します。
min(x,y) xとyの最小値を返します。
max(x,y) xとyの最大値を返します。
min3(x,y,z) x、yとzの最小値を返します。
max3(x,y,z) x、yとzの最大値を返します。
mean(x,y) xとyの平均値を返します。
point_distance(x1,y1,x2,y2) ポイント(x1,y1)とポイント(x2,y2)間の距離を返します。
point_direction(x1,y1,x2,y2) ポイント(x1,y1)からポイント(x2,y2)への方向を度で返します。
is_real(x) xは実数か否かを返します(文字列に対して)。
is_string(x) xは文字列であるか否かを返します(実数に対して)。
次の関数は文字と文字列の扱いに使えます。
chr(val) valのASCIIコードをもつ文字列を返します。
ord(str) 文字列strの最初の文字のASCIIコードを返します。
real(str) strを実数に変換します。Strは否定の符号、小数点、もしくはエクスポネンシャルの部分がもてます。
string(val) valの実数を文字列に変換します。標準変換で、対象の値は小数部無しの整数か2桁の小数部のものに変換されます。
string_format(val,tot,dec) totの全桁数およびdecで指定された小数部の桁数でvalを文字列に変換します。
string_length(str) 文字列の文字数を返します。
string_pos(substr,str) 文字列内のサブ文字列の先頭位置を返します(不一致の場合は0を返します)。
string_copy(str,index,count) countの長さで、indexを先頭とするサブ文字列をstr文字列から抽出します。
string_char_at(str,index) str内のindexの位置にある文字を返します。
string_delete(str,index,count) countの長さで、indexを先頭とするサブ文字列をstrから除いた文字列(str一部のコピー)を返します。
string_insert(substr,str,index) substrの文字列をindexの位置に挿入したstrのコピーを返します。
string_replace(str,substr,newstr) 最初のsubstrの文字列をnewstrに置き換えたstrのコピーを返します。
string_replace_all(str,substr,newstr) すべてのsubstrの文字列をnewstrに置き換えたstrのコピーを返します。
string_count(substr,str) str内にsubstrの文字列の発生数を返します。
string_lower(str) 小文字に変換したstrのコピーを返します。
string_upper(str) 大文字に変換したstrのコピーを返します。
string_repeat(str,count) countで指定したstrのコピーを含む文字列を返します。
string_letters(str) strに入っている文字のみで構成される文字列を返します。
string_digits(str) strに入っている数字のみで構成される文字列を返します。
string_lettersdigits(str) strに入っている数字および数字のみで構成される文字列を返します。
次の関数でクリップボードを使用するテキストの扱いを行えます。
clipboard_has_text() クリップボードにテキストがあるか否かをを返します。
clipboard_get_text() クリップボードにあるテキストを返します。
clipboard_set_text(str) strをクリップボードに設定します。
ゲーム・プレイを定義するために数多くの変数と関数があります。これらは、特にインスタンスの動きおよびその生成、イベントのタイミングとハンドリング(扱い)に影響を与えます。
ゲームの重要な側面はオブジェクトのインスタンスの動きです。各インスタンスはインスタンスの位置を示すxとyの組み込み変数をもっています(厳密にいうと、これらはスプライトのオリジンを指定します)。0,0はルームの一番左上の角の位置です。このxとy変数の値を変えると、インスタンスの位置が変わります。オブジェクトに複雑な動きをもたせたいときはこれらの変数を使用します。通常この変数の扱うコードをオブジェクトのステップ・イベントに置きます。
オブジェクトが固定のスピードと方向で動くときはより簡単な方法があります。各オブジェクトが水平速度用の変数(hspeed)および垂直速度用変数(vspeed)をもっています。肯定の水平のスピードは右方向を意味します。否定の速度は左方向になります。肯定垂直速度は下への移動を、否定のは上への移動を意味します。このため、一回だけこれらの変数を設定すればよいです(たとえば、クリエーション・イベントのとき)。こうすれば、オブジェクトのインスタンスが固定のスピードをもつようになります。
方向(0〜360の角度)と速度(肯定のみ)の設定は、もう一つの移動設定方法です。これに関連の変数を読んだり、更新したりすることで特定の移動が設定できます(内部でこれはhspeedとvspeedの値に変換されます)。また、摩擦、引力および引力の方向があります。さらに、最後にmotion_add(dir,speed)の関数で現在の移動に方向とスピードを加えることができます。
まとめると、各インスタンスが次の変数と関数あります。
x インスタンスのxの位置(ポジション)
y インスタンスのyの位置
xprevious 前のxの位置
yprevious 前のyの位置
xstart ルーム内の初期のxの位置
ystart ルーム内の初期のyの位置
hspeed 速度の水平の構成分
vspeed 速度の垂直の構成分
direction 現在の方向(0〜360度、反時計回り、0は右へ)
speed 現在の速度(ピクセル数/ステップ)
friction 現在の摩擦(ピクセル数/ステップ)
gravity 現在の引力(ピクセル数/ステップ)
gravity_direction 引力の方向(270は下へ)
motion_set(dir,speed) dirの方向とspeedの速度で動きを設定します。
motion_add(dir,speed) 現在の動きに加えます(ベクトル加算のように)。
path_index インスタンスの通っているパスのインデックス。パスのない場合は-1に設定されます。
path_position パス上の現在の位置。0はパスのスタート点、1は終了点です。
path_orientation パスの通る方向(逆時計回り)。0は通常の方向です。
path_scale パスのスケール。1はデフォルトで、パスを大きくにしたい場合はこの値を増加させます。
数多くの関数で移動を定義することができます。
place_free(x,y) 座標(x,y)はコリーション・フリーであるか否かをチェックして、その結果を返します。これは、通常あるところに移動する前に使用します。
place_empty(x,y) インスタンスが(x,y)の座標に置かれたとき、他のオブジェクトに合うかどうかをチェックして、その結果を返します。このため、チェック対象のオブジェクトは非固体のものも考慮します。
place_meeting(x,y,obj) インスタンスが(x,y)の座標に置かれたとき、objのオブジェクトに合うかどうかをチェックして、その結果を返します。Objはオブジェクトのとき、そのインスタンスが(x,y)の座標にあると、真(true)が返されます。Objはインスタンスのidでもよいで、特別なallの語を使うといずれのオブジェクトのインスタンスを指し、other(他の)の予約語も使用できます。
place_snapped(hsnap,vsnap) スナッピング値にしたがって、インスタンスが整列されているかどうかを返します。
move_random(hsnap,vsnap) 対応のアクションと同様にランダムに生成された位置にインスタンスをスナップした形で移動させます。
move_snap(hsnap,vsnap) 対応のアクションと同様にインスタンスをスナップさせます。
move_towards_point(x,y,sp) spの速度で座標(x,y)にインスタンスを移動させます。
move_bounce_solid(adv) 対応のアクションと同様に固体のインスタンスに対して弾みます。Advはアドバンスはねかたを用いるかどうかを指定します(これは複雑な面に対応するとき使います)。
move_bounce_all(adv) すべてのインスタンスに対して弾みます。
move_contact_solid(dir,maxdist) 指定された方向にインスタンスが固体物とコンタクトのあるまで移動されます。現在の位置にコリーションがない場合はコリーションのある場所の前にまでインスタンスが移動されます。既にコリーションがあった場合はインスタンスが移動されません。maxdistで移動する最大の距離が指定できます(任意の距離を指定したいときは、否定値を使いましょう)。
move_contact_all(dir,maxdist)
前の関数と同様ですが、この場合は、すべてのオブジェクト(固体のみではなくて)を考慮します。
move_outside_solid(dir,maxdist) 指定された方向にインスタンスが固体物の領域外になるまで移動されます。現在の位置にコリーションがない場合はインスタンスが移動されません。maxdistで移動する最大の距離が指定できます(任意の距離を指定したいときは、否定値を使いましょう)。
move_outside_all(dir,maxdist)
前の関数と同様ですが、この場合は、すべてのオブジェクト(固体のみではなくて)を対象になります。
distance_to_point(x,y) 現在のインスタンスのバウンディング・ボックスから座標(x,y)までの距離を返します。
distance_to_object(obj) 現在のインスタンスからobjの一番近いのインスタンスまでの距離を返します。
position_empty(x,y) (x,y)座標は空いているかどうかを返します。
position_meeting(x,y,obj) 座標(x,y)にobjのインスタンスかあるかどうかを返します。Objはいずれのオブジェクト、idのインスタンス、予約語self、other、あるいはall、として指定できます。
ゲームの基本単位はオブジェクトのインスタンスです。ゲームのプレイ中にこれらのインスタンスの特徴を変えることができます。また、新しいインスタンスを生成したり、インスタンスを削除したりすることができます。上記に説明した移動関係の変数と後に説明する描画関係の変数の他に、各インスタンスは次の変数をもっています。
object_index* オブジェクトのインスタンスのインデックス。変更不能。
id* インスタンスの唯一のid(>= 100000)。ルームを定義するときは、マウスがインスタンスの上にあるときは、インスタンスの下にidが表示されます。
mask_index コリーション用のマスクのインデックス。これを-1にすると、スプライトのインデックスに等しくなります。
solid インスタンスが固体のとき。これはゲーム中に変えられます。
persistent インスタンスがパーシステントかどうかを指定します。パーシステントのときルームが変わってもインスタンスが残ります。ゲーム中にこれをオフにするのが望ましいです(たとえば、ルームに戻るとき)。
インスタンスを扱うときには一つの問題があります。各インスタンスを区別するのは簡単ではありません。インスタンスが一つのときその名前を使いますが、それ以外の場合はインスタンスのidの取得が必要です。これはインスタンスの唯一の固有のものです。これはwith文でインスタンスの区別に使用できます(28.6節で説明するドット構文の使用で)。幸いに、インスタンスのidを調べる変数と関数があります。
instance_count* ルームに存在するインスタンスの数
instance_id[0..n-1]* 特定のインスタンスのid。ここではnはインスタンスの番号です。
一つの例を示しましょう。ゲームの各インスタンスはパワーをもつことを仮定しましょう。また、一番パワーフルなインスタンスを決定したいです。そのために、次のコードを使うことができます。
{
maxid = -1;
maxpower = 0;
for (i=0; i<instance_number; i+=1)
{
iii = instance_id[i];
if (iii.object_index == unit)
{
if (iii.power > maxpower)
{maxid = iii; maxpower = iii.power;}
}
}
}
ループの後、maxidの変数は最大のパワーのインスタンスidを保存します(このようなループではインスタンスを破壊しないでください。それらは自動的に配列から削除され、配列のインデックスはそれに伴って替わりますので、インスタンスを飛ばすことになってしまいます)。
instance_find(obj,n) objタイプの(n+1)番目のインスタンスのidを返します。Objは、オブジェクト、あるいはallのキーワードです。そのインスタンスが存在しないときは、nooneの特別なオブジェクトが返されます。
instance_exists(obj) objタイプのインスタンスが存在するかどうかを返します。Objはオブジェクト、インスタンスのid、あるいはallのキーワードです。
instance_number(obj) objタイプのインスタンスの数を返します
。Objは、オブジェクト、あるいはallのキーワードです。
instance_position(x,y,obj) 座標(x,y)にあるobjタイプのインスタンスのidを返します。多数存在するときは、最初のが返されます。Objは、オブジェクト、あるいはallのキーワードです。そのインスタンスが存在しないときは、nooneの特別なオブジェクトが返されます。
instance_nearest(x,y,obj) 座標(x,y)に一番近いobjタイプのインスタンスのidを返します。Objは、オブジェクト、あるいはallのキーワードです。
instance_furthest(x,y,obj) 座標(x,y)に一番遠いobjタイプのインスタンスのidを返します。Objは、オブジェクト、あるいはallのキーワードです。
instance_place(x,y,obj) 現在のインスタンスが座標(x,y)に置かれたとき、そこに合うobjタイプのインスタンスのidを返します。Objは、オブジェクト、あるいはallのキーワードです。そのインスタンスが存在しないときは、nooneの特別なオブジェクトが返されます。
次の関数はオブジェクトの作成とその破壊に使用できます。
instance_create(x,y,obj) 座標(x,y)にobjタイプのインスタンスを作成します。関数は新インスタンスのidを返します。
instance_copy(performevent) 現在のインスタンスのコピーを作成します。関数の引数は生成(クリエーション)イベントをコピーされたインスタンスに施すか否かを指定します。この関数は生成されたインスタンスのidを返します。
instance_destroy() 現在のインスタンスを破壊します。
instance_change(obj,perf) 現在のインスタンスをobjタイプに変換します。perfは破壊とクリエーション・イベントを行うかどうかを指定します。
position_destroy(x,y) (x,y)のポジションをもつスプライトのすべてのインスタンスを破壊します。
position_change(x,y,obj,perf)
座標(x,y)にあるすべてのインスタンスをobjタイプに変換します。perfは破壊とクリエーション・イベントを行うかどうかを指定します。
よいゲームはきめ細かい物事の出現タイミングを要します。幸いにゲーム・メーカーはほとんどのタイミング作業を行ってくれます。すべてのことはあるレート(頻度)で行われていることを保証します。このレートはルームの定義段階で指定します。しかし、room_speedのグローバル変数の使用で変更できます。たとえば、各ステップ毎にroom_speed増加(例0.001で)させて少しずつゲームを早くにして、難しくすることができます。使っているコンピュータが遅ければこのスピードが得られない場合があります。これをfpsの変数でチェックすることができます。この変数は常に現在の秒当たりのフレーム数を監視しています。最後に、アドバンス・タイミングを行うときは、コンピュータが起動されてから経過したミリ秒の数を保持するcurrent_time の変数を使うことができます。次に示すのは使用できる変数のすべてです(最初のものしか変更できません)。
room_speed 現在のルームでのゲームの速度(ステップ数/秒)。
fps* 1秒あたり描画されるフレーム数。
current_time* システムがスタートしてから経過した時間(ミリ秒単位で)。
current_year* 現在の年。
current_month* 現在の月。
current_day* 現在の日。
current_weekday* 現在の曜日(1は日曜日、…7は土曜日)。
current_hour* 現在の時間。
current_minute* 現在時間の分数。
current_second* 現在時間の秒数。
時々、ゲームを一時的停止したいことがあります。このためにスリープ関数を使います。
sleep(numb) numbで指定されたミリ秒数スリープします。
最後に、もう既に知っているように各インスタンスが設定可能な異なる8つのアラームをもっています。その値を変える(または取得する)ために次の変数を用います。
alarm[0..7] 指定されたアラームの値(オブジェクトのアラーム・イベントがアクションをもつときのみアラームがアップデートされることに注意しましょう)。
前に示したように複雑なタイミングにはタイム・ライン・リソースが使用できます。各インスタンスが独自のタイム・ライン・リソースをもつことができます。次の変数はタイム・ライン・リソースに関わっています。
timeline_index インスタンスに関連されたタイム・ライン・リソースのインデックス。これは特定のタイム・ラインの指定に使用できます。現在のタイム・ラインの使用を停止するには−1の値を使います。
timeline_position タイム・ライン内の現在の位置。これを変えると、タイム・ラインの一部の繰り返しや一部の飛び出しが可能になります。
timeline_speed 通常、タイム・ラインの各ステップに位置が1に増加されます。この変数を変えればその増加分が変えられます。0.5のような実数も使えます。1より大きな値を使うと色々な時刻を同時に発現します。しかし、該当のアクションは元の順序通りで行われますので、実行されないアクションがありません。
ゲームはルームで行われます。各ルームはその名で指定されたインデックスをもっています。現在のルームはroom変数に保持されます。ルームは連続した番号で番号付けられていることが仮定できません。このため、ルーム番号を対象に値を足したり、引いたりしないでください。それより、次の変数と関数を使いましょう。古典的なコードは次のようになります。
{
if (room != room_last)
{
room_goto_next();
}
else
{
game_end();
}
}
ルームを扱う次の変数と関数があります。
room 現在のルームのインデックス。他のルームへ移動するために変更できますが、次のルーチンを用いた方がよいです。
room_first* ゲームの最初のルームのインデックス
room_last* ゲームの最後のルームのインデックス。
room_goto(numb) numbインデックスのルームへ移動。
room_goto_previous()前のルームへ移動。
room_goto_next() 次のルームへ移動。
room_restart() 現在のルームを再スタートします。
room_previous(numb)numbインデックスをもつルームの前のルームのインデックスを返します(−1=そのルームが存在しない)。
room_next(numb) numbインデックスをもつルーム の次のルームのインデックスを返します(−1=そのルームが存在しない)。
game_end() ゲームを終了させます。
game_restart() ゲームを最スタートさせます。
ルームは次の特徴もあります。
room_width* ピクセル数でのルーム幅。
room_height* ピクセル数でのルームの高さ。
room_caption ウインドウのカプションに表示されるルーム用のカプション文字列。
room_persistent 現在のルームはパーシステントであるかどうか。
数多くのゲームはプレイヤーにゲームを保存したりセーブしたゲームをロードしたりすることを可能にします。ゲーム・メーカーではこれは自動的に行われます。プレイヤーが<F5>を押すと、ゲームがセーブされ、<F6>を押すと、ゲームのロードができます。コードでもこのゲームのセーブ(保存)とロード(開く)が可能です(ローディングは現在のステップの終了時に行われます)。
game_save(string) stringのファイル名にゲームをセーブします。.
game_load(string) stringのファイル名からゲームをロードします。
ゲームのもう一つの重要な特徴はスコアー、ヘルスおよびライブ数です。ゲーム・メーカーは、グローバル変数scoreおよびlivesでスコアーおよびライブ数を管理しています。スコアーの更新は該当変数を変えることで行えます。ヘルスおよびライブ数については同様です。ライブ数が0以上の値で始まって、0以下になったときは、no-more-livesイベントがすべてのインスタンスを対象に実行されます。スコアーとライブ数をカプションに表示したくない場合は、show_score等の変数をfalseに設定します。
score 現在のスコアー。
lives 現在のライブ数。
health 現在のヘルス(0−100)。
show_score スコアーを表示するかどうか。
show_lives ライブ数を表示するかどうか。
show_health ヘルスを表示するかどうか。
caption_score スコアー用のカプション。
caption_lives ライブ数用のカプション。
caption_health ヘルス用のカプション。
スコアー・リストを管理するために組み込みの仕組みがあります。このリストには10名まで管理できます。これの詳細については第34章を見てください。
ご存じのようにゲーム・メーカーはイベントで動きます。すべてのアクションはイベントの結果です。異なる幾つかのイベントがあります。クリエーションと破壊のイベントは、それぞれインスタンスの生成とその破壊によって発生します。各ステップにシステムはまずアラームイベントを処理します。その次に、キーボードおよびマウス・イベントを扱います。その後、インスタンスが新位置に着いたときコリーション・イベントが処理されます。最後に、ドロー・イベントを使ってインスタンスの描画が行われます(多数ビューの場合は、ドロー・イベントは各ステップに数回呼び出されます)。コードからもイベントを現在のインスタンスに適用することができます。そのために、次の関数があります。
event_perform(type,numb)現在のインスタンスにtype型のnumbイベントを適用します。次のイベント・タイプを指定することができます。
ev_create
ev_destroy
ev_step
ev_alarm
ev_keyboard
ev_mouse
ev_collision
ev_other
ev_draw
ev_keypress
ev_keyrelease
指定されたタイプのイベントが多数存在するときは、numbでそのイベントを明確にすることができます。アラーム・イベントの場合はnumbは0〜7です。キーボード・イベントの場合はキーのキーコードを与えなければなりません。マウス・イベントの場合は次の定数が使用できます。
ev_left_button
ev_right_button
ev_middle_button
ev_no_button
ev_left_press
ev_right_press
ev_middle_press
ev_left_release
ev_right_release
ev_middle_release
ev_mouse_enter
ev_mouse_leave
ev_joystick1_left
ev_joystick1_right
ev_joystick1_up
ev_joystick1_down
ev_joystick1_button1
ev_joystick1_button2
ev_joystick1_button3
ev_joystick1_button4
ev_joystick1_button5
ev_joystick1_button6
ev_joystick1_button7
ev_joystick1_button8
ev_joystick2_left
ev_joystick2_right
ev_joystick2_up
ev_joystick2_down
ev_joystick2_button1
ev_joystick2_button2
ev_joystick2_button3
ev_joystick2_button4
ev_joystick2_button5
ev_joystick2_button6
ev_joystick2_button7
ev_joystick2_button8
コリーション・イベントのとき、他方のオブジェクトのインデックスを出します。最後に、他方の(other)イベントでは次の定数が使えます。
ev_outside
ev_boundary
ev_game_start
ev_game_end
ev_room_start
ev_room_end
ev_no_more_lives
ev_no_more_health
ev_animation_end
ev_end_of_path
ev_user0
ev_user1
ev_user2
ev_user3
ev_user4
ev_user5
ev_user6
ev_user7
指定したステップ・イベントでは次の定数が使えます。
ev_step_normal
ev_step_begin
ev_step_end
event_perform_object(obj,type,numb) この関数は上記の関数と同様なものですが、この関数では他のオブジェクトを対象にすることができます。ただし、指定されたイベントのアクションは、指定したオブジェクトのすべてのインスタンスではなく、現在のインスタンスだけに適用されます。
event_user(numb) 他のイベントでは8つまでのイベントを定義することができます。そのイベントはこの関数を呼ばない限り実行されません。numbの範囲は0〜7です
event_inherited() 継承されたイベントを実行します。これは現在のインスタンスには親インスタンスのあるときだけ有効です。
現在実行中のイベントについての情報を、次の読み出し専用の変数で得ることができます。
event_type* 実行中のイベントのタイプ。
event_number* 現在実行されているイベント番号
event_object* 現在実行されているイベントのオブジェクトのインデックス。
event_action* 現在実行されているアクションのインデックス(0番目は、イベントの最初のものです)。
エラーの扱う次の変数があります。
error_ocurred エラーが発生したか否かを指定します。
error_ocurred 最後のエラー・メッセージを格納する文字列です。
Show_debug_message(str) デバッグ・モードの文字列を表示します。
ユーザーとやり取りしないゲームはありません。ゲーム・メーカーでのこれを実現するための標準的なやり方では、マウスもしくはキーボード・イベントにアクションを設定します。しかし、より厳密な制御の場合もあります。コードを用いれば、キーボードのキーが押されているかどうかやマウスの位置やまたそのボタンが押されているか否かをチェックすることができます。通常、これをコントローラ型のオブジェクトのステップ・イベントでチェックして、アクションを起こします。このため、次の変数と関数があります。
mouse_x* マウスのx座標。変更不能変数
mouse_y* マウスのy座標。変更不能変数
mouse_button 現在押されているマウスのボタン。値としてmb_none、 mb_any、mb_left、mb_middle、あるいはmb_rightを使います。
keyboard_lastkey 最後に押されたキーのコード。キーの定数について後述の文を参照しましょう。これを0に設定したり、変えたりすることができます。
keyboard_key 現在押されているキーのコード(以下を参照;0は無し)。
keyboard_lastchar 最後に押されたキーの文字(文字列として)
keyboard_string 最後にタイプインされた80文字の文字列。この文字列は印刷可能なもののみで構成されています。バックスペースの操作にも正しく反応します。つまり、バックスペースが押されたとき、文字一つが文字列の末尾から削除されます。
時々、一つのキーを他のキーに対応させることが便利です。たとえば、プレイヤーに矢印のキーとテンキーのキーが使えるようにしたいことがあります。アクションを二重化するよりテンキーのキーを矢印のキーに対応することができます。または、キーの設定をプレイヤーに任せたいこともあります。この場合は、次の関数が使用できます。
keyboard_set_map(key1,key2) 最key1コードのキーをkey2コードのキーに対応させます。
keyboard_get_map(key) keyの現在のマッピングを返します。
keyboard_unset_map() すべてのキーのマッピングを自分自身にリセットします。
どれのマウス・ボタン、あるいはキーが押されたかを調べるために次の関数を使うことができます。これらは、特に複数のキーが押されたとき便利です。
keyboard_check(key) keyコードのキーが押されているか否かを調べる。
keyboard_check_direct(key) keyコードのキーが押されているか否かを直接にハードウェアで調べる。アプリケーションと独立に行われます。その他の幾つかのチェックも可能です。特に、vk_lshift、vk_lcontrol、vk_lalt、vk_rshift、vk_rcontrol、およびvk_raltキー・コードでshift、control、およびaltキーを調べることができます(W95で使用不能)。
mouse_check_button(numb) マウス・ボタンが押されているか否かを調べます(使う値は、mb_none、mb_left、mb_middle、またはmb_rightです)。
キーボードの状態を扱うために次のルーチンを使用することができます。
keyboard_get_numlock テンキーが有効か否かを返します。
keyboard_set_numlock(on) テンキーを設定(true)か非設定(false)します。
keyboard_get_numlockテンキーが有効か否かを返します(W95で使用不能)。
keyboard_key_press(key) keyのキーコードのキーが押されていることをシミュレーションします。
keyboard_key_release(key) keyのキーコードのキーを切り離すことをシミュレーションします。
次のバーチャル・キーコード対応の定数があります。
vk_nokey キーが押されていないことを示すキー・コード
vk_anykey いずれのキーが押されていることを示すキー・コード
vk_left 左の矢印キーのキー・コード
vk_right 右の矢印キーのキー・コード
vk_up 上の矢印キーのキー・コード
vk_down 下の矢印キーのキー・コード
vk_enter エンター・キー
vk_escape スケープ・キー
vk_space スペース・キー
vk_shift シフト・キー
vk_control コントロール・キー
vk_alt alt キー
vk_backspace backspaceキー
vk_tab tabキー
vk_home homeキー
vk_end endキー
vk_delete deleteキー
vk_insert insertキー
vk_pageup pageupキー
vk_pagedown pagedownキー
vk_pause pause/breakキー
vk_printscreen printscreen/sysrqキー
vk_f1 … vk_f12 F1〜F12のキー
vk_numpad0 … vk_numpad9 テンキーの数字のキー
vk_multiply テンキーの「×」キー
vk_divide テンキーの「÷」のキー
vk_add テンキーの「+」キー
vk_subtract テンキーの「−」キー
vk_decimal テンキーの「.」(浮動小数点)キー
文字列の場合は、たとえばord('A')を用いる(大文字)。次の定数がkeyboard_check_directだけで使用できます。
vk_lshift 左のshiftキー
vk_lcontrol 左のcontrolキー
vk_lalt 左のAltキー
vk_rshift 右のshiftキー
vk_rcontrol 右のcontrolキー
vk_ralt 右のAltキー
これらは、古いウインドウのバーションで動作しません。
たとえば、矢印のキーで制御できるオブジェクトがあったとします。このとき、次のコードがオブジェクトのステップ・イベントに置けます。
{
if (keyboard_check(vk_left)) x -= 4;
if (keyboard_check(vk_right)) x += 4;
if (keyboard_check(vk_up)) y -= 4;
if (keyboard_check(vk_down)) y += 4;
}
もちろん、これをキーボード・イベントに置いた方が簡単です。
やり取りに関連の他の5つの関数があります。
keyboard_clear(key) キーの状態をクリアします。ユーザーがキーを放すまでキー・イベントが発生しません。
mouse_clear(button) マウスの状態をクリアします。ユーザーがマウスを放すまでマウス・イベントが発生しません。
io_clear() マウスとキーボード状態をすべてクリア(削除)します。
io_handle() ユーザーの入出力を扱い、マウスおよびキーの状態を更新します。
keyboard_wait() がキーを押すまで待ちます。
ジョイスティックに関連されたイベントが幾つありますが、ジョイスティックを制御するための関数があります。ゲーム・メーカーが二つまでのジョイスティックをサポートします。このため、すべての関数はジョイスティックのidを使用します。
joystick_exists(id) ジョイスティックid(1か2)が存在するか否かを返します。
joystick_name(id) ジョイスティックidの名前を返します。
joystick_axes(id) ジョイスティックidの軸の数を返します。
joystick_buttons(id) ジョイスティックidのボタンの数を返します。
joystick_has_pov(id) ジョイスティックidがpov(point-of-view)機能を持つか否かを返します。
joystick_direction(id) ジョイスティックid(1か2)の向きに対応するキー・コード(vk_numpad1〜vk_numpad9)を返します。
joystick_check_button(id,numb) ジョイスティック・ボタンが押されているか否か(ボタン番号:1〜4)を返します。
joystick_xpos(id) ジョイスティックidのx座標(-1か1)を返します。
joystick_ypos(id)ジョイスティックのy座標を返します。
joystick_zpos(id) ジョイスティックのz座標を返します。
joystick_rpos(id) ジョイスティックのr座標(rudder位置、4番目の軸)を返します。
joystick_upos(id) ジョイスティックのu座標(5番目の軸)を返します。
joystick_vpos(id) ジョイスティックのv座標(6番目の軸)を返します。
joystick_pov(id) ジョイスティックidのpov(point-of-view)を返します。これは角度で、0-360の間の値です。0は前進(フォワード)、90は右、180は後退(バックワード)へ、270は左です。Povが押されていないときは−1が返されます。
ゲームの一つの重要な要素はグラフィックスです。通常ゲーム・メーカーが管理しますから、簡単なゲームでは我々がほとんど何もしなくてもよいです。しかし、自分で制御したいときもあります。多少のものにはそれに対応するアクションがありますが、幅広い制御の場合はコードを使用します。この章はこのために用いる関数や変数について述べ、発生することの詳細について触れています。
デフォルトでゲームはスクリーンの真ん中に配置されるウインドウで実行されます。プレイヤーは、こらが<F4>のキーでフル・スクリーンに変更できます(これは無効でない場合)。プログラムに次の変数を用いれば、同様のことが実現できます。
full_screen この変数はフル・スクリーン・モードでtrueです。この変数でモードが変えられます(falseで通常サイズ)。
フル・スクリーン・モードでカプションおよびスコアがスクリーンに表示されます(これは、ゲームのオプションを使えば無効にすることができます)。フル・スクリーン・モードでイメージが中央に表示されるか、あるいはスケール化されます。これが次の変数で制御できます。
scale_window ウインドウ・モードのスケール率を示す変数です。100はスケール無しを意味します。
scale_full フル・スクリーン・モードのスケール率を示す変数です。100はスケール無しを意味し、0は最大のスケール率を指します。
スケール・モードは遅いマシンや遅いグラフィクス・カードではゲームを遅くしてしまいます。デフォルトで、ゲーム実行中にカーソルが表示されます。ほとんどのゲームにはこれは不要です。カーソルを排除するために次の変数を使います。
show_cursor falseに設定するとカーソルがゲーム領域内に表示されませんが、trueの場合は表示されます。
ウインドウで予め定義されているカーソルを次の関数で使用することができます。
show_cursor(cur) カーソルをcurに設定します。次の定数が使えます。cr_default、cr_none、cr_arrow、cr_cross、cr_beam、cr_size_nesw、cr_size_ns、cr_size_nwse、cr_size_we、cr_uparrow、cr_hourglass、cr_drag、cr_nodrop、cr_hsplit、cr_vsplit、cr_multidrag、cr_sqlwait、cr_no、cr_appstart、cr_help、cr_headpoint、cr_size_all。
ところで、カーソルを作成するのはとても簡単です。否定の深さのオブジェクトを作成して、そのステップのイベントでマウスの位置を追跡するようにします。
モニターの解像度を調べるには次の読み出し専用の変数を使います。
monitor_width* ピクセル単位のモニターの横幅
monitor_height* ピクセル単位のモニターの縦幅
各オブジェクトはスプライトをもちます。これは単一のイメージかあるいは多数のイメージのものです。オブジェクトの各インスタンスのために、プログラムはそれに該当するイメージをスクリーンに表示します。その(スプライトで指定された)原点はオブジェクトのx、y座標となります。多数のイメージのものの場合は、一つずつを表示して動きのある効果を実現します。イメージの描画に影響を与える変数が幾つかあります。これらを使えば描画効果が変えます。各インスタンスは次の変数をもちます。
visible この変数が1(true)に設定されると、イメージが描画され、falseの場合は表示されません。透明のインスタンスはアクティブですので、衝突イベントも起こします。ただ、見えないだけです。このように可視性をfalseにすると、制御用のオブジェクト(衝突イベントを起こさないために非固定ものにしましょう)に使えますし、隠れたスイッチにも使用できます。
sprite_index インスタンスの現在のスプライトのインデックスです。これを変えるとインスタンスに他のスプライトが与えられます。値として定義したスプライトの名前が使えます。スプライトを変えても現在表示されているサブイメージのインデックスが変わりません。
sprite_width* スプライトの横幅を表し、変えられないが使用できます。
sprite_height* スプライトの縦幅を表し、変えられないが使用できます。
sprite_xoffset* スプライトの横方向でのオフセットを表し、変えられないが使用できます。
sprite_yoffset* スプライトの縦方向でのオフセットを表し、変えられないが使用できます
image_number* インスタンスの現在のスプライトのサブイメージ数(変更不能)
image_index イメージが多数のサブイメージを持つとき、プログラムはこれら一つずつを繰り返し使います。この変数は現在描画されているサブイメージを指します(これらが0から番号付けられています)。現在のイメージがこの変数の変更で変えられます。プログラムはこのインデックスからサブイメージを一つずつ繰り返し使います。
image_single 時々一つのイメージだけを使いたいことがあります。そのときはこの変数を見たいサブイメージのインデックスに設定します(最初のサブイメージは0です)。−1に設定すると、プログラムはサブイメージを一つずつを繰り返し使います。多数の外観のオブジェクトの場合はこれが役に立ちます。たとえば、回転のできるオブジェクトがあったとします。このときオブジェクトのスプライトが(反時計)各方向用のサブイメージを持つとします。このオブジェクトのステップのイベントでは次のようなコードが使えます。
{
image_single = direction * image_number/360;
}
image_speed サブイメージの置き換えの速度です。値は1だと、一つずつのイメージを扱うことになります。1より小さい値は置き換えを遅くし、一つのサブイメージが何回も表示されます。1より大きい値を使用すると、指定された速度に合わせるためにサブイメージは飛ばされてしまいます。
depth 通常イメージはインスタンスの生成順に従って表示されます。これを変えるためにこの変数を設定します。オブジェクト・プロパティの設定段階に他の値を指定されていない限り、この変数のデフォルト値は0です。値が高ければインスタンスは後方の方に設定されます(否定の値も使えます)。小さい値のものは大きい値のものより前面に表示されます。ディップの値の設定で自分で指定した通りインスタンスが描画されます(たとえば、飛行機が雲の前)。バックグランドイメージは高い値を持ちます。フォアグランドイメージはディップが小さい(か否定値)。
image_scale イメージを小さくしたり、大きくしたりするためのスケール係数です。1の値は通常の大きさを意味します。この変数を変えるとイメージの高さと横幅が変わり、コリーション・イベントにも影響を与えます。スケール化されたイメージ(特に小さくなったもの)は描画時間が大きくなることに注意しましょう。スケーリングを用いれば3D(3次元)効果が得られます。
bbox_left* イメージのバウンディング・ボックスの左辺(スケールの考慮入り)
bbox_right* イメージのバウンディング・ボックスの右辺
bbox_top* イメージのバウンディング・ボックスの上辺
bbox_bottom* イメージのバウンディング・ボックスの下辺
各ルームは8つまでのバックグランドをもちます。また、バックグランド色も有します。これらの特徴をコードで次の変数で変えられます(バックグランドは配列で管理され、その要素(0〜7)は一つのバックグランドを指しています)。
background_color ルームのバックグランド色
background_showcolor バックグランド色でウインドウを削除します
background_visible[0..7] それぞれのバックグランド・イメージを可視する
background_foreground[0..7] それぞれのバックグランドをフォアグランドにします
background_index[0..7] バックグランド用のバックグランド・イメージ・インデックス
background_x[0..7] バックグランド・イメージのx座標
background_y[0…7] バックグランド・イメージのy座標
background_width[0…7]* バックグランド・イメージの幅
background_height[0…7]* バックグランド・イメージの高さ
background_htiled[0..7] 横方向でタイル化
background_vtiled[0..7] 縦方向でタイル化
background_hspeed[0..7] バックグランドの水平のスクローリング速度(ピクセル数/ステップ)
background_vspeed[0..7] バックグランドの垂直のスクローリング速度(ピクセル数/ステップ)
background_alpha[0..7] バックグランドを描画するときに使用する透明度(alpha)値を指定します。1は通常の設定です。0は完全に透明を意味します。使用時には気を付けましょう。半透明バックグランドの描画は時間がかかり、ゲームを遅くにします。
もう既に分かるようにルームにタイルを追加することができます。タイルはバックグランド・リソースの一つです。タイルは可視のイメージです。イベントに反応しませんし衝突も起こしません。このため、オブジェクトより高速に処理できます。イベントまたは衝突を要しないものをタイルで実現しましょう。きれいなグラフィックスの実現にタイルを、衝突にはオブジェクトを使いましょう。
実は、思ったよりタイルをよく制御することができます。通常、ルームの設計段階に追加するが、ゲーム実行中にも追加できます。タイルの位置を変えたり、スケール化したり半透明にしたりすることができます。
タイルは次のプロパティをもっています。
タイルのプロパティを変えるために、そのidは必要です。ルーム作成時にタイルを追加すると、タイルのidは下部の情報バーに表示されます。特定の位置にあるタイルのidを調べる関数があります。
次の関数はタイルの操作に使用できます。
tile_add(background,left,right,width,heigth,x,y,depth) ルームに指定の値の新しいタイルを追加します(上記の説明を参照)。関数はタイルのidを返します。
tile_delete(id) 指定のidのタイルを削除します
tile_find(x,y,foreground) x、y座標にあるタイルのidを返します。その位置にタイルがないと、−1が返されます。フォーグランドが真(true)の場合は0未満の値のタイルのみ対象になります。そうでない場合は、0か0以上の値のタイルだけ対象になります。多数該当の場合は、最初のタイルのidが返されます。
tile_delete_at(x,y,foreground) x、y座標にあるタイルを消去します。フォーグランドが真(true)の場合は0未満の値のタイルのみ対象になり、そのすべてが削除されます。そうでない場合は、0か0以上の値のタイルだけ対象になり、消去されます。多数該当の場合は、すべて削除されます。
tile_exist(id) 指定されたidのタイルの有無を表します。
tile_get__x(id) 指定されたidのタイルのx座標を返します
tile_get__y(id) 指定されたidのタイルのy座標を返します。
tile_get__left(id) 指定されたidのタイルのleft値を返します。
tile_get__top(id) 指定されたidのタイルのtop値を返します。
tile_get_width(id) 指定されたidのタイルの幅を返します。
tile_get_height(id) 指定されたidのタイルの高さを返します。
tile_get_depth(id) 指定されたidのタイルの深さを返します。
tile_get__visible(id) 指定されたidのタイルが可視か透明かを表す値を返します。
tile_get__xscale(id) 指定されたidのタイルのxscale値を返します。
tile_get__yscale(id) 指定されたidのタイルのyscale値を返します。
tile_get__background(id) 指定されたidのタイルのバックグランドを返します。
tile_get__alpha(id) 指定されたidのタイルのalpha値を返します。
tile_set__position(id,x,y) 指定されたidのタイルのx、y座標を設定します。
tile_set__region(id,left,right,width,height) 属するバックグランド内に、指定されたidのタイルの領域を設定します。
tile_set__background(id,background) 指定されたidのタイルのバックグランドを設定します。
tile_set__visible(id,visible) 指定されたidのタイルを可視か透明かを設定します。
tile_set__depth(id,depth) 指定されたidのタイルの深さを設定します。
tile_set__scale(id,xscale,yscale) 指定されたidのタイルのスケールを設定します。
tile_set__alpha(id,alpha) 指定されたidのタイルのalpha値を設定します。
オブジェクトはそのイメージと全く異なる形にすることができます。色々な形のものを描くために数多くの関数があります。テキストを表示する関数もあります。これらの関数をオブジェクトのドローイング(描画用)・イベントで使うべきです。他のコードでは意味がありません(後述の32.8節を参照)。コンピュータのグラフィクス・ハードウェアはグラフィックスの表示を高速化するだけです。このため、他のドローイング・ルーチンはかなり遅くなります。また、ゲーム・メーカーは高速なイメージ表示に最適化されています。このため、できるだけ他のドローイング・ルーチンの使用を避けてもらいたいです(それより、可能な限りビットマップ素材を作成しましょう)。インスタンス間の衝突は、描画されることではなくオブジェクトの外観であるスプライト(あるいはマスク)で決定されることを忘れないでほしい。イメージ関連の関数には次のものがあります。
draw_sprite(n,img,x,y) スプライトのn番目(インデックス:−1は現在)のサブイメージimgを座標 (x,y)に描きます。
draw_sprite_scaled(n,img,x,y,s) スケール・ファクターsでスプライトを描画します。
draw_sprite_stretched(n,img,x,y,w,h) 座標(x,y)を一番左上の角を基準として、幅w と高さhの領域を全部使うようにスプライトを表示します。
draw_sprite_transparent(n,img,x,y,s,alpha) スケールsでバックグランドの色と混合したスプライトを描画します。透明度はalphaで指定します。 0の値はスプライトを完全に透明にし、1の値はスプライトを可視にします。この関数で非常によい効果が実現できます(半透明爆発などがその一つの例です)。この効果はソフトで行われるのでとても遅く、注意して使いましょう。
draw_background(n,x,y) インデックスnのバックグランドを座標(x,y)に描画します。
draw_background_scaled(n,x,y,s) バックグランドをスケール化して描画します。
draw_background_stretched(n,x,y,w,h) 指定された領域にバックグランドをストレッチして描画します。
draw_background_transparent(n,x,y,s,alpha) 透明度alpha(alpha: 0〜1)とスケール係数sでバックグランドを描画します。
draw_background_tiled(n,x,y) ルーム全体をバックグランドのタイルで描画します。
次の関数で基本的な形を描画します。これらの関数は色々なプロパティ、特にブラシおよびペンの色を用います。その設定は色々な変数で可能です。
draw_pixel(x,y) ブラシ色で座標(x,y)にピクセルを描画します。
draw_getpixel(x,y) 座標(x,y)にあるピクセルの色を返します。
draw_fill(x,y) 座標(x,y)から該当領域をブラシ色で塗りつぶします。
draw_line(x1,y1,x2,y2) 座標(x1,y1) から(x2,y2)までの線を描きます。
draw_circle(x,y,r) 座標(x,y)に半径rの円を描きます。
draw_ellipse(x1,y1,x2,y2) 楕円を描きます。
draw_rectangle(x1,y1,x2,y2) 長方形を描きます。
draw_roundrect(x1,y1,x2,y2) 面取り長方形を描きます。
draw_trangle(x1,y1,x2,y2,x3,y3) 三角形を描きます。
draw_arc(x1,y1,x2,y2,x3,y3,x4,y4) 楕円の弧を描きます。
draw_chord(x1,y1,x2,y2,x3,y3,x4,y4) 楕円の弦を描きます。
draw_pie(x1,y1,x2,y2,x3,y3,x4,y4) パイ型(楕円の一部分)の絵を描きます。
draw_button(x1,y1,x2,y2,up) ボタンを描画します。1の値はボタンがアップ、0はボタンがダウンを意味します。
draw_text(x,y,string) 座標(x,y)に文字列(string)を表示します。#の記号、改行(char(13))、またはライン・フィード(char(10))は改行として見なされます。これを使えば、多行数のテキストを作成することができます(#の表示に\#を使いましょう)。
draw_text_ext(x,y,string,sep,w) 前記の関数と同様ですが、多行数のテキストを作成するときは、行間の距離(sep)を指定することができます。−1はデフォルトの距離を指定します。もう一つの定数wは、テキストの幅をピクセル数を指定します。指定された幅より長いテキストは空白区切りか−記号で数行に分けられます。−1を指定すると、行は分割されません。
draw_text_sprite(x,y,string,sep,w,sprite,firstchar,scale) 上記の関数でテキストを表示すると資源がかなり使います。この関数は上記の関数と同様ですが、文字をスプライトから取り出します。つまり、スプライトが各文字に対応するサブイメージを持たなければなりません。その最小の文字はfirtscharで指定されます。これ以降の文字はASCII順で並ばなければなりません。ウインドウの文字マップのツールがコードの確認に使えます。文字一部(数字か大文字までか)を使用するときその他の文字の指定は不要です。スケール計数はscaleで指定します(1は通常サイズ)。スケール使用に気を付けましょう。ゲームを遅くすることがあります。これらのスプライトは通常大きいです。また、衝突時に厳密なチェックは不要です。
draw_poligon_begin() 多角形の描画をスタートさせます。
draw_polygon_vertex(x,y) 座標(x,y)に多角形に角を追加します。
draw_polygon_end() 多角形の描画を終わらせます。実は、この関数は多角形を描画します。
線(ペン)の色や領域(ブラシ)やフォントなど数多くの設定が変えられます。これらの変数は、グローバルであり、ゲームのすべてのものに影響を与えます。このため、一つのオブジェクトのドローイング・イベントでこれらを変えますと、それ以降のすべてのオブジェクトに有効になります。これらの変数は他のイベントにも使用できます。たとえば、固定にしたいときはゲームのスタートに設定できます(これは一番効率よいです)。
brush_color シェイプを塗りつぶすための色。予め用意されている次の色があります。
c_aqua
c_black
c_blue
c_dkgray
c_fuchsia
c_gray
c_green
c_lime
c_ltgray
c_maroon
c_navy
c_olive
c_purple
c_red
c_silver
c_teal
c_white
c_yellow
他の色はmake_color(red,green,blue)のルーチンで作れます。各red、green、およびblueの値は0〜255です。
brush_style 塗りつぶすためのブラシ・スタイル。次のスタイルが使えます
bs_hollow
bs_solid
bs_bdiagonal
bs_fdiagonal
bs_cross
bs_diagcross
bs_horizontal
bs_vertical
pen_color 境界線を描く用のペン色
pen_size ペンのサイズ(ピクセル数)
font_color フォントの色
font_size フォントのサイズ(ポイント数)
font_name フォント名(文字列)
font_style フォントのスタイル。次のスタイルがあります(加算でその組み合わせが可能になります)。
fs_normal
fs_bold
fs_italic
fs_underline
fs_strikeout
font_angle フォント回転の角度(0〜360)。通常のテキストでは90度を用います
font_align 指定に従ってテキストを揃える。次の指定が使えます
fa_left
fa_center
fa_right
次の関数もあります。
string_width(string) draw_text()関数に該当する現在のフォントでの文字列の幅。グラフィックスの厳密な位置決定に使用できます。
string_height(string) draw_text()関数に該当する現在のフォントでの文字列の高さ。
string_width_ext(string,sep,w) draw_text_ext()関数に該当する現在のフォントでの文字列の幅。グラフィックスの厳密な位置決定に使用できます。
string_height_ext(string,sep,w) draw_text_ext()関数に該当する現在のフォントでの文字列の高さ。
screen_gamma(r,g,b) ガンマ定数値を設定します。r、gおよびbは−1〜1までの値をとります。デフォルトは0です。0より小さい値を用いると該当の色は暗くなります。0以上の値を用いると、その色が明るくなります。ほとんどの場合は、値三つとも同値に保ちます。たとえば、照明効果を得るために、三つの値を1に近い値に設定します。この関数は排他的モードでしか使用できません。
screen_save(fname) スクリーンのイメージをbmp形式で指定されたファイルに保存します。これはスクリーン・ショットの作成にとても便利です
screen_save_part(fname,left,top,right,bottom) スクリーンの一部分を指定されたファイルに保存します
もう既に分かっていることですが、ルームを設計するときは、8つまでのビューを定義することができます。これでルームの異なる部分をスクリーンの異なる位置に表示できます。また、特定のオブジェクトはいつも可視であることも指定できます。ビューをコードで制御することができます。ビューを可視にしたり、透明にしたりすることもできます。また、スクリーン上のその配置位置やサイズを変えたり、ルーム内の位置を変更したりすることもできます(可視オブジェクトがない場合はとても便利)。さらに、可視オブジェクトの周辺の枠線のサイズやビューに可視となるオブジェクトも指定できます。最後のものは、ゲーム中で重要なオブジェクトが変わったとき非常に大切なことです。たとえば、現在の状態に基づいて主人公を変えることができます。しかし、これはこのオブジェクトがそのまま可視になることを意味しません。これを実現するために、主要なオブジェクトのクリエション・イベントで次の一行のコードを入れます(最初のビューで起こることを仮定にしたとき)。
{
view_object[0] = object_index;
}
ビューに影響を与えるの次の変数があります。最初の二つを除いて、変数が0(最初のビュー)〜7(最後のビュー)の配列です。
view_enabled ビューが許可されているかを表します。
view_current* 現在描画中のビュー(0〜7)。これはドローイング・イベントでしか使わないでください。この変数をチェックすれば一つのビューに幾つかのことを描画するときに使います。この変数が変更できません。
view_visible[0..7] スクリーンにビューが可視かを表します。
view_left[0..7] ルーム内のビューの左位置を示します。
view_top[0..7] ルーム内のビューのトップ位置を示します。
view_width[0..7] ビューの幅(ピクセル数で)を示します。
view_height[0..7] ビューの高さ(ピクセル数で)を示します。
view_x[0..7] スクリーン上のビューのx座標の位置を示します。
view_y[0..7] スクリーン上のビューのy座標の位置を示します。view_hborder[0..7] 可視オブジェクトの上下枠線のサイズ(ピクセル数で)を示します。
view_vborder[0..7] 可視オブジェクトの左右枠線のサイズ(ピクセル数で)を示します。
view_hspeed[0..7] ビューの横方向での最大速度を示します。
view_vspeed[0..7] ビューの縦方向での最大速度を示します。view_object[0..7] ビューに見えるべきオブジェクトのインスタンスを示します。多数のインスタンスの場合は、最初のは選ばれます。インスタンスidをこの変数に代入することができます。この場合はそのインスタンスが選ばれます。
ルームの最初の可視ビューでスクリーン上のイメージサイズが決まることに注意しましょう。ゲーム実行中にビューを変えると、スクリーンに入れなくなるおそれがあります。スクリーンサイズは動的に変わらないため、その変更を次の変数を使って手動で行わなければなりません。
screen_width スクリーン上のイメージの幅、つまり描画の領域です。ビューのない場合は、room_widthの値に等しくなります。
screen_height スクリーン上のイメージの高さ。
ご存じのように、一つのルームから他のルームへ移動するとき、遷移効果が指定できます。transition_kindの変数を使えば、ルーム変化無しでも次のフレームへの遷移効果が指定できます。この変数に1〜17の値を与えると、それに対応する遷移効果が使用されます(これはルームに指定できる遷移効果と同様です)。0の値は遷移効果無しを意味します。これは次回のフレームの表示に影響を与えます。次のルームに行く前にこれらの変数がコードで設定できます。
transition_kind 次のフレームの遷移効果を指定する(0〜13)
transition_time 遷移効果に使用したい総合時間(ミリ秒単位で)
transition_steps 遷移効果のステップ数
通常、各ステップ末にルームが再描画されます。それ以外ルームを再描画することは滅多にありません。あるのは、プログラムが制御を握るときだけです。たとえば、スリープ・モードに入る前に再描画が必要であり、また、実行中にメッセージを出してユーザーの入力を待つときにも再描画が必要です。これを行うために次の二つの関数があります。
screen_redraw() すべての描画イベントを呼び出して、ルームを再描画します。
screen_refresh() 現在のルーム・イメージでスクリーンをリフレッシュします(描画イベントを行いません)。
2番目の関数を理解するために、描画作業の理解が必要です。内部にイメージが用意され、このイメージ上に描画作業が行われます。このイメージはスクリーンに表示されず、すべての描画が終わった後、ステップ末にスクリーンがこのイメージに置き換えられます(これはダブル・バッファリングという)。上記の最初の関数は内部のイメージを再描画してスクリーン・イメージをリフレッシュします。第二番目の関数では、スクリーンのイメージしかリフレッシュしません。
描画用アクションあるいは関数は描画・イベント以外で使えないことは、この説明で理解できたのでしょうか。他のイベントは、内部のイメージ上にものを描きますが、スクリーンに表示されません。描画イベントが行われると、まずバックグランドが表示されますので、内部イメージに描画したものが削除されてしまいます。しかし、screen_refresh()を描画の後に使用すると、更新されたイメージがスクリーンに表示されます。このため、たとえば次のようなスクリプトでスクリーンにメッセージを出して、ユーザーのキー入力を待つことができます。
{
draw_text(screen_width/2,100,'Press any key to continue.');
screen_refresh();
keyboard_wait();
}
描画イベント以外に、描画しようとすると、ビューではなくイメージ上に描画しますので、使用した座標はビューないときと同じものになってしまいます。
気を付けてこの技術を使いましょう。まずこの技術をよく理解して、またリフレッシュ時間が短くはないことを覚えておきましょう。
サウンドは、ゲームの重要な部分です。サウンドを大きく分けるとバックグランド用のサウンドとサウンド効果が二つあります。バックグランド・サウンドは永遠に繰り返される長いmidi型のミュージックです。一方、サウンド効果は短いwave型のファイルです。即時効果を持たせるために、これらのファイルはメモリに格納されます。このため、その再生時間は長くはないように気を付けましょう。
サウンドはサウンド・リソースとしてゲームに追加されます。使用する名前は変数名の書式規則に従うものでなければなりません。サウンドには、サウンドのバッファ数が少々理解しにくい特徴があります。システムは一度にwave型の同一サウンドを一回しか再生できないため、再生中に同じサウンドを用いると再生中のサウンドは中止されます。これは余り望ましくない効果です。このため、ガン・ショットのようなサウンドを同時に多数用いるときは、同じサウンドを多数コピーして使用しなければなりません。この数を、サウンドのバッファ数といいます。バッファ数が多ければ、同時に再生できる数も増えます。しかし、これに伴ってメモリの使用も増加します。このため、その使用に注意が必要です。ゲーム・メーカーはいつも最初の使用可能バッファを使います。ですから、数を指定すれば、あとは余り心配しなくてもよいです。
サウンド関連の基本関数は5つです。二つは再生用であり、一つはサウンドが再生中かどうかをチェックするもので、他の二つはサウンドをストップするためのものです。これらすべてがサウンドのインデックスを使います。サウンドの名前をサウンドのインデックスとなります。インデックスを変数に格納して使うこともできます。
sound_play(index) 指定されたサウンドを一回再生します。
sound_loop(index) 指定されたサウンドを永遠に再生します。
sound_stop(index) 指定されたサウンドを停止します。共有のindexのサウンドのとき、すべてが停止されます。
sound_stop_all() サウンドすべてが停止されます。
sound_isplaying(index) 指定されたサウンドは生成中か否かを知らせます。
この他のサウンド効果も使えます。しかし、waveファイルのみ対応になります。特別なサウンド効果が使用したいときは、サウンド・プロパティのアドバンス・タッブにある妥当のチェック・ボックスをチェックしなければなりません。サウンド効果を使用するサウンドはそれをしないサウンドよりシステムのリソースを使うことに注意しましょう。以下に示す関数(コール)を使うときのみ、該当のボックスをチェックしましょう。サウンド効果が三あります。まず、ボリュームが変更できます。0はサウンドをオフにします。1は元の音量になります(これより大きな音量が設定できません)。サウンドが流されてくる方向(パンという)も制御できます。0は左から、1は右から、0.5はデフォルトで、真ん中からを意味します。これはパンニングといい、たとえばものが左から右に移動しているような効果が簡単に実現できます。最後に、サウンドの再生の周期が変えられます。これは、エンジンのスピードを表現するには使います。0は一番遅い周期、1は一番早い周期となります。
sound_volume(index,value) サウンドのボリュームを変えます(0は小さい、1は大きい)。
sound_pan(index,value) サウンドのパンを変えます(0は左、1は右)。
sound_frequency(index,value) サウンドの再生の周期を変えます(0は遅い、1は速い)。
サウンドは結構複雑なものです。Midi型のファイルは標準のマルチメディア・プレイヤーで再生されます。ただし、一回で一つのmidiファイルしか再生できないし、効果サウンドがサポートされていません。ウエーブ(wave)型ファイルの再生にはゲーム・メーカーがDirectSoundを使用しますので、すべてのウエーブ・ファイルはメモリに格納され、そのファイルには効果を持たせることができます。ゲーム・メーカーはその他のサウンド・ファイルも特にMP3ファイルを指定されれば、再生しようとします。このとき、標準のマルチメディア・プレイヤーを使用します。しかし、これは使えるかどうかはシステムやインストールされているソフトに依存します。このため、配布するゲームには、MP3ファイルを使用しないようにしてください。
CDから音楽を再生するための関数が幾つあります。
cd_init() 他の関数を使用する前に呼び出すべき関数です。また、CDが変えられたときに呼び出すべきです(または時々呼び出しましょう)。
cd_present() CDが挿入されているかを返します。
cd_number() CD上のトラック数を返します。
cd_playing() CDが再生中かを返します。
cd_paused()
CDが一時停止かを返します。
cd_track() 現在のトラック番号を返します(1は最初のトラック)。
cd_length()
CDの総合再生時間をミリ秒単位で返します。
cd_track_length(n) CDのn番目のトラックの再生時間をミリ秒単位で返します。
cd_position() CD上の現在の位置をミリ秒単位で返します。
cd_track_position() 現在のトラック上の現在の位置をミリ秒単位で返します。
cd_play(first,last) トラックからlastトラックまでCDの再生を指示します。全曲の再生を指定するには1と1000を使いましょう。
cd_stop() 再生を止める。
cd_pause() 再生を一時停止します。
cd_resume()
再生を再開始します。
cd_set_position(pos) CD上の位置をミリ秒単位で設定します。
cd_set_track_position(pos) 現在のトラック上の現在の位置をミリ秒単位で設定します。
cd_open_door() CDのトレイを開きます。
cd_close_door() CDのトレイを閉めます。
ウインドウのマルチメディア機能をアクセスするために次の関数があります。
MCI_command(str) この関数はMCI(Media Control Interface)を使ってウインドウのマルチメディア・システムに命令列を送ります。返し列を返します。これで色々なマルチメディア装置を制御することができます。ウインドウの資料を参考にして、該当の命令の使用を調べましょう。たとえば、MCI_command('play
cdaudio from 1')の命令でCDを再生することができます(他の命令で初期化が行った後)。この関数はアドバンス使用だけです。
数多くのゲームはスプラッシュ画面(スクリーン)を使用します。これらのスクリーンはビデオやイメージあるいはテキストを表示します。これらの画面は、ほとんどの場合は、ゲーム開始、レベルの始まりに、またはゲーム終了時に用いられます。ゲーム・メーカーでは、これらの画面はいつでも使用できます。スプラッシュ・スクリーンが表示されるとき、ゲームは一時的に停止します。このような画面の使用には次の関数を使います。
show_text(fname,full,backcol,delay) テキスト・スプラッシュ画面を表示します。fnameはテキストのファイル名(.txtまたは.rtf)です。このファイルをゲームのフォルダに手動でおかなければなりません。スタンド・アロンのゲームの作成のときもこのファイルの追加は忘れてはいけません。fullは画面全体の使用を示します。backcolはバックグランドの色で、delayはゲームに戻るまでの遅延時間です(プレイヤーがいつでもゲームの画面にクリックすればゲームに戻ります)。
show_image(fname,full,delay) イメージ・スプラッシュのスクリーンを表示します。fnameはビデオのファイル名です (.bmp, .jpgと.wmfのみ)。このファイルをゲームのフォルダに手動でおかなければなりません。fullは画面全体の使用を示します。delayはゲームに戻るまでの遅延時間です。
show_video(fname,full,loop) ビデオ・スプラッシュのスクリーンを表示します。fnameはビデオのファイル名です (.avi,.mpg)。このファイルをゲームのフォルダに手動でおかなければなりません。fullは画面全体の使用を示します。loopはビデオをループで再生することを示します。
show_info() ゲームの情報用のフォームを表示します。
load_info(fname) ゲームの情報をfnameのファイルからロードします。このファイルはrtf形式でなければなりません。これで色々な場面に色々なヘルプファイルの表示が可能になります。データ・ファイルのリソースでこれらのファイルの追加ができます。
メッセージの表示や、質問、メニューやダイヤログなどのようなポップ・アップを表示する次の関数があります。
show_message(str) strの文字列をメッセージとしてダイアログ・ボックスを表示します。
show_message_ext(str,but1,but2,but3) strの文字列をメッセージとして3つのボタンのダイアログ・ボックスを表示します。But1、but2、but3はボタンのテキストです。空白の文字列はそのボタンを表示しないを意味します。&と文字を使うと、その文字はボタンのショットカットになります。この関数は押されたボタンの番号を返します(Escが押されると、0を返します)。
show_question(str) 質問を表示します。ユーザーがyesを選んだときtrueを返し、yesではないとき、falseを返します
get_integer(str,def) ダイアログ・ボックスで値(整数)を要求します。strはメッセージです。defはデフォルトの値です。
get_string(str,def) ダイアログ・ボックスで文字列を要求します。strはメッセージです。defはデフォルトの文字列です。
message_background(back) 上記の関数のポップアップ・ボックスのバックグランド・イメージを設定します。backはゲームで定義されたバックグランドの一つでなければなりません。
message_button(spr) ポップアップ・ボックスのボタンのスプライトを設定します。これは三つのイメージで構成されていなければなりません。最初のは、ボタンが押されてないしマウスはその上にないときのイメージです。2番目は、ボタンが押されてないがマウスはその上にあるときのイメージです。3番目はボタンが押されたときのイメージです。
message_text_font(name,size,color,style) ポップアップ・ボックスのテキストのフォントを設定します。
message_button_font(name,size,color,style) ポップアップ・ボックスのボタンのフォントを設定します。
message_input_font(name,size,color,style) ポップアップ。ボックスの入力フィルドのフォントを設定します。
message_mouse_color(col) ポップアップ・ボックスのボタン上にマウスが置かれるときのボタンのフォント色を設定します。
message_input_color(col) ポップアップ・ボックスの入力フィルドのバックグランド色を設定します。
message_caption(show,str) ポップアップ・ボックスのカプションを設定します。枠線の表示(1)・非表示(0)をshowで指定します。枠線が表示されるとき、strはそのカプションを指定します。
message_position(x,y) スクリーン上のポップアップ・ボックスの位置を設定します。
message_size(w,h) ポップアップ・ボックスの大きさを固定します。幅を0に設定すると、イメージの幅が使われます。高さを0に設定すると、メッセージの行数に高さが合わせられます。
show_menu(str,def) ポップアップ・メニューを表示します。strはメニューのテキストです。これは縦棒「|」で区切られたメニューの項目です。たとえば、str = 'menu0|menu1|menu2'その一つを例示します。最初の項目が選択されたとき、0が返され、その次の項目の場合は1、0から始まる項目の位置が返されます。選択がない場合は、defのデフォルト値が返されます。
show_menu_pos(x,y,str,def) 上記関数と同様ですが、x,y座標にポップアップ・メニューを表示します。
get_color(defcol) 色をプレイヤーに要求します。defcolはデフォルトの色です。ユーザがcancelを押すと、−1の値が返されます。
get_open_filename(filter,fname) 指定したフィルターで開くファイル名をプレイヤーに要求します。フィルターの書式は:'name1|mask1|name2|mask2|…'です。つまり、セミコロンで区切られた色々なオプションを含んだマスクです。「*」はいずれの文字列を意味します。例: 'bitmaps|*.bmp;*.wmf'。ユーザがcancelを押すと、空列が返されます。
get_save_filename(filter,fname) 指定したフィルターで保存されるファイル名を要求します。ユーザがcancelを押すと、空列が返されます。
get_directory(dname) ディレクトリ名を要求します。dnameはデフォルト名です。ユーザがcancelを押すと、空列が返されます。
get_directory_alt(capt,root) もう一つのディレクトリ要求方法。captは表示されるカプションです。rootはディレクトリ・ツリーのルートです。空白を与えるとツリー全体が表示されます。ユーザがcancelを押すと、空列が返されます。
show_error(str,abort) エラー・メッセージを表示します(若しくはログ・ファイルにこれを保存します)。abortはゲームは終了すべきかを表示します。
最上位得点のリストはゲーム毎で保持される特別なポップ・アップです。これに関連の次の関数が使用できます。
highscore_show(numb) スコアー表を示します。numbは新スコアーです。これが現行スコアーよりよいものであれば、スコアー表に入れられ、プレイヤーが氏名を記入することができます。−1の値を使うと、現在のリストだけ表示されます。
highscore_show_ext(numb,back,border,col1,col2,name,size) スコアー表を示します。numbは新スコアーです。これが現行スコアーよりよいものであれば、スコアー表に入れられ、プレイヤーが氏名を記入することができます。−1の値を使うと、現在のリストだけ表示されます。backは使用するバックグランド・イメージを指定します。borderは枠線を表するか否かを指定します。col1は新スコアーの色、col2はその他のスコアーの色です。nameは使用するフォントの名前です。sizeはフォントのサイズです。
highscore_clear() スコアー・リストをクリアします。
highscore_add(str,numb) strの名前のプレイヤーをnumbというスコアーでリストに追加します。
highscore_add_current() 現在のスコアーをリストに追加します。ユーザにその氏名が要求されます。
highscore_value(place) placeの順位(1〜10)にある人のスコアーを返します。これは自分のスコアー・リストを表示するために使えます。
highscore_name(place) place(1〜10)の順位にある人の名前を返します。
draw_highscore(x1,x2,x3,x4) スコアー・リストを現在のフォントで現在のルームに指定されたボックスに表示します。
ゲームが排他的グラフィックス・モードで実行されているときは、これらのポップアップメニューを表示させることができないことにご注意願います。
ゲーム・メーカーではスプライト、サウンド、データ・ファイル、オブジェクト等のリソースを定義することができます。この章ではこれらのリソースを対象にする関数について述べます。その前に、次の説明をよく読んでおいてください。リソースを変更すると元のデータが失われます!。そのリソースを使用するすべてのインスタンスが影響を受けます。たとえば、スプライトを変えると、それを使用するインスタンスはその時点から変更後のスプライトを使用します。ルームのリスタートやゲームのリスタートはリソースを元通りにしません。また、ゲームの状態をセーブするときは変更されたリソースは保存されません。このため、ゲームをロードするときはリソースを妥当な状態に戻すのを自分でやらなければいけません。
次の関数はスプライトについて情報を提供します。
sprite_exists(ind) インデックスindのスプライトが存在するか否かを返します。
sprite_get_name(ind) インデックスindのスプライト名を返します。
sprite_get_number(ind) インデックスindのスプライトのサブイメージ数を返します。
sprite_get_width(ind) インデックスindのスプライトの幅を返します。
sprite_get_height(ind) インデックスindのスプライトの高さを返します。
sprite_get_transparent(ind) インデックスindのスプライトが透明か否かを返します。
sprite_get_xoffset(ind) インデックスindのスプライトのxオフセットを返します。
sprite_get_yoffset(ind) インデックスindのスプライトのyオフセットを返します。
sprite_get_bbox_left(ind) インデックスindのスプライトのバウンディング・ボックスの左サイドを返します。
sprite_get_bbox_right(ind) インデックスindのスプライトのバウンディング・ボックスの右サイドを返します。
sprite_get_bbox_top(ind) インデックスindのスプライトのバウンディング・ボックスのトップ・サイドを返します。
sprite_get_bbox_bottom(ind) インデックスindのスプライトのバウンディング・ボックスのボトム・サイドを返します。
sprite_get_precise(ind) インデックスindのスプライトが厳密な衝突の計算を使用するか否かを返します。
sprite_get_videomem(ind) インデックスindのスプライトがビデオ・メモリを使用するか否かを返します。
sprite_get_loadonuse(ind) インデックスindのスプライトが使用のときだけロードされるか否かを返します。
スプライトは沢山のメモリを占めます。描画時間を短くにするためにスプライトをビデオ・メモリに保存しなければなりません。第14章に示したように、どれがビデオ・メモリに保持することを指定できます。また、必要に応じたロードも指定可能です。これらのスプライトはレベルの終了時点で捨てられます。コードを用いればこれがある程度制御できます。このため次の関数があります。
sprite_discard(numb) スプライト用のビデオ・メモリを解放します。スプライトのload-on-useプロパティが設定されていれば、完全に削除されます。設定のない場合は、そのコピーがメイン・メモリに保存され、(通常このメモリが大きいからです)再び必要であればそこからリストアされます。
sprite_restore(numb) スプライトを(ビデオ)メモリにリストア(再び保存)します。通常、これは必要に応じて自動的に行われます。しかし、これはload-on-useプロパティが設定されて、スプライトが大きいとき、小さなhick-upを起こします。このため、たとえばルームの始まりでこれを意図的に使用します。
discard_all() load-on-useプロパティが設定されているすべてのスプライト、バックグランドおよびサウンドを削除します。
ゲームは沢山の異なる大きなスプライト・イメージを使用すると、ゲームファイルを大きくして、そのロード時間が長くなります。また、必要なときこれらをメモリに保存したい場合は、必要なメモリ容量が大きくなります。もう一つの選択は、スプライトのイメージ(.bmp、.jpg、あるいは.gif形式の)を別にして、ゲーム中にロードするように、ゲームと一緒に配布することができます。このため次の三つの関数があります。
sprite_add(fname,imgnumb,precise,transparent,videomem,loadonuse,xorig,yorig) ファイルfnameにあるイメージをスプライト・リソースに追加します。.bmp、.jpg、あるいは.gif形式のものしか扱えません。.bmpか.jpgのファイル型の場合は、サブイメージを含むストリップが使用できます。このとき、imgnumの番号を使います(1は単一のイメージを意味します)。.gifまたはアニメイテッドgifの場合はこの引数を使いません。その代わりにgifファイルのイメージ数を使用します。preciseは、衝突時に厳密な計算を行うか行わないかを指定します。transparentは、イメージが半透明かそうでないかを指定し、videomemはスプライトがビデオメモリに保存するかしないかを指定し、loadonuseは必要に応じたロードが行うか行わないかを指定します。最後のxorigとyorigはスプライトのオリジンを指定します。この関数は新しいスプライトのインデックス番号を返しますので描画、またはインスタンスのsprite_indexに割り当てることができます。エラーの場合は−1の値が返されます。
sprite_replace(ind,fname,imgnumb,precise,transparent,videomem,loadonuse,xorig,yorig) 上記の関数と同様ですがindインデックス番号のスプライトがfnameにあるスプライトのイメージに変えられます。関数の返す値は置き換えに成功したかしなかったかに該当する値です。
sprite_delete(ind) indインデックス番号のスプライトを削除してそのメモリを解放します(元に戻すことができません)。
注意:プレイ中にゲームをセーブすると、追加されたスプライトあるいは置き換えられたスプライトはセーブしたゲームと一緒に保存されません。ですから、再ロードのときそれらはもう現れません。また、著作権に関わる問題で、gifファイルは無料でないアプリケーションと配布することができません。このため、この形式のファイルの使用を避けましょう。
次の関数はサウンドの情報を示します。
sound_exists(ind) インデックスindのサウンドが存在するか否かを返します。
sound_get_name(ind) インデックスindのサウンド名を返します。
sound_get_kind(
sound_get_buffers(ind) インデックスindのサウンドのバッファ数を返します。
sound_get_effect(ind) インデックスindのサウンドが特別効果を許すか否かを返します。
sound_get_loadonuse(ind) インデックスindのサウンドが必要に応じてロードされるか否かを返します。
サウンドは沢山のリソースを使います。また、数多くのシステムは限られた数のサウンドしか再生できません。規模の大きいゲームを開発すると、メモリにあるサウンドを制御したくなります。load-on-useオプションを使用すれば、サウンドは使用されるときのみ、ロードさせることができます。しかし、サウンドが初めて再生されるとき雑音(hick-up音)を起こします。大きなルームの使用もこれを悪化します。制御をより細かく行うために次の関数が使えます。
sound_discard(index) サウンドの使用したメモリを解放します。
sound_restore(index) サウンドを再びメモリに格納します。
discard_all() load-on-useオプションをセットされたスプライト、バックグランドおよびサウンドをすべて削除します。
作成したゲームがバックグランド・ミュジックのような色々な複雑なサウンドを使う場合は、これらをゲームと一緒に保存しないようにしましょう。保存すると、ゲームファイルは非常に大きくなります。それより、別途で提供してゲーム中にロードするようにしましょう。これはゲームのロード時間を短縮します。このために次の関数があります。
sound_add(fname,buffers,effects,loadonuse) サウンド・リソースをゲームに追加します。fnameは追加されるサウンドのファイル名です。buffersは使用するバッファ数です。effectsは効果を使用するか否かを、loadonuseはサウンドが内部メモリに保存するか否かを示します(真か偽で)。関数はサウンドのインデックスを返します。これがサウンドの再生に使用できます(エラー、たとえば、ファイルが存在しないときは−1が返されます)。
sound_replace(index,fname,buffers,effects,loadonuse) 上記と同様なものですが、新規サウンドではなく、indexのサウンドがfnameのサウンドに変えられます。元のサウンドのメモリが解放されます。操作が正か否かを示す値が返されます。
sound_delete(index) 指定されたサウンドを削除し、そのメモリを解放します。この操作が復帰不能です。
注意:プレイ中にゲームをセーブすると、追加されたサウンドあるいは置き換えられたサウンドはセーブしたゲームと一緒に保存されません。ですから、再ロードのときそれらはもう現れません。
次の関数がバックグランドについて情報を示します。
background_exists(ind) インデックスindのバックグランドが存在するか否かを返します。
background_get_name(ind) インデックスindのバックグランド名を返します。
background_get_width(ind) インデックスindのバックグランドの幅を返します。
background_get_height(ind) インデックスindのバックグランドの高さを返します。
background_get_transparent(ind) インデックスindのバックグランドが透明か否かを返します。
background_get_videomem(ind) インデックスindのバックグランドがビデオ・メモリを使用するか否かを返します。
background_get_loadonuse(ind) インデックスindのバックグランドが必要に応じてロードされるか否かを返します。
バックグランド・イメージは沢山のメモリを占めます。これらを高速に描画するためにビデオ・メモリに保存する必要があります。第18章に示したようにビデオ・メモリに保持されるバックグランドが指定できます。また、必要に応じたロードの指定も可能です。これらのバックグランドは、レベルの終了時に削除されます。この過程をある程度コードで次の関数を用いれば制御できます。
background_discard(numb) バックグランド・イメージ用のビデオ・メモリを解放します。バックグランドのload-on-useプロパティが設定されていれば、完全に削除されます。設定のない場合は、そのコピーがメイン・メモリに保存され、(通常このメモリ大きいからです)再び必要であればそこからリストアされます。
background_restore(numb) バックグランド・イメージを(ビデオ)メモリにリストア(再び保存)します。通常、これは必要に応じて自動的に行われます。しかし、これはload-on-useプロパティが設定されて、バックグランドが大きいのととき、小さなhick-upを起こします。このため、たとえばルームの始まりでこれを意図的に使用します。
discard_all() load-on-useプロパティが設定されているすべてのスプライト、バックグランドおよびサウンドを削除します。
ゲームは沢山の異なるバックグランド・イメージを使用すると、ゲームファイルを大きくして、そのロード時間が長くなります。また、必要なときこれらをメモリに保存したい場合は、必要なメモリ容量が大きくなります。もう一つの選択は、スプライトのイメージ(.bmp、.jpg、あるいは.gif形式の)を別にして、ゲーム中にロードするように、ゲームと一緒に配布することができます。このため次の三つの関数があります。この方法はプレイヤーにバックグランドを選ばせたいときも使います。また、ゲームのイメージを保存してその後にそれをバックグランドとして使うことがあります(例:ペインティング・ソフトのプログラム)。該当関数は次のものです。
background_add(fname,transparent,videomem,loadonuse) ファイルfnameにあるイメージをバックグランド・リソースに追加します。.bmp、および.jpg、(あるいは.gif形式)のものしか扱えません。transparentは、イメージが半透明かそうでないかを指定し、videomemはバックグランドがビデオメモリに保存するかしないかを指定し、loadonuseは必要に応じたロードが行うか行わないかを指定します。この関数は新しいバックグランドのインデックス番号を返しますので描画、またはインスタンスのbackground_index[0]に割り当てて、現在のルームに表示することができます。エラーの場合は-1の値が返されます。
background_replace(ind,fname,transparent,videomem,loadonuse) 上記の関数と同様ですがindインデックス番号のバックグランドがfnameにあるバックグランドのイメージに変えられます。関数の返す値は置き換えに成功したかしなかったかに該当する値です。現在表示されているバックグランドも入れ替えられます。
background_delete(ind) indインデックス番号のバックグランドを削除してそのメモリを解放します(元に戻すことができません)。
注意:プレイ中にゲームをセーブすると、追加されたバックグランドあるいは置き換えられたバックグランドはセーブしたゲームと一緒に保存されません。ですから、再ロードのときそれらはもう現れません。また、著作権に関わる問題で、gifファイルは無料でないアプリケーションと配布することができません。このため、この形式のファイルの使用を避けましょう。
次の関数はパスについて情報を示します。
path_exists(ind) インデックスindのパスが存在するか否かを返します。
path_get_name(ind) インデックスindのパス名を返します。
path_get_length(ind) インデックスindのパスの長さを返します。
path_get_kind(ind) インデックスindのパスの接続タイプ(0=直線 1=滑らか)を返します。
path_get_end(ind) インデックスindのパスの末に起こること(0=停止、1=スタートへジャンプ、2=スタートに接続する、3=逆方向、4=続ける)を返します。
次の関数はスクリプトについて情報を示します。
script_exists(ind) インデックスindのスクリプトが存在するか否かを返します。
script_get_name(ind) インデックスindのスクリプト名を返します。
script_get_text(ind) インデックスindのスクリプトのテキストを返します。
次の関数はデータ・フィルについて情報を示します。
datafile_exists(ind) インデックスindのデータ・ファイルが存在するか否かを返します。
datafile_get_name(ind) インデックスindのデータ・ファイル名を返します。
datafile_get_filename(ind) インデックスindのデータ・ファイルのファイル名を返します。
データ・ファイルを自動的にゲーム開始時に輸出(エスポート)しないときは、次の関数が使えます。
datafile_export(ind,fname) 指定されたindデータ・ファイルをfnameファイル名のファイルへエスポーとします(デフォルトでこれを行わないとき実行されます)。
datafile_discard(ind) 指定されたindデータ・ファイルのメモリを解放します。
次の関数はオブジェクトについて情報を示します。
object_exists(ind) インデックスindのオブジェクトが存在するか否かを返します。
object_get_name(ind) インデックスindのオブジェクト名を返します。
object_get_sprite(ind) インデックスindのオブジェクトのデフォルトのスプライトのインデックスを返します。
object_get_solid(ind) インデックスindのオブジェクトがデフォルトで個体か否かを返します。
object_get_visible(ind) インデックスindのオブジェクトがデフォルトで透明か否かを返します。
object_get_depth(ind) インデックスindのオブジェクトの深さを返します。
object_get_persistent(ind) インデックスindのオブジェクトがパシステントか否かを返します。
object_get_mask(ind) インデックスindのオブジェクトのマスクのインデックスを返します(特別なマスクがない場合は−1が返されます)。
object_get_parent(ind) インデックスindのオブジェクトの親オブジェクトのインデックスを返します(親がない場合は−1が返されます)。
object_is_ancestor(ind1,ind2) インデックスind2のオブジェクトがind1のオブジェクトの祖先であるか否かを返します。
次の関数はルームについて情報を示します。
room_exists(ind) インデックスindのルームが存在するか否かを返します。
room_get_name(ind) インデックスindのルーム名を返します。
ルームがゲーム中に変わるため、ルームの内容を変えるために他のルーチンがあります。
より上級レベルのゲームではゲームと一緒に配布されたファイルからデータを読み込みたいことがあります。たとえば、ゲーム中の幾つかの場面で起こることを指定するファイルを作成することができます。また、ゲームの再使用のとき関連の情報(現在のルームなど)を保存したい場合もあります。このために、次の関数があります。
file_exists(fname) 指定したfnameのファイルがある(true)かない(false)を返します。
file_delete(fname) 指定したfnameファイルを削除します。
file_rename(oldname,newname) ファイルの名前oldnameをnewnameに変えます。
file_copy(fname,newname) ファイルfnameをnewnameにコピーします。
file_open_read(fname) 指定されたfnameファイルを読み出し専用に開きます。
file_open_write(fname) 指定したfnameファイルを書き込み可能にして開きます。ファイルが存在しない場合は、新規作成します。
file_open_append(fname) 指定したfnameファイルを書き込み追加可能にして開きます。ファイルが存在しない場合は、新規作成します。
file_close() 現在のファイルを閉じます(ファイルが開いている場合は最後に必ずこれを使用して下さい)。
file_write_string(str) 現在開いてあるファイルにstrの文字列を書き込みます。
file_write_real(x) 現在開いてあるファイルにxの実数を書き込みます。
file_writeln() ファイルに改行コードを書き込みます。
file_read_string() ファイルから行末までの文字列を読み込み、これを返します。
file_read_real() ファイルから実数を読んでその値を返します。
file_readln() 現在の行から飛び出して次の行の先頭に移動します。
file_eof() ファイル末に着いたことを知らせます。
directory_exists(dname) 指定されたディレクトリの存在の有無を知らせます。
directory_create(dname) 指定されたディレクトリが存在しないとき新規作成します(パスを含めた作成に成ります)。
file_find_first(mask,attr) 指定されたmaskおよびattrの特徴を満たす最初のファイルの名前を返します。そのファイルが存在しないときは空列を返します。マスクにパスおよびワイルド文字が記入できます。たとえば、‘C:\temp\*.doc’が可能です。アトリビュートは他みたいファイルの特徴を指します(通常、マスクを満たすファイルが返されます)。次の定数を使えばみたいファイルを指定することができます。
fa_readonly 読み出し専用ファイル
fa_hidden 非表示ファイル
fa_sysfile システム・ファイル
fa_volumeid volume-idファイル
fa_directory ディレクトリ
fa_archive アーカイブ・ファイル
file_find_next() 指定されたマスクと特徴を満たす次のファイルを返します。そのファイルが存在しないときは空列が返されます。
file_find_close() ファイルを取り扱った後必ずこの関数を呼んでメモリを解放しましょう。
file_attributes(fname,attr) 指定されたfnameのファイルは指定された特徴を持つか否かを返します。上記の定数の組み合わせを使います。
環境設定(Preferences)で安全モードがチェックされていると、上記の幾つかの関数はパス指定ができなくなります。このとき、アプリケーション・フォルダー内のファイルのみ書き換えられます。
次の読み出し専用変数は役に立ちます。
game_id* ゲームの唯一のidです。唯一のファイル名が必要のときこれが使用できます。
working_directory* ゲームのワーキング・ディレクトリ(最後のバックスラッシュを除いた文字列)
temp_directory* ゲーム用の一時的なディレクトリ。一時的なファイルをここで保存できます。ゲーム終了時にこれらは削除されます。
場合によっては、ゲーム中にペレイヤーにコマンド・ラインの入力を許してあげたいことがあります(たとえば、トリックや特別モードの作成のため)。その引数を得るために次の関数が使えます。
parameter_count() コマンド・ラインの引数の数を返します(プログラムはその一つであることに注意)。
parameter_string(n) n番目のコマンド・ラインの引数を返します。最初の引数は0です。これはプログラム名です。
ゲーム実行の間に少量の情報を保存したいときは、ファイル使用より簡単方法があります。registry(登録)が使えます。このregistryはウインドウスが完備して、プログラムの設定に使用されている大きなデータベースです。その各項目(entry)は名前と値をもっています。この両方、つまり文字列と実数が次の関数で使用できます。
registry_write_string(name,str) registryにnameの名前とstrの値で一つの項目を生成します。
registry_write_real(name,x) registryにnameの名前とxの(実数)値で一つの項目を生成します。
registry_read_string(name) nameの名前で保存されている文字列を返します(nameが存在しないとき空列が返されます)。
registry_read_real(name) nameの名前で保存されている(実数)値を返します(nameが存在しないとき0が返されます)。
registry_exists(name) nameの名前があるかないかを返します。
実は、registryの値はキーでグループ化されています。上記の関数はゲームのために作成されたキーの下にある値を使います。作ったプログラムがこれらの値で実行環境の情報を収集することができます。その他のキーの値も読めますし、書き換えます。書き換えを行うと簡単に自分のシステムを破壊することができますので要注意(システムに障害を与えるため、書き換えが安全モードで禁止です)。キーもグループ化されています。次の関数はHKEY_CURRENT_USERのグループのキーでしか使えません。ルートのグループが変えられます。ですから、たとえば現在のtemp(テンポラリ)ディレクトリを取得したいときは、次の命令を使います。
path = registry_read_string_ext('/Environment','TEMP');
次の関数があります。
registry_write_string_ext(key,name,str) 指定されたキー(key)の下でnameという名前の文字列をregistryに作成します。
registry_write_real_ext(key,name,x) 指定されたキー(key)の下でnameという名前の実数をregistryに作成します。
registry_read_string_ext(key,name) 指定されたキー(key)の下でnameという名前がもっている文字列を返します(nameが存在しないとき空列が返されます)。
registry_read_real_ext(key,name) 指定されたキー(key)の下でnameという名前がもっている実数を返します(nameが存在しないとき0が返されます)。
registry_exists_ext(key,name) 指定されたキー(key)の下でnameという名前があるかないかを返します。
registry_set_root(root) 他のルーチンのルートを設定します。次の値を使いましょう。
0 = HKEY_CURRENT_USER
1 = HKEY_LOCAL_MACHINE
2 = HKEY_CLASSES_ROOT
3 =
HKEY_USERS
ゲーム・メーカーが外部のプログラムを起動することもできます。このためにexecute_programおよびexecute_shell二つの関数があります。execute_programの関数は引数を用いてプログラムを実行し、その終了を待つことができます(待つとき、ゲームを一時停止することができます)。execute_shellの関数はファイルを開きます。このファイルは関連のあるhtmlやワードなどのようなファイルかプログラムです。この関数は実行終了が待てませんのでゲームが一時停止しません。
execute_program(prog,arg,wait) progのプログラムをargの引数で実行します。waitは終了を待つか否かを指定します。
execute_shell(prog,arg) シェルでプログラム(ファイル)を実行します。
ユーザーが安全モードを環境設定(preferences)で設定したとき、この両方の関数は機能しません。次の読み出し専用変数でこれがチェックできます。
secure_mode* ゲームが安全モードになっているか否かを示します。
コンピュータを相手にしてゲームをプレイするのは楽しいですが、人間を相手にしたのはもっと楽しいです。このようなゲームは非常に簡単に実現できます。コンピュータを相手にしたときに必要となる人工知能(AI)の相手を実現しなくてもよいです。もちろん、同一のコンピュータで異なるキーの組み合わせでもう一人の人と対戦したりすることができるが、それよりおもしろいのは相手は別のコンピュータを使うことです。また、もっといいのは相手は海外の所にいながら対戦できることです。ゲーム・メーカーはマルチプレイヤーをサポートしています。同期できて、待つ時間の短くて効率のよいマルチプレイヤー・ゲームの作成が簡単作業ではありません。この章は可能な作業等を簡潔に説明します。ゲーム・メーカーのwebサイトにもう少しの情報を提供するチュートリアルがあります。
コンピュータ間の通信を可能にするために接続のプロトコルが必要です。他のゲームと同様にゲーム・メーカーでは四つの接続の仕方が使用できます。これは、IPX、TCP/IP、モデム、およびシリアルです。IPXの接続(実は一つのプロトコル)はユーザから見えない形で動作します。同じローカル・ネットワークの人とのプレイには使用できます。使用するためにコンピュータにインストールされていなければなりません(動かない場合は、ウインドウスのマニュアルを参照して下さい。または、コントロール・パネルのネットワークの設定でIPXを追加して下さい)。TCP/IPはインターネットのプロトコルです。インターネット上の他人とのプレイに使用できます。このとき相手のIPアドレスが必要です。ローカル・ネットワーク上ではIPアドレスなしでも使用できます。モデムの接続はモデム経由で行われます。この場合は、モデム設定用の文字列と電話番号を指定しなければいけません。シリアル接続では直接にコンピュータとコンピュータをつなぎます。この場合はポート番号を設定しなければなりません。GMLではこれの設定を行うために次の四つの関数が用いられます。
mplay_init_ipx() ipxの接続を初期化します。
mplay_init_tcpip(addr) TCP/IPの接続を初期化します。addrはIPのアドレスかwebアドレスを含む文字列です。たとえば、www.gameplay.comや123.123.123.12(そして、:12のようなポート番号)が使えます。セッションに参加するときはアドレスを設定しなければなりません(後述を参照)。ローカル・ネットワークではアドレスが不要です。
mplay_init_modem(initstr,phonenr) inistrでモデムを初期化します(inistr文字列は空でもよい)。ダイヤルする番号(例:0201234567)をphonenrで指定します。セッションに参加するときはこの番号は必要です。
mplay_init_serial(portno,baudrate,stopbits,parity,flow) シリアル接続を初期化します。portnoはポートの番号(1〜4)であり、baudrateは転送速度(100〜256K)であり、stopbitsはストップ・ビット数(0は1ビット、1は1.5ビット、2は2ビット)であり、parityは奇遇数のチェックの仕方(0は無し、1は奇数、2は偶数、3はマーク使用)を指定します。Flowはフロー制御を指定します(0は無し、1はxon/xoff、2はrts、3はdtr、4はrtsとdtr)。成功したかどうかを戻り値です。
記述例:mplay_init_serial(1,57600,0,0,4) 。0を最初の引数にすると、ダイヤログが現れ、プレイヤーが設定が変更できます。
ゲームは上記の関数のいずれかの一つのみを一回だけ呼びます。何れの関数は設定に成功したか否かを知らせます。失敗はプロトコルが使用不能場合に起こります。使用可能な接続があるかどうかをチェックするには次の関数が用いられます。
mplay_connect_status() 現在の使用可能な接続の表す番号を返します。0は接続無し、1はIPX接続を、2はTCP/IP接続を、3はモデム接続を、4はシリアル接続を使用可能と意味します。
接続のセッションを終わらせるために次の関数を用います。
mplay_end 現在の接続を終了させます。
次の関数で相手に自分のIPアドレスを知らせることができます。
mplay_ipaddress() 自分のコンピュータのIPアドレスを返します(たとえば、123.123.123.12のような文字列が返されます)。これがスクリーンのどこかに表示できます。この関数は遅いので、頻繁に使用しないで下さい。
ネットワークに接続すると、そのとき同ネットワークに幾つかのゲームが行われている可能性があります。ここではこれらをセッションといいます。これらのセッションは異なるゲームか同一のゲームであるかもしれません。ゲームはネットワーク上で自分の存在を明確にしなければなりません。しかし、幸いにゲーム・メーカーがこれをやってくれます。ただし、ゲームのidをオプションで変えるとゲームのid(識別情報)が変わることを覚えておきましょう。これを使えば、ゲームの古い版のプレイヤーが新版のと対戦しないように設定できます。
新しいマルチプレイヤーゲームを開始したい場合は、新セッションを作成しなければなりません。このとき次の関数を使います。
mplay_session_create(sesname,playnumb,playername) 現在の接続上で新セッションを作成します。sesnameは新セッションの名前になります。playnumbは最大のプレイヤー数です(任意に設定したい場合は0を使用します)。playnameは自分のプレイヤー名です。作成の成功を表す値を返します。
ゲームの一つのインスタンスがセッションを作成しなければなりません。その他のインスタンスがセッションに参加するだけです。実は、これはもう少しい複雑ですが。まず、参加可能なセッションをみて、決めます。このために次の三つの重要な関数があります。
mplay_session_find() プレイヤーがまだ参加できるセッションを探して、その数を返します。
mplay_session_name(numb) numbという番号(0は最初のセッション)のセッション名を返します。これは前の関数の実行後にしか使えません。
mplay_session_join(numb,playername) numbで指定したセッションに参加させます(0は最初のセッション)。playernameはそのセッションでのあなたのプレイヤー名になります。参加に成功したかどうかを表す値を返します。
次の関数でセッション・モードを変えることができます。セッション作成の前に実行すべきです。
mplay_session_mode(move) セッションのホストコンピュータを別のコンピュータに移動するかどうかを設定します(現行のホストが終了時)。moveは真か偽(デフォルト)かの値を取ります。
現在のセッションの状態を調べるには次の関数を使います。
mplay_session_status() 現行のセッションの状態を返します。0はセッションがない、1は作成したセッション、2は参加したセッション。
プレイヤーが次の関数でセッションを終了することができます。
mplay_session_end()ends the session for this player.このプレイヤーのセッションを終了します。
セッションに参加する各ゲームは一つのプレイヤーになります。プレイヤーが名前をもちます。プレイヤー対応の関数には次のものがあります。
mplay_player_find() 現行のセッションのプレイヤー数を返します。
mplay_player_name(numb) numb番号のプレイヤー名を返します(0は最初のプレイヤーで、自分の番号になります)。これは前の関数の実行後にしか使えません。
mplay_player_id(numb) numb番号のidを返します(0は最初のプレイヤーで、自分の番号になります)。この関数も前の最初の関数の実行後にしか使えません。このidはメッセージの送受信に使います。
共有データの使用は、ゲームを同期させるには一番簡単な方法です。通信はバックグランド(見えないところ)で行われます。1万個の値が共用できます。ゲームの各成分はこれらにアクセスすることができます。ゲーム・メーカーは皆同じ値をみることを保証します。これらの値は実数か文字列です。このための関数が二つあります。
mplay_data_write(ind,val) ind(0〜10000)で指定された場所にvalという値(実数か文字列)を格納します。
mplay_data_read(ind) ind(0〜10000)で指定された場所に格納されている値(実数か文字列)を返します。初期値すべてが0です。
コンピュータ間のデータを一致(同期)させるために保証モード(遅い方)と保証無しモードが使えます。このモードの変更には次の関数を用います。
mplay_data_mode(guard) 保証モードを使うか否かを設定します。guardは真(デフォルト)か偽の値です。
ゲーム・メーカーでサポートされているのもう一つの通信仕組みはメッセージの送受信です。一つのプレイヤーがもう一つのプレイヤーかすべてのプレイヤーにメッセージを送ることができます。プレイヤーがメッセージをみて、それに対応したことをしたりすることができます。メッセージも保証モード(遅い)か保証無しモード(速い)で送られます。メッセージ専用関数には次のものがあります。
mplay_message_send(player,id,val) player(識別子か名前)のプレイヤー(0はすべてのプレイヤー)にvalというメッセージを送ります。idはメッセージの識別番号です。非保証モードの転送です。
mplay_message_send_guaranteed(player,id,val) player(識別子か名前)のプレイヤー(0はすべてのプレイヤー)にvalというメッセージを送ります。idはメッセージの識別番号です。保証モードの転送です。
mplay_message_receive(player) player(識別子か名前)のプレイヤー(0は何れのプレイヤー)から送られているメッセージ列から次のメッセージを受け取ります。メッセージかあったか否かを表す値を返します。新しいメッセージがあった場合は、次の関数が使用できます。
mplay_message_id() 最後に受信したメッセージの識別番号を返します。
mplay_message_value() 最後に受信したメッセージの値を返します。
mplay_message_player() 最後に受信したメッセージの送ったプレイヤーを返します。
mplay_message_name() 最後に受信したメッセージの送ったプレイヤー名を返します。
mplay_message_count(player) playerからまだ読み出していないメッセージ数を返します(0使うとすべて残っているメッセージが数えられます)。
mplay_message_clear(player) playerからまだ読み出していないメッセージ数をすべて削除します(0使うとすべて残っているメッセージが消去されます)。
ここでもう少し説明しましょう。まず、特定のプレイヤーにのみメッセージを送りたい場合は、そのプレイヤーのidが必要です。前に示したようにmplayer_player_id()の関数でそのidが取得できます。このidも受信のときも使います。選択ですが、プレイヤーの名前を文字列で指定することもできます。多数のプレイヤーが同一名をもつ場合は、最初のプレイヤーだけメッセージを受信します。
なぜ各メッセージが識別番号があると疑問に思うのでしょうか。これがアプリケーションに異なるタイプのメッセージが送られることを可能にします。受信側が識別番号でメッセージに対応するアクションを選択することができます(通常メッセージは非保証で送られるので、二つのメッセージに分けて識別値と値を送るのは問題を起こします)。
GMLの機能が十分ではない場合は、機能の拡張にplug-inが使用できます。Plug-inはDLL(Dynamic Link Library)ファイル形式で使います。そのDLLファイルで関数を定義することができます。その関数はDLLをサポートするどんな言語でも作成できます(Delphi 、Visual
C++、Visual Basic等)。もちろんそのために、プログラミングの能力が不可欠です。このplug-in関数は特定の形式にしたがって作ります。これらの関数は、ゼロから12個までの引数をもつことができます。引数は実数(Cではdouble)かヌル(null)を末尾にもつ文字列の何れか一つのタイプのものです(現在、4つ以上の引数の場合は実数しか使えません)。また、これらの関数を返すものは、実数かヌルを末尾にもつ文字列だけです。
Delphiでは、そのメニューからNewをFileメニューからを選び、DLLを選択します。次に示すのは、ゲーム・メーカーで使用可能なDelphiで作成したDLLファイルの例です(これはDelphiコードで、GMLではないことに注意)。
library MyDLL;
uses SysUtils, Classes;
function MyMin(x,y:real):real; cdecl;
begin
if x<y then Result := x else Result := y;
end;
var res : array[0..1024] of char;
function DoubleString(str:PChar):PChar; cdecl;
begin
StrCopy(res,str);
StrCat(res,str);
Result := res;
end;
exports MyMin, DoubleString;
begin
end.
このDLLは、二つの値のその最小値を出すMyMinおよび文字列を倍にするDoubleString二つの関数を定義します。メモリ管理を厳密に行うことを忘れないように注意しましょう。このため、結果の文字列をグローバルとしました。また、cdeclの呼び出し方の使用にも注意されたい。呼び出しにはcdeclかstdcalを使用できます。DelphiでDLLを作ると、MyDLL.DLLのファイルが得られます。このファイルはゲームの実行用ディレクトリに置かなければなりません(またはウインドウスOSに見つけられる場所でもよい)。
このようなDLLをゲーム・メーカーで用いるために、まず使いたい外部関数およびその引数を指定しなければなりません。このため、GMLには次の関数があります。
external_define(dll,name,calltype,restype,argnumb,arg1type,arg2type,…) 外部関数を定義します。dllはdll型のファイル名です。nameは関数の名前です。calltypeは呼び出し方です。ここでdll_cdeclとdll_stdcallが使えます。restypeは結果のタイプを指定します。タイプ指定にはty_realまたはty_stringを使います。argnumbは引数の数を指定します(0〜12)。これらのタイプを指定しなければなりません。タイプ指定にはty_realまたはty_stringを使います。4つ以上の引数の場合はすべてが実数(ty_real)でなければなりません。
この関数がその関数を外部から呼び出すときに必要となる関数のidを返しますので、上記の例のためにゲームのスタートに次のようなGMLコードが必要です。
{
global.mmm = external_define('MYOWN.DLL','MyMin',dll_dcecl,
ty_real,2,ty_real,ty_real);
global.ddd = external_define('MYOWN.DLL','DoubleString',dll_dcecl,
ty_string,1,ty_string);
}
関数を呼び出す必要であれば、次の関数を使います。
external_call(id,arg1,arg2,…) 指定されたidをもつ外部関数を呼び出します。適切な引数の数とタイプを指定しなければなりません(実数か文字列)。この関数は外部関数の結果を返します。
ですから、次のような記述を使います。
{
aaa = external_call(global.mmm,x,y);
sss = external_call(global.ddd,'Hello');
}
ゲーム用DLLの作成はどうやってやると疑問に思うのでしょうか。たとえば、ゲームにインスタンスを追加するプログラムを作りたいことを仮定しましょう。一番簡単作りはGMLコードを文字列で返す関数で実現できます。返された文字列のコードが次のGML関数で実行できます。
execute_string(str) strの文字列にあるコードを実行します。
また、DLLに実行可能なスクリプトのファイルを作成させることができます(この関数はその後ゲームの動作を変更させるにも使えます)。
execute_file(fname) fnameのコードを実行します。
このように外部の関数を呼んで、返された文字列が次のように実行できます。
{
ccc = external_call(global.mmm,x,y);
execute_string(ccc);
}
滅多に必要はないが、DLLがゲームのメイン・グラフィックスを扱い方(ハンドル)が知らなければなりません。これは次の関数で実現でき、その結果はDLLに渡せます。
window_handle() メイン・ウインドウのハンドルを返します。
DLLは安全モードで使用できないことに注意しましょう。
外部のDLLの使用は強力なツールです。しかし、やっていることをよく分かっているときのみこれを利用ください。