スプライトとサーフェイス
The returned surface is not the physical screen, but a hidden screen. When you perform a graphic operation into this surface, it won’t be displayed on screen immediately, but at next frame loop. Also you must tell MMF what area you have changed, so that it can copy it to the screen.
MMF2は革命的な技術を使っているわけでは無く、むしろ常識的な小難しい既存技術を使いながら難しさを上手に隠蔽しているだけなので内部的にはスプライトも使っているしサーフェイスも使っています。ヘルプとかではそれをとりわけ説明していません。エクステンションを開発するためのMMF2SDKにはさすがに少しだけ詳しく書いてありましたが、期待したよりドキュメントはずっと薄かった…
スプライト?
今回筆者が記事を書くに当たってMMF2のSDKを読んだのですがあんまり大したことは書いてありませんでした。MMF2のスプライトとサーフェイスについて知りたいことがあったのですが、資料が無さ過ぎるので一般的なスプライトとサーフェイスの概念で大差ないでしょってことでスプライト?サーフェイス??という方は興味が沸いたら是非自分でこの辺をキーワードにしてGoogle先生で検索してみてください。一般的な「スプライト」と「サーフェイス」に対する知識を得れば、MMF2への理解も自然に一歩高まると思います。個人的にはPython + Pygameでスプライトを使って遊んでいた経験があるのでPygameのドキュメントをちょっと紹介しておきます。
「初心者のための pygame ガイド」は久しぶりに読んだのですが、なんかMMF2(日本語版)にも共通して言える部分がいくつかあります。
- ハードウエア surface は利点よりもトラブルのもと
- 枝葉の問題に心をうばわれないようにしよう
- ピクセルごとの完全な衝突判定に頭を悩ませるのはやめよう
HWAが来ない・・・(ハードウエア surface は利点よりもトラブルのもと)
アップデートも来ない・・・(枝葉の問題に心をうばわれないようにしよう)
衝突判定については「デテクター(detector/衝突判定・当たり判定用の別オブジェクト)」と高速ループ使えば良いのだけど、これを理解できるかどうかはMMF2を使いこなす上での大きな試練の一つかもしれません。上下左右の壁判定を自動でやってくれる、こんな機能が欲しかったのですがMMF2でやる場合、Pygameと同じ程度の労力(自前で衝突を検出するロジックを組む手間)がかかる気がします。
その他の仕様:インクエフェクト
半透明
反転
XOR
AND
OR
モノクロ
加算
減算
半透明処理はソフトウェア0〜127段階、HWAを使用した場合0〜255段階。
インクエフェクトは通常一つしか選択できず、一つのオブジェクトで複数のインクエフェクトを組み合わせるような高度な選択はできません。これに対してHWAはシェーダーを自作することもできるしすでにある程度の種類のシェーダーが公開されてもいるので、HWAが使えれば表現の自由度は飛躍的に高くなります。また最新版パッチが当たった(英語版用R254以降)SWFエクスポータでもインクエフェクトは使えますが、Javaアプリなどではもともと半透明すらサポートしてませんしインクエフェクトは使えません。つまり「インクエフェクト」はビルドするアプリケーションの種類によっては使えたり使えなかったりするものがある可能性はあります。iOSやXNA、AndroidではHWAとともにシェーダーも使えるはずなのであんまり心配いりません(英語版の場合のお話です)。
変数型
MMF2の変数には「型」があるらしく、数値はLong(signed integer:長整数型)である。つまり-2147483648 / +2147483647の整数が扱えます。ここで変数型に敏感な人は「Longだから小数点以下は基本として無視されるはずだ」と考える、しかしたちが悪いことにプロパティから変数に値を代入した際にはMMF2のインターフェース上では問題も無く一見ちゃんと代入できてるように見える。これだと実は小数部が無視された結果が返ってくるんですがね。しかし小数が扱えないかというとそんなこともありません。
「アクティブ」のプロパティから初期値として変数Aに与える値にわざと小数点以下の数値を含ませてみよう。このやり方だと後で確認すると小数点以下は確かに無視されるのだが、今度はイベントエディター上から「フレームが開始時」に小数点以下を含めた値を代入するようにすると値はfloat(6桁)になって返ってくる。これはMMF2は数値に型があるようでC言語のような厳密さはなく、どちらかというとjavaのように変数の型があわないときには自動でlongからfloatに型を合わせて代入してくれるという仕様になっています(だったらプロパティからも少数を代入させてくれよと愚痴がでるのですが…)。
参考:(外部リンク)リテラルと変数の型.
◎,○は代入可。×は不可。
代入する数値の型→ | int | long | float | double | |
---|---|---|---|---|---|
数値の例→ | 12 | 12L | 12F | 12D | |
変数の型 | int | ◎ | × | × | × |
long | ◎ | ◎ | × | × | |
float | ○ | ○ | ◎ | × | |
double | ◎ | ○ | ◎ | ◎ |
座標もサブピクセル(ピクセル以下の単位)をサポートしていないので例えば毎回オブジェクトの座標X値を取得してそれに0.1を加算するような計算をしてもオブジェクトは永遠に移動することはない。しかし前述の仕様を利用すればイベントエディタ上で「フレーム開始時」にターゲットの座標X値を変数Aに代入したとします。次に変数Aに対して毎フレームごとに0.3を加算した場合、4フレーム目には1.2pixel分移動する計算になる。これで変数Aの計算結果をX値に代入すればオブジェクトは右にゆっくりと移動するようになります。
おまけ