統合開発環境としての体裁は C2 や MMF/CF25 よりも整っている。基本的にブラックボックスが少ないというか、ブラック度?でいうと MMF/CF25 で鍛えられたため GMS はかなりドキュメントがしっかりしているという印象。
GMS はウェブとの連携が強い開発ツールで、ブラウザ・コンポーネントを開発環境に取り込んでいる。ドキュメントやサンプル・チュートリアルは専用フォーラムからアクセスもできるけど、公式が特定リポジトリから提供しているものなら開発環境で直接ダウンロードして直接起動できるなど工夫が随所に見られる。
MMF/CF25 との違い
MMF/CF25 と比較して GMS は開発言語の経験ないし実際のゲーム開発経験がある程度無いと、あらゆる意味で「完全なる初心者」にはやや敷居が高い。
だけど MMF/CF25 で経験積んでいれば GMS への移行は大きな助けになる。逆に GMS から MMF/CF25 への移行はメリットが無さそう。
MMF/CF25 で「フレーム」と呼ばれているものは「ルーム(ROOM)」、オブジェクトはオブジェクトでそのまま。ただし MMF/CF25 では「アクティブ」と呼ばれている類はちゃんと「スプライト」と呼ばれている。
MMF/CF25(あるいは C2 も) はツール独自のループ処理があるけど、GMS で用いられる GameMaker Language(以下 GML ) は一般的スクリプト言語の仕様から大きく逸脱した概念が無いため、ループ処理にツール独自の癖は無さそう。
角度など数学関数系は「Radian(ラジアン角)」で返される。
数のデータは実数型、これを文字列化する場合には桁数を指定しない場合、桁が勝手に丸められる。上のスクリーンショットは丸められた例。
表示する桁数を指定して文字列化する関数もあるので、数値の文字列化は string 関数と string_format 関数、二つある点に注意したい。
GML の変数はゆるい型の概念のみ
変数は型の概念が緩く、最初はグローバル( Global Variables )かローカル( Local Variables )かなど、スコープだけを意識しておけば良さそう。
グローバル宣言がない限り基本的にはローカル(インスタンス変数)として一時的に確保、インスタンス変数はインスタンスの生存する限りデータが保持される。メモリ管理とは無縁っぽい。
データ型にはポインタもあるけど一般的な C 言語のポインタとは違い、極めて限定されたシーンでのみ利用可能な特殊仕様。
配列は文字列と数値を混在してデータを格納可能、二次元配列まで扱える。List など拡張された配列的要素がアクセサリ(データ構造)として利用可能になっている。
MMF/CF25 は配列や変数は案外データ型の制限を受けやすく、「エクステの仕様」とも勘違いされるけれど、実はエクステ開発に用いられた C /C++ 言語のデータ型仕様が影響してるだけだったりする。だから MMF/CF25 は初心者向けとされる割にデータ型による制限は細かい部分で多々受ける。配列などはその傾向が強い、型は無視して作ることができない。
GML の変数は動的型付けで型の概念が緩くてこれも便利だけど、スクリプト言語としての処理速度がやはり遅いらしい。そこで速度を高速化する Yoyo Compiler (YYC) だが、「 YYC 」 は GML で書かれたスクリプト部分を C++ などに変換して速度アップを図る仕組み。この機能が有料版でないと使えないようフリー版では利用制限を施されている。
変数名「a」はダメ?「 built in variables 」について
最近一番ハマった点。「 built in variables 」である。
筆者は基本的に横着なので変数名は深く考えないし長いのは論外、特にローカル変数の宣言は短く速くを追求した結果一文字、C 言語の場合「int a,b,c,d,e,f,g…x,y,z;」 とか極端にいうとこんな感じで宣言してる。MMF/CF25 で用いられるオブジェクトの名前も最近はもっぱら a, b, c とかがマイブームだ。
これを GML でもやろうとしたら 「var a,b,c…x,y,z;」なのだけど、「var a」 の時点でエラーが出る。
「var b;」は良いのに「var a;」はなぜダメなのか。なにか予約が入っているらしく GML で
show_message(a);
はエラーがなく通るけど値は「0」を返す。なにこの仕様…なにかひっかかる。
変数名 a がダメなのではない、オブジェクト名と同じだからや
よく考えたらオブジェクト名と確保しようとしたローカル変数名が重複していることに問題があるみたいだ。
でもローカルであると宣言しているのに、ビルトインと名前が重複しちゃダメなの?なぜなの?
この辺りはインタプリタである GML の仕様だと後に知ることとなる。
グローバルとローカルが同じ名前でも普通区別してくれるはずでは……………そうか、ローカルとグローバルで識別子が同じだとしてもグローバルを呼び出す場合はプレフィックス(接頭辞)に「global.」を付ける。
しかし宣言したあとで変数をローカルとして区別するプレフィックスが見当たらない、そしてビルトインを区別するプレフィックスも無いのだとしたらローカルとビルトインは区別されていない。ビルトインをローカル変数名には使えない。だったらグローバルならグローバルとして明示的に宣言すればオブジェクト名と同名でも使える?
変数名と関数名を同じにしてはいけないルールとたぶん同じで、GMS のオブジェクト名=クラス名>関数オブジェクトを参照している変数 = Built in Variables って理解に至った。
MMF/CF25 ではオブジェクト名はあくまでも各オブジェクトを区別するための識別子であり、関数とかクラスとかそんな概念は薄いのでオブジェクトに付ける名前に関して深く考える理由がなかった。
しかし GMS ではオブジェクトはクラスのようなものなので、それを利用する GML でもオブジェクト名はビルトインとして利用されるから、オブジェクト名と同名のローカルやグローバル変数は利用できないという仕組みになるっぽい。
GMS ではスクリプトをオブジェクト単位で扱い、例えばオブジェクト名が「a」なら「a」という識別子には予約 ( Built in ) が入る。これはつまりオブジェクトを作成した時点で Built In としての宣言も行われたに等しいということだ。だからオブジェクト名は必ず固有のものでなければならない。
この識別子はオブジェクトを呼び出すため必要になるから、この名前(a)でローカル変数を確保することはできない。だからオブジェクトの識別子が「a」の場合スクリプト内では「var a; global.a;」宣言は不正である。
こんな感じか。やはり GameMakerStudio の専用ブログを作って垂れ流すことにしようと思う。