NetStream と NetGroup 比較
RTMFP による通信手段には大きく分けて NetStream クラスを使う方法と、 NetGroup クラスを使う方法があります。それぞれ一長一短があるので、要件に応じてうまいこと使っていきたいところ、ということで、ゲームを作る上で調べてた時に気づいたことを書いてみます。
NetStream
- FlashPlayer10から使用可
- 基本的に 1 対 1 の一方向通信用。双方向通信するためには、クライアント毎に受信用、送信用、2 つの NetStream が必要。
- 通信速度が速い。ローカルで試した結果、お互い通信待ち処理を入れても、スムーズに同期がとれた。(遠距離だと分からないですが)
- コネクションの確立に、相手の NearID が必要。不特定の相手と接続するためには、 CGI とかによる別ルートのやり取りが必要。
NetGroup
- FlashPlayer10.1から使用可
- 不特定多数との同時通信向き
- 通信速度が若干遅い。同期待ち処理を入れると、かなりガタガタして使いものにならなかった。
- あるグループに対して接続するイメージであるため、グループの識別名を指定するだけで、簡単に双方向通信する準備が出来る。
総括 格ゲーとかアクションゲームのようなリアルタイムさが要求される場合、NetStream クラスを、RPG の戦闘や、ボードゲーム、 カードゲームのような、各プレイヤーが順番に操作していくようなリアルタイムさはさほど不要なゲームなら NetGroup クラスを使う感じでしょうか。 しかし、NetStream クラスは高速ながら、複数人数の双方向通信環境を構築するだけでも、結構な手間です。NetGroup クラスの、コーディングの容易さは異常で、簡単なチャット程度ならすぐに実装出来てしまいます。リアルタイムさを求めるゲームを Flash で実現する場合、まずはできるだけ簡単に NetStream クラスによる複数人数の双方向通信を行える環境を作れるようにする必要があると思います。
Flex4でSpriteを使う
Flex で画面を作るのに MXML はとても便利なので使いたいけど、同時に Shape をぐりぐり動かすようなゲームも作りたいというような場合、MXML で Shape を addChild したいことと思います。しかし、MXML のコンポーネントに対して Sprite を addChild しようとすると、例外が発生します。 こういう場合は、mx:Image に対して addChild をすると、Sprite を追加することができ、追加した Sprite に対して Shape なり Bitmap なりを addChild することで、自由にオブジェクトをぐりぐりできます。
サンプルコードは以下。今回の例は Flex4 の MXML ですが、Flex2、 Flex3 でも使えると思います。
<?xml version=“1.0” encoding=“utf-8”?>
<s:Application xmlns:fx=“http://ns.adobe.com/mxml/2009”
xmlns:s=“library://ns.adobe.com/flex/spark”
xmlns:mx=“library://ns.adobe.com/flex/mx”>
<mx:Image id="rootObject" initialize="_onInitialize()">
</mx:Image>
<fx:Script>
<![CDATA[
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
private var _rootSp:Sprite;
private var _shape:Shape;
private function _onInitialize():void
{
_rootSp = new Sprite();
_rootSp.addEventListener(Event.ENTER_FRAME, _onEnterFrame);
rootObject.addChild(_rootSp);
_shape = new Shape();
_shape.graphics.beginFill(0);
_shape.graphics.lineStyle(1, 0);
_shape.graphics.drawCircle(0, 0, 10);
_shape.graphics.endFill();
_rootSp.addChild(_shape);
}
private function _onEnterFrame(event:Event):void
{
_shape.x++;
_shape.y++;
}
]]>
</fx:Script>
</s:Application>
RTMFP導入
FlashPlayer10から、クライアント間で直接データ送受信を行えるAPIが追加されたようです。Flashで複数のクライアント上のデータをリアルタイムに同期させようとすると、XMLSocketだとかソケットサーバーだとかで実現してたと思いますが、FlashPlayer10からはデータ送受信の処理をサーバーではなく、swfのみで実施できるようになったということみたいです。これらのAdobe製通信プロトコルをRTMFPというらしいです。 今回はRTMFPを試すのに有用なページを幾つかピックアップしたいと思います。
RTMFPのサンプルを試すには、以下のページを見ると良いかと思います。 Adobeのプロジェクトページは以下です。 Adobe Labs - Cirrus 英語ですが、一番下のGetting Startedを見たら、なんとなくどうすれば良いかが分かります。 また以下のページにて、RTMFPのステキさが伝わる詳細な説明を読むことができます。 Flash Player上でP2P通信ができるRTMFPについて - blog.katsuma.tv
実際にAS3でRTMFPを使用したプログラムを書く場合は以下をば。 akihiro kamijo: netアーカイブ 具体的なクラスの説明はこちら。 Adobe® Flex® 4.1 リファレンスガイド
僕が軽く試した感覚だと、チャットぐらいならサーバーサイドのプログラム無しでかなり手軽に作ることができそうです。
次回から、RTMFPでFlashによるリアルタイムなオンラインゲームが出来るかどうか、僕が試してみたことを書いてみようと思います。
【修正】任意の引数を持つ初期処理メソッドを共通的に実行したい
任意の引数を持つ初期処理メソッドを共通的に実行したい
やりたかったことを思いついたのでメモします。wonderflで実験したら成功しました。
引数の異なる初期処理メソッドを共通的に呼び出すコード - wonderfl build flash online
僕がしたかったことは、ゲームのシーンを表すSceneクラスをSceneManagerクラスへ予め登録しておくことで、シーンを初期処理→画面遷移効果→ローディング→シーン処理実行→画面遷移効果→終了処理という一定の処理を行わせるということです。こういうことをさせる場合、Sceneクラスには例えば初期処理の場合、
public function initialize(context:Object):void { }
といった空メソッドを定義し、タイトルシーンの実装ということでSceneクラスを継承したTitleSceneを定義、initializeメソッドを以下のようにオーバーライドします。
override public function initialize(context:Object):void {
// 初期処理
}
contextとは、シーン毎に必要なデータや処理を選択的に取得、実行させることが出来るようにするための自分ルールで、シーン単位で作成する「I~Context」というインターフェイス型で渡ってきます。これがObject型だといちいちインターフェイス型にキャストしないといけません。これが煩わしく感じていて、回避策を探してました。
解決法を日本語で言うと、「"initialize"という名前のメソッドを引数を1つ与えて実行する。"initialize"メソッドが定義されていなければ何もしない。」ということです。詳しくはwonderflのコードを覗いてみてください。
このパターン、多用してしまいそうだなぁ。
2010/11/09追加
成功していませんでした。→【修正】任意の引数を持つ初期処理メソッドを共通的に実行したい
AM902を引っ越しました。
ということで、AM902を引っ越しました。デザインも一新しています。
僕としては珍しく、ちゃんとWebデザインというものをしてみようと頑張った結果、いつもより小奇麗に出来たと思います。僕はデザイン周りがすごく弱いことは自覚しているので、ゲーム1つ1つでも、とりあえずちゃんと意識してデザインする習慣が必要です。
ということで、これからもよろしくお願いします!
「Error #1068」に気をつけろという話
「Error #1068」というランタイムエラーにはまってしまいましたので、調べた結果を記録しておきます。
see? 「Error #1068: int と * は共有できません。」というランタイムエラー再現 URL #wonderfl
2010-06-23 01:09:52 via web
どうやらfor eachとラベルを併用してcontinue <ラベル>;すると、1068のエラーが出る模様・・・。通常のfor分では発生しない。
調べてみると、1068はAS3のランタイムエラーの中でも特殊な位置づけみたいです。
breakやcontinueを使った複雑な制御フローによる1068ランタイムエラー。URL
ところで、これってコンパイラのバグなんですかね?