質問への回答:インビルト・ペアと ForEach (OnEach) について


この記事は一時的にニュースカテゴリへ放り込まれましたが、多分 12 月頃には整理されて試作品もしくは備忘録、あるいは初心者カテゴリへ移動します。内容的にはまったく初心者向きではない。インビルト・ペアと OnEach(ForEach) に関する内容。

インビルト・ペアの有効性とかが分からねーんだけど?という趣旨の質問が来たので、質問に対する回答と動作サンプルとかを記事にまとめて載せておきます。サンプルファイルについては希望に添えず申し訳ねーのですが、MMF2 ではなくてフリー版の CF25 を使ってください。それように作って有ります。

フリー版:ダウンロード

サンプルファイル:InbuiltPair&OnEach_Sample


※注意点
「 On Each 」は「 For Each 」に UI 表記がすでに変わっています(英語 UI、フリー版等含む)。ただし本ブログではエクステと区別するため特別に OnEach と書いています。
ForEach

まず MMF2 Gaido の頃に書かれた記事のなかにある「インビルト・ペア (Inbuilt Pairing)」について、正式名称を今も知らないですが、その後開発者とのやりとりで普通に意味通じているためテキトーにつけたこの名前についてはそれほど問題なさそう。

CF25 の OnEach について

CF25 の OnEach(ForEach) については MMF2 英語版で利用されていたエクステの「 ForEach 」から一部機能が標準機能化されたものです。

開発者いわくエクステンションと比較して完全な機能的互換性を確保する予定はなく、独立した標準機能として搭載されたものだとのこと。つまりエクステにはあるけど OnEach には無い機能とかについては標準機能化されないので、エクステにしかない機能を使っている場合は ForEach Object の利用を継続してください。

この場では今後エクステとしての ForEach については語らず OnEach についてのみ解説の対象とします。

インビルト・ペアについて

MMF2 におけるループ処理は基本として 3 種類が挙げられます。

  1. ゲームループ(メインループ)
  2. 高速ループ(For)
  3. アクションループ(インスタンスへのループ処理)

インビルト・ペアは 3 番目、アクションループで主に働くカップリング機能のことで、「親と子」の関係にも例えられています。

OnEach は二番目の系統に属するループ処理でインスタンスを要素としたループ処理に特化し拡張された For(繰り返し処理)。しかし処理内容的には 3 番目、アクションループに似ています。

OnEach と高速ループは処理速度が違います。条件にもよりますが OnEach はインスタンスを要素としたループ処理に特化しているから使い方次第で高速ループよりも効率の良いループ処理が実現できるのです。

ここで今回このために用意したサンプルファイルがどのように作られているか過程を動画で見てみましょ。5 分くれ。Mendelssohn の曲 ( Midsummer Night’s Dream ) が終わる頃には完成してます。

▶ InbuiltPair&OnEachOfTwo Sample – YouTube.

てなわけで

動画では 5 分で作るために 5 行でしたが、サンプルは 6 行となっています。まずはイベントリストエディタで見てみましょう。

6line
score

スコアとライブを変数として利用してます。本来の用途ではないですが、グローバル変数確保する手間が要らないので楽するためにこっちを使いました。「Create Object by Name」も CF25 からの新機能です。

インビルト・ペアの部分はここ。従来までの説明や解説だとここは高速ループか OnEach が必要とされるところでしたが、製作者がインビルト・ペアを意識して作ることによって非常にシンプルな記述が実現できます。下の画像をご覧ください。

InbuiltPair

最後に OnEach of Two Object、ここが肝です。インビルト・ペアを意識して作った親子関係をここで親子もろとも虐殺するためのループ処理がこれ。大事なのは条件を二つ用意してそれぞれを要素としてひとつのループ処理で済ますための下ごしらえにあります。

onEachOfTwoObject
ForEachofTwo

総括

ForEach of Two については、条件で抽出し合致したインスタンスのみを対象としたループを回すことができるから効率が良いわけで、高速ループの場合最初からすべてのオブジェクトを対象にループを回し、そこから条件一致したオブジェクトを抽出して処理するから効率が悪い。こういう理屈です。

子の破壊については変な処理すると親子のうち子だけ生き残ってしまうケースがあって本家の PDF サンプルでもたぶんその見落としがあります。

子だけ生き残った場合はデバッガに生き残った子がカウントされているので、姿は見えないけどデバッガをチェックしていると存在に気が付きます。ただうまく処理される場合もあるため、深く考えるのをやめるというのも男らしい生き方であり筆者はそれに憧れます。

result

今回作ったサンプルは親子を確実に関連付けして殺すためのもので、移動速度を速くしてあるのは複数同時処理にちゃんと対応しているかどうかを確認する目的です。だいたい親が死んで子が生き残るケースはアクションループのみに頼った場合で、OnEach に頼るとこの不確実性は排除できる。

子が生き残るのはバグと言うより複数同時処理を考慮してないとか組み方がちょっとオカシイとか。おおむね人為的なミスが原因で、再現性があるものについてはバグとして報告できると思います。

こんな感じの回答となりましたが、すでにある程度ループ回せる方だと思うのであとは適当にいじって試してください。事前に頂いたサンプルは子が生き残る場合が確かにありました。しかし今回この作り方なら残らないと思います(たぶんな)。そのためにループを回しているので、本家の PDF とは一部作り方違うのは主にこの部分です。ご意見ありがとうございました。

Prester.

Leave a comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です