スカイサーバーサービス
スカイサーバーサービス
フェニックスソフトは、より多くのお客さまによるFlashでのインタラクティブコンテンツ開発を支援することを目的とし、サーバーを公開しASPとして提供いたします!
本サービスをご利用いただくことにより、お客様はサーバーを準備することなく、Flashオンラインコンテンツを開発することができます。
正式サービスではアプリケーションの管理ツールの提供やトラフィックの開放など、お客様の開発ニーズにそったサービスを提供していく予定です。
※現在は正式サービスの前の簡易公開サーバーとして無料でご提供しております。
※ライブラリ事業ページのリニューアル作業のため、nine製品のダウンロードを一時中止とさせていただきます。
以下、スカイサーバーサービスについてご説明いたします。
100heartsのサンプルソース(Flashアプリ開発パックの中にあります)をこちらからダウンロードして100heartsのソースを見ながらチュートリアルを読み進めて下さい。
100heartsはFlash上でスカイサーバーによる通信とPapervision3Dによる3D描画を利用していますので、
(nine for flashとnine.ASP のライブラリが入っています。)
最新のPapervision3Dライブラリ(.swcファイル)をダウンロードします。
これらのswcファイルをローカルディレクトリに置き、そのディレクトリにパスを設定します。
このクラスの中で変数の初期化等を行います。
initGame()の中でタイトルスクリーンを作成してaddChild()を行っています。
Main.asのコード
ここではNetworkManagerクラスというクラスを作成し、DistributionServerを継承しています。
NetworkManager.asのコード
ログインボタンが押されるとASPへの接続が開始されるようにします。
ready()が呼び出されると、ログインボタンが有効になり、
ログインボタンを押した際に呼び出されるコールバック関数onClickLogin()が有効になります。
ログインボタンを押すとNetworkManagerのconnect()関数が呼び出されます。
Title.asのコード
Main.asに追加
これらのプレーヤ情報をTCP/IPを用いてサーバー・クライアント間で共有しようとすると
大変ですが、ASPサーバーのオブジェクト共有機能を使用すると簡単に共有することができます。
オブジェクト共有を使用するには、情報を共有したいクラスをNetworkObjectクラスを継承して作成します。
TYPE_IDはこのクラスのユニークなIDです。他の共有オブジェクトやメッセージのクラスを作成する際には、必ず別のIDを設定して下さい。このIDはNetworkObjectManager.register()関数を呼び出す時に使用します。
PlayerCharacter上で共有したいデータは、IntProperty(Int型データ)やNumberProperty(Number型データ)、StringProperty(String型データ)等のクラスのオブジェクトにして、PlayerCharacterクラスのメンバーにします。
PlayerCharacterのコンストラクタでaddProperty()を呼び出す事で、プロパティがDistributionServerに登録されます。
今回はユーザーのログインネーム、ハートの数、ステータス番号、アバターの座標と向きをプロパティにします。
PlayerCharacter.asのコード
接続が完了したら、DistributionServerのaddObject()関数を呼び出して
アバターオブジェクトの共有を開始します。
共有オブジェクトの登録が完了すると、onAddObject()関数が呼び出されます。
この関数は自分のクライアントのオブジェクトの登録でも、他のクライアントのオブジェクト登録でも
呼び出されますので、NetworkObjectのlocalプロパティで自他の判別を行います。
ここでは、自オブジェクトの登録が完了したと判断した所でMainクラスのstartGame()関数を呼び出しています。
NetworkManager.asのコード
Main.asに追加
Main.asに追加
100heartsでは、アバターオブジェクトのステータス番号が変化した時に
アバターの外見を変化させていますので、ステータス番号の変化が
自動的に検出されると便利です。
NetworkObjectには、プロパティが変化した時に呼ばれるコールバック関数
onPropertyUpdate()があります。onPropertyUpdate()をオーバーライドして、
その中にコードを追加します。
引数indexは初期化時にPlayerCharacter()でaddProperty()を行った順番を表します。
indexは0始まりなので、index==2 のとき、m_statusが変化したということになります
PlayerCharacter.asに追加
DistributionServerのPostAll()関数を使用してメッセージを全員に送信します。
メッセージの定義
UserMaessageを継承したクラスChatMessageを作成します。
まず、ユニークなメッセージIDを決めます。
MessageTypeRegistry.register()を呼び出し、自クラスとメッセージIDを登録します。
getMarshalSize(), marshal(), unmarshal()を定義します。
getMarshalSize()は、このクラスのデータをシリアル化した時のサイズを返すようにします。
marshal()は、このクラスのデータをバッファに書き込んでシリアル化します。
unmarshal()は、シリアル化されたバッファからクラスのメンバ変数にデータを読み込みます。
ChatMessage.as
ASPサーバーへの接続時にメッセージクラスがDistributionServerに登録されるようにします。
NetworkManager.asに追加
メッセージオブジェクトを生成してデータを設定し、DistributionServerのpostAll()で送信します。
NetworkManager.asに追加
DistributionServerのhandleMessage()関数をオーバーライドします。
受信したメッセージのIDが引数のmsgに入っていますので、IDがChatMessageのものだけを処理します。
NetworkManager.asに追加
本サービスをご利用いただくことにより、お客様はサーバーを準備することなく、Flashオンラインコンテンツを開発することができます。
正式サービスではアプリケーションの管理ツールの提供やトラフィックの開放など、お客様の開発ニーズにそったサービスを提供していく予定です。
※現在は正式サービスの前の簡易公開サーバーとして無料でご提供しております。
※ライブラリ事業ページのリニューアル作業のため、nine製品のダウンロードを一時中止とさせていただきます。
以下、スカイサーバーサービスについてご説明いたします。
ASPサーバーチュートリアル
このページでは、スカイサーバーを利用したネットワークアプリケーション"100hearts" の通信部分をどのように作成したのかを順を追ってご紹介します。100heartsのサンプルソース(Flashアプリ開発パックの中にあります)をこちらからダウンロードして100heartsのソースを見ながらチュートリアルを読み進めて下さい。
準備しよう
Adobe Flash CS4上で開発することを前提に説明を進めます。100heartsはFlash上でスカイサーバーによる通信とPapervision3Dによる3D描画を利用していますので、
- nine. for flash ライブラリ
- nine.ASP ライブラリ
- Papervision3Dライブラリ
ダウンロードしよう
Flashアプリ開発パックをこちらからダウンロードします。(nine for flashとnine.ASP のライブラリが入っています。)
最新のPapervision3Dライブラリ(.swcファイル)をダウンロードします。
これらのswcファイルをローカルディレクトリに置き、そのディレクトリにパスを設定します。
作成しよう
以下の、ASPサーバーチュートリアルをご説明いたします。Mainクラスを作る
プログラムをスタートさせるMainクラスを作りましょうこのクラスの中で変数の初期化等を行います。
initGame()の中でタイトルスクリーンを作成してaddChild()を行っています。
Main.asのコード
package {
(中略)
public class Main extends Sprite {
(中略)
public static var main_obj : Main;
public function Main() {
main_obj = this;
initVars();
initGame();
}
(中略)
private function initGame():void {
(中略)
_sceneTitle = new Title(this);
_sceneTitle.x = 400;
_sceneTitle.y = 300;
_screen.addChild(_sceneTitle);
(中略)
}
}
}
DistributionServerの派生クラスを作る
スカイサーバーサービスを利用するには、まずDistributionServerを継承したクラスを作成します。ここではNetworkManagerクラスというクラスを作成し、DistributionServerを継承しています。
NetworkManager.asのコード
package {
public class NetworkManager extends DistributionServer {
(中略)
public function NetworkManager(game:Main,
progressBar:Main = null) {
_parent = game;
_progressBar = game;
}
public function connect():void {
if(!super.initialize(Settings.SERVER_ADDRESS,
Settings.SERVER_PORT, Settings.AUTH_CODE,
Settings.CROSSDOMAIN_PORT)) { return; }
PlayerCharacter.enable();
(中略)
}
public function run():void {
turn();
}
(中略)
}
}
タイトルを作る
題名 ユーザー名入力欄 ログインボタンが付いたタイトルを作ります。ログインボタンが押されるとASPへの接続が開始されるようにします。
ready()が呼び出されると、ログインボタンが有効になり、
ログインボタンを押した際に呼び出されるコールバック関数onClickLogin()が有効になります。
ログインボタンを押すとNetworkManagerのconnect()関数が呼び出されます。
Title.asのコード
package {
(中略)
public class Title extends MovieClip {
private var _parent:Main;
public function Title(parent:Main) {
stop();
(中略)
}
public function ready():void {
nextButton.addEventListener(MouseEvent.MOUSE_DOWN,
onClickLogin);
(中略)
}
private function onClickLogin(event:MouseEvent):void {
if (nameForm.text != "") {
nextButton.removeEventListener(
MouseEvent.MOUSE_DOWN, onClickLogin);
nextButton.buttonMode = false;
_parent.connectServer(nameForm.text);
}
}
}
}
Main.asに追加
public function connectServer(name:String):void {
myName = name;
_player = new PlayerCharacter();
_networkManager.connect();
addEventListener(Event.ENTER_FRAME, connectingServer);
}
プレーヤーの各種情報を保持するアバターオブジェクトを作成する
100heartsでは複数のプレーヤーがフィールド上を移動します。これらのプレーヤ情報をTCP/IPを用いてサーバー・クライアント間で共有しようとすると
大変ですが、ASPサーバーのオブジェクト共有機能を使用すると簡単に共有することができます。
オブジェクト共有を使用するには、情報を共有したいクラスをNetworkObjectクラスを継承して作成します。
TYPE_IDはこのクラスのユニークなIDです。他の共有オブジェクトやメッセージのクラスを作成する際には、必ず別のIDを設定して下さい。このIDはNetworkObjectManager.register()関数を呼び出す時に使用します。
PlayerCharacter上で共有したいデータは、IntProperty(Int型データ)やNumberProperty(Number型データ)、StringProperty(String型データ)等のクラスのオブジェクトにして、PlayerCharacterクラスのメンバーにします。
PlayerCharacterのコンストラクタでaddProperty()を呼び出す事で、プロパティがDistributionServerに登録されます。
今回はユーザーのログインネーム、ハートの数、ステータス番号、アバターの座標と向きをプロパティにします。
PlayerCharacter.asのコード
package {
(中略)
public class PlayerCharacter extends NetworkObject {
public static const TYPE_ID:uint = 201;
public var m_userName :StringProperty = new StringProperty();
public var m_coin :IntProperty = new IntProperty();
public var m_status :IntProperty = new IntProperty();
public var m_tx :NumberProperty = new NumberProperty();
public var m_ty :NumberProperty = new NumberProperty();
public var m_tz :NumberProperty = new NumberProperty();
public var m_angle :NumberProperty = new NumberProperty();
(中略)
protected var m_is_first_update: Boolean = true;
public static function enable() : void
{
NetworkObjectManager.register( TYPE_ID, create );
}
public static function create() : NetworkObject
{
return new PlayerCharacter();
}
public function PlayerCharacter()
{
super( TYPE_ID );
addProperty( m_userName );
addProperty( m_coin );
addProperty( m_status );
addProperty( m_tx );
addProperty( m_ty );
addProperty( m_tz );
addProperty( m_angle );
}
}
}
接続後の処理を行おう
以下の、ASPサーバーチュートリアルをご説明いたします。- ASPサーバーに接続成功した後の処理を行う
- メインループ内でDistributionServerのturn()関数を呼び出します。
- 共有オブジェクトの状態変化を検知する
- グローバルチャットを実装する
- メッセージハンドラを追加しよう
ASPサーバーに接続成功した後の処理を行う
ASPサーバーへの接続が完了すると、DistributionServerのonInit()が呼び出されます。接続が完了したら、DistributionServerのaddObject()関数を呼び出して
アバターオブジェクトの共有を開始します。
共有オブジェクトの登録が完了すると、onAddObject()関数が呼び出されます。
この関数は自分のクライアントのオブジェクトの登録でも、他のクライアントのオブジェクト登録でも
呼び出されますので、NetworkObjectのlocalプロパティで自他の判別を行います。
ここでは、自オブジェクトの登録が完了したと判断した所でMainクラスのstartGame()関数を呼び出しています。
NetworkManager.asのコード
package {
public class NetworkManager extends DistributionServer {
(中略)
public function NetworkManager(game:Main,
progressBar:Main = null) {
_parent = game;
_progressBar = game;
}
public function connect():void {
if(!super.initialize(Settings.SERVER_ADDRESS,
Settings.SERVER_PORT, Settings.AUTH_CODE,
Settings.CROSSDOMAIN_PORT)) { return; }
PlayerCharacter.enable();
(中略)
}
public function run():void {
turn();
}
public override function onInit(id : uint) : void
{
super.onInit(id);
addObject(_parent._player as PlayerCharacter);
}
public override function onAddObject(
object : NetworkObject) : void
{
trace("NetworkManager: function onAddObject()");
if( object.local )
{
_parent.startGame(object.objectId);
}
else
{
_parent.addCharacter(object);
}
}
}
}
Main.asに追加
public function connectServer(name:String):void {
myName = name;
_player = new PlayerCharacter();
_networkManager.connect();
addEventListener(Event.ENTER_FRAME,
connectingServer);
}
private function connectingServer(event:Event):void {
_networkManager.run();
}
メインループ内でDistributionServerのturn()関数を呼び出します。
この関数を繰り返し呼び出す事により、ASPサーバーとの通信が実行されます。Main.asに追加
public function startGame(id:int):void {
(中略)
removeEventListener(Event.ENTER_FRAME,
connectingServer);
addEventListener(Event.ENTER_FRAME, loop);
(中略)
}
private function loop(event:Event):void {
(中略)
_networkManager.run();
(中略)
}
共有オブジェクトの状態変化を検知する
ゲーム中に、共有オブジェクトの状態変化を検知したい場合があります。100heartsでは、アバターオブジェクトのステータス番号が変化した時に
アバターの外見を変化させていますので、ステータス番号の変化が
自動的に検出されると便利です。
NetworkObjectには、プロパティが変化した時に呼ばれるコールバック関数
onPropertyUpdate()があります。onPropertyUpdate()をオーバーライドして、
その中にコードを追加します。
引数indexは初期化時にPlayerCharacter()でaddProperty()を行った順番を表します。
indexは0始まりなので、index==2 のとき、m_statusが変化したということになります
PlayerCharacter.asに追加
public override function onPropertyUpdate(index:uint):void
{
super.onPropertyUpdate(index);
if( local ) return;
if( m_is_first_update )
{
m_is_first_update = false;
init( Main.main_obj._scene, Main.main_obj._modelManager );
}
else
{
if( index == 2/*status*/ )
{
Main.main_obj.changeStatusCharacter( objectId,
m_status.value );
}
}
}
グローバルチャットを実装する
グローバルチャットを実装するには、チャットデータが入ったメッセージクラスを定義し、DistributionServerのPostAll()関数を使用してメッセージを全員に送信します。
メッセージの定義
UserMaessageを継承したクラスChatMessageを作成します。
まず、ユニークなメッセージIDを決めます。
MessageTypeRegistry.register()を呼び出し、自クラスとメッセージIDを登録します。
getMarshalSize(), marshal(), unmarshal()を定義します。
getMarshalSize()は、このクラスのデータをシリアル化した時のサイズを返すようにします。
marshal()は、このクラスのデータをバッファに書き込んでシリアル化します。
unmarshal()は、シリアル化されたバッファからクラスのメンバ変数にデータを読み込みます。
ChatMessage.as
package
{
import nine.*;
import flash.utils.ByteArray;
public class ChatMessage extends UserMessage
{
public static const MESSAGE_ID:UserMessageID
= new UserMessageID(205);
public var id : uint;
public var text : String = null;
public function ChatMessage() {
super(MESSAGE_ID);
}
public static function enable() : void {
MessageTypeRegistry.register(MESSAGE_ID, create);
}
public static function create() : Message {
return new ChatMessage();
}
public override function getMarshalSize() : int {
return 4 + Buffer.getWriteStringSize(text);
}
public override function marshal(buf:Buffer) : void {
buf.writeUInt32(id);
buf.writeString(text);
}
public override function unmarshal(buf:Buffer) : void {
id = buf.readUInt32();
text = buf.readString();
}
}
}
ASPサーバーへの接続時にメッセージクラスがDistributionServerに登録されるようにします。
NetworkManager.asに追加
public function connect():void {
(中略)
ChatMessage.enable();
(中略)
}
メッセージオブジェクトを生成してデータを設定し、DistributionServerのpostAll()で送信します。
NetworkManager.asに追加
public function sendChatMessage(text:String):void {
if(text.length == 0) return;
var msg : ChatMessage = new ChatMessage();
msg.text = text;
postAll(msg);
}
メッセージハンドラを追加しよう
メッセージを受信した時の処理を追加します。DistributionServerのhandleMessage()関数をオーバーライドします。
受信したメッセージのIDが引数のmsgに入っていますので、IDがChatMessageのものだけを処理します。
NetworkManager.asに追加
public override function handleMessage(from : uint,
msg:Message) : Boolean
{
switch( msg.messageId )
{
case ChatMessage.MESSAGE_ID.id:
return handleChatMessage( from, ChatMessage(msg) );
(中略)
default:
return false;
}
}
protected function handleChatMessage(from : uint,
msg:ChatMessage) : Boolean {
_parent.receiveChat(msg.text);
return true;
}
お問い合わせ
nineに関するお問い合わせはこちらのアドレスまでご連絡ください。
※iPhone用nineについてのお問い合わせも下記のアドレスまでご連絡ください。
※iPhone用nineについてのお問い合わせも下記のアドレスまでご連絡ください。
コミュニティ
採用情報






