alpha3を使ってチャットを作ってみます。alpha3を使用します。以下の事項を確認していきます。実際に動作するサンプルはwonderflに投稿してあります。online機能このswfファイルを閲覧する人をユーザと呼びます。ユーザは以下のようなことが出来ます。com.asmple.union.chatへobserveすることが出来ます。com.asmple.union.chatへjoinすることが出来ます。Attributeを通じてアバター・発言の色を変更することが出来ます。Attributeを通じて発言時のニックネームを変更することが出来ます。ユーザは、Roomにjoinした状態であれば以下の操作が可能です。ユーザは、メッセージ入力欄にメッセージを入力し、エンターキーを押すことで、Messageを通じて発言することが出来ます。Attributeを通じて変更することが出来ます。概念にて解説しております。今回は実際にobserveとjoinの違いを体験できます。以下のswfは上のものとまったく同じものです。先ほどのswfと下記swf両方を再生し、先ほどのswfでjoinボタンをクリックしてから画面内のアバターを移動してみましょう。このとき、下記のswfでは何も見えないはずです。Roomにobserveもjoinもしていないからです。次に、下記swfでobserveボタンをクリックすると、画面内にアバターが表示されます。(同時に本エントリーを閲覧している人がいたら数人のアバターが表示されるかもしれません。)ただ、画面内には自分のアバターも表示されませんが、発言は出来ることが分かる思います。joinせずにまたは、observe時もMessageを送信出来ます。RoomにjoinしていないClientからのMessage送信を抑止する為には、自身でチェックコードを書く必要があります。リリース時には権限管理の強化で挙動は変更される可能性があるそうです。(@keno42さんがcolinさんに確認してくれました。この場を借りて感謝致します。onlineというわけで、observeとjoinの違いを感じていただけましたでしょうか。alpha3の時点では不都合と思われる挙動があるため、本エントリーではその点も確認していきます。AttributeとMessageは情報の共有化に使います。情報の共有化にて解説しております。Attributeは、今回の例ではニックネームや色となります。後から入室したユーザは最新の情報を共有することがわかります。Messageでの共有は、今回の例では発言メッセージとなります。後から入室したユーザにはそれ以降の情報しか共有されないことが分かります。Attribute各クライアントが持つ属性を定義を紹介します。100,200,0,100アバターの情報は下記の情報を「,(カンマ)」区切りで格納します。距離:100を表します。Attributeのスコープをグローバルにしましたが、もしRoomを増やすことになればRoomごとにアバターの情報は異なるでしょうから、アバター情報のスコープをRoomごとに持つように変更しましょう。ユーザーインターフェースユーザーインターフェースのUnionChatUIクラス定義は、L:675以降にあります。UnionChatUIクラスは以下の図内に示した各パーツに対応したpublicプロパティを持っています。Serverとの接続待ちの際に表示します。後述するメソッドで制御するため直接操作する必要はありません。Serverの特定のRoomへobserveする際に使用します。observe処理開始時の処理をこのボタンのハンドラへ記述します。Serverの特定のRoomへjoinする際に使用します。join処理開始時の処理をこのボタンのハンドラへ記述します。Serverとの接続状態を表示します。RoomEvent.JOINなど各イベントのハンドラ内でこのラベルの値を書き換えます。Serverの特定のRoomにjoinしているClient数を表示します。RoomEvent.CLIENT_COUNTイベントのハンドラ内でこのラベルの値を書き換えます。ユーザ文字を入力し、エンターキーを押した際に、RoomインスタンスのsendMessage()メソッドを通じてMessageを送信する際に使用します。Reactorの各種ログの表示と、RoomインスタンスのsendMessages()メソッドを通じて送信されたMessagesを表示する際に使用します。Attributeのcolorを変更する際に使用します。Attributeのnicknameを変更する際に使用します。Attributeの値を更新する際に使用します。Attributeの更新処理をこのボタンのハンドラへ記述します。Attributeのavatarを変更する際に使用します。このオブジェクトをクリックした際メソッドは以下のものを用意しました。ローディングサークルを再生します。ローディングサークルを停止します。messageListにメッセージを追加します。アバターアバターは、以下のswfを使用しています。online以下のプロパティとメソッドを備えます。Serverへの接続コンストラクタから呼ぶconnectメソッドをみてみましょう。UnionServerへ接続します。}Reactorをnewする際の引数は、1つ目が設定ファイルのxmlの場所。2つ目がデバッグ用のログの出力設定フラグとなります。Playerで再生した際に、ログを確認することが出来ます。今回は使用しませんが以下のようなxmlを用意してあげることで自動的にconnectすることが可能です。Serverへ接続が完了したことを知るには、ReactorEvent.READYイベントの送出を待ちます。先ほど指定したハンドラの中身をみてみましょう。Attributeの初期化ReactorEvent.READYイベントが送出された後に、L:491にて自身のClientオブジェクトを取得しています。Attributeはこのタイミングで代入しておくと良いでしょう。Room作成チェックL:503にて、RoomManagerインスタンスを取得し、Room作成時のイベントの送出を待ちます。Server側でもRoom生成が正常に行われたかをチェックする為に使います。RoomSettingでRoomの自動削除を防ぐデフォルトではRoomに接続しているClientがいなくなった時点でRoomは破棄されてしまいます。これを防ぐために、L:510でRoomSettingインスタンスを生成し、dieOnEmptyプロパティにfalseを代入します。このRoomSettingインスタンスをRoomManagerインスタンスのcreateRoomメソッドの第二引数に指定するこたおでRoom内にClientが居ない状態でもRoomを残しておくことが可能です。RoomEventのリスナー登録L:520でaddRoomEventListeners()メソッドを実行することで、RoomEventの各イベントを監視します。Serverとの情報共有を行います。詳しくは、後ほどみます。Room作成完了Roomの作成完了を知るには、RoomManagerEvent.CREATE_ROOM_RESULTSイベントの送出を待ちます。先ほど指定したハンドラをみていきましょう。}作成の結果はevent.getStaus()の値を確認します。下記のいずれかの値をとります。Status.SUCCESSStatus.ROOM_EXISTStatus.ERROR作成に成功した場合は、Status.SUCCESSとなります。今回の場合は、Roomの自動削除を無効としているので、Status.ROOM_EXISTとなる状況が多いと思います。いずれもroomへの接続が可能な状態を示します。"";次に実行されるのは、activate()メソッドです。attemptの値がobseverの場合は、room.observe()メソッドの実行、attemptの値がjoinの場合は、room.join()メソッドの実行となることを心に留めておきましょう。このような作りとしているかは後ほど説明します。Serverとの接続が確立されてユーザのイベントを待つ状態となります。observeボタンの動作を登録します。joinボタンの動作を登録します。updateボタンの動作を登録します。メッセージ入力時の動作を登録します。アバターフィールドクリック時の動作を登録します。}先ほど確認したユーザーインターフェースの各プロパティにマウスイベントやテキスト入力時のイベントを設定しています。observeボタンの動作L:384で、ReadyEvent.READYイベントのハンドラで登録した、RoomEventのリスナーを解除します。L:381で_attemptにobserveを代入してから、connectメソッドを実行します。}これは、先ほど見たとおり、roomManager_createRoomReslutsHandler内で、下記のようにroom.observe()を実行することになります。activate();joinボタンの動作observeとの違いは、_attemptにjoinを代入する点です。このような処理は、本来ならば1つの関数にまとめたほうが良いかも知れません。}何度も見てきたように、roomManager_createRoomReslutsHandler内で、下記のようにroom.join()を実行することになります。Serverの接続を繋ぎなおしています。alpha3では、一度observeしたRoomに対してjoinしたり、いったんstopObservingしてからjoin。その逆を行うと、RoomEventが正常にdispatchされないなど動作が不安定となるようです。そのため、observeとjoinの切り替え時にコネクションを張りなおす処理を行っています。updateボタンの動作ClientのAttributeを更新する処理です。L:414で自身のClientインスタンスのsetAttribute()メソッドを呼び出します。}メッセージ入力時の動作TextFieldで入力した文字をエンターキーで抽出します。KeyboardEvent.KEY_UPのハンドラ内で、Keyboard.ENTER判定をするだけだと、日本語入力の変換時のエンターキー入力を拾ってしまい、入力途中で文章が抽出されてしまいます。そこで、文字入力中かどうかを判定するためにTextEvent.TEXT_INPUTのハンドラを活用します。}L:441でRoomインスタンスのsetMessage()メソッドを使ってchatMessageというMessageを送信しています。}アバターフィールドクリック時の動作クリックされた場所とアバターの位置関係と距離計算して、アバターが向くべき方向を決定します。L:475で自身のClientインスタンスのsetAttribute()メソッドを呼び出します。これらの値は同時にAttributeの更新イベントを通知して欲しいので1つのAttributeにカンマ区切りで代入しています。入室していなければ何もしない。Attributeを更新する。}addRoomEventListenersjoinボタン、observeボタンをクリックした後、ReactorEvent.READYイベントが送出された段階で呼び出される_reactor_readyHandler内で実行しているメソッドです。RoomEventの各イベントをリスナー登録します。Serverとをつなぐ要とも言える処理です。}各イベントと登録されたハンドラ内の処理をみていきます。RoomEvent.OBSERVEとそのハンドラRoomEvent.OBSERVEはRoomインスタンスのobserveが完了すると、Roomインスタンスから送出されるイベントです。activate()メソッドでユーザーインターフェースの活性化を行います。詳細は前述の通りです。}RoomEvent.JOINとそのハンドラRoomEvent.JOINはRoomインスタンスのjoinが完了すると、Roomインスタンスから送出されるイベントです。activate()メソッドでユーザーインターフェースの活性化を行います。詳細は前述の通りです。}RoomEvent.CLIENT_COUNTとそのハンドラRoomEvent.CLIENT_COUNTはRoomにjoinしているClient数が変化すると、Roomインスタンスから送出されるイベントです。RoomEventインスタンスのgetNumClients()メソッドで人数を取得します。Serverとの同期を完了すると、Roomインスタンスから送出されるイベントです。observeしたClientが現状のRoom内のClientの情報などを取得する処理を記述します。今回は、すでにRoomにjoinしているClientのアバターを描画します。RoomインスタンスのgetClients()メソッドを通して、Room内のClientのオブジェクトを取得する点がポイントとなります。addAvatar()メソッドは後述します。}RoomEvent.ADD_CLIENTとそのハンドラRoomEvent.ADD_CLIENTはRoomインスタンスの新しいClientが追加されると、Roomインスタンスから送出されるイベントです。現ClientがRoomにjoinまたはobserveした後にRoomにjoinしてきたClientの情報を取得します。}addAvatar()メソッドLoaderインスタンスを使って、外部のswfをロードします。ロード後の処理も一括で記述したかったので、無名関数をリスナー登録しています。AttributeのavatarをAvatarに設定しています。updateAvatar()メソッドは後述します。}RoomEvent.REMOVE_CLIENTとそのハンドラRoomEvent.REMOVE_CLIENTはRoomインスタンスからClientが削除されると、Roomインスタンスから送出されるイベントです。現ClientがRoomにjoinまたはobserveした後にRoomからleaveしたClientの情報を取得します。}removeAvatar()メソッドアバターフィールドから、アバターを削除します。Attributeを更新すると、Roomインスタンスから送出されるイベントです。Attributeであるかを確認します。今回は、colorとavatarの更新を検知するようにしています。Attributeです。Attributeだと思います。avatarの更新を実際のアバターに適用します。アバターの向きを指定して、目的地へアバターを移動します。移動する際のモーションは、BetweenAS3を使っています。BetweenAS3は大変直感的に使える素敵ライブラリです。}chatMessageのMessageイベントchatMessageというIDのMessageを受信した際のハンドラを指定します。受け取ったMessageをメッセージリストに追加しています。}まとめさて、大変長々と説明してまいりました。お付き合い頂きありがとうございます。今回は具体的なサンプルコードでUnionを使ったアプリケーションの構築方法を紹介してきました。いかがでしたでしょうか。Unionを使ったアプリケーションの作り方は、もちろん他にもあると思います。1つの例として参考にしていただければと思います。ご意見やご感想は、お気軽にコメントやtwitterでのつぶやきを頂ければと思います。Serverをローカルにインストールしてみようと思います。alpha4がリリースされたので使ってみました。Serverに焦点を合わせます。10注目記事-->引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。