Let's share rame position! forked from: colin challenge for professionals
ラーメンの位置を共有するサンプルです。
@author Copyright (C) naoto koshikawa, All Rights Reserved.
/**
* Copyright naoto5959 ( http://wonderfl.net/user/naoto5959 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1ZY5
*/
// forked from checkmate's colin challenge for professionals
package
{
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.system.Capabilities;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import net.user1.reactor.Attribute;
import net.user1.reactor.IClient;
import net.user1.reactor.Reactor;
import net.user1.reactor.ReactorEvent;
import net.user1.reactor.Room;
import net.user1.reactor.RoomEvent;
[SWF(width = "465", height = "465", backgroundColor = "0x111111", frameRate = "30")]
/**
* ラーメンの位置を共有するサンプルです。
* @author Copyright (C) naoto koshikawa, All Rights Reserved.
*/
public class UnionForWonderfl001 extends Sprite
{
//----------------------------------------------------------------------
// properties
//----------------------------------------------------------------------
//------------------------------
// static proeperties
//------------------------------
/**
* 接続先のUnionServerのホストを指定します。
* tryunion.comは無償のテストサーバ
*/
public static const UNION_SERVER_HOST:String = "tryunion.com";
/**
* 接続先のUnionSeverのポートを指定します。
*/
public static const UNION_SERVER_PORT:Number = 9100;
/**
* 接続先のRoom名を指定します。
*/
public static const ROOM_NAME:String = "naoto5959UnionForWonderfl001";
/**
* Roomへ設定するラーメンのポジションを指定します。
*/
public static const RAMEN_POSITION:String = "ramenPosition";
/**
* ラーメンのポジションを指定する際のセパレーター
*/
public static const RAMEN_SEPARATER:String = ",";
/**
* メッセージ用
*/
public static const CHAT_MESSAGE:String = "CHAT_MESSAGE";
/**
* ラーメンの画像を指定します。
*/
public static const RAMEN_URL:String = "http://farm3.static.flickr.com/2589/3787648401_0b3d62a314_o.png";
//------------------------------
// private properties
//------------------------------
/**
* Reactorクラスのインスタンス Union Serverへ接続する際に作成するClientみたいなものです
* @see http://keno.serio.jp/union/docs/reactor/api/net/user1/reactor/Reactor.html
*/
private var _reactor:Reactor;
/**
* Roomクラスのインスタンス Union Server上に作成する部屋みたいなものです。
* http://keno.serio.jp/union/docs/reactor/api/net/user1/reactor/Room.html
*/
private var _room:Room;
//------------------------------
// Display Object
//------------------------------
/**
* ローディング中のアニメーション
*/
private var _loadingCircle:LoadingCircle;
/**
* ラーメンの画像を表示するLoaderです。
*/
private var _ramenLoader:Loader;
/**
* ラーメンコンテナ
*/
private var _ramenDonburi:Sprite;
/**
* メッセージを表示するフィールドです。
*/
private var _message:TextField;
//----------------------------------------------------------------------
// method
//----------------------------------------------------------------------
/**
* constructor
*/
public function UnionForWonderfl001()
{
buildUI();
loadRamen();
}
/**
* User Interfaceを構築します
*/
private function buildUI():void
{
// ローディング中を表すモーションを開始します。
_loadingCircle = new LoadingCircle({color:0xFF0000});
addChildAt(_loadingCircle, 0);
_loadingCircle.x = stage.stageWidth / 2;
_loadingCircle.y = stage.stageHeight / 2;
// メッセージ表示用フィールドを作成します。
_message = new TextField();
_message.defaultTextFormat = new TextFormat("_等幅", 12, 0xFFFFFF);
_message.type = TextFieldType.DYNAMIC;
_message.mouseEnabled = false;
_message.width = _message.height = 465;
addChildAt(_message, 0);
}
/**
* most important method
* ラーメンの画像をロードする大事なメソッドです。
*/
private function loadRamen():void
{
_ramenDonburi = new Sprite();
_ramenDonburi.visible = false;
_ramenLoader = new Loader();
_ramenDonburi.addChild(_ramenLoader);
var ramenLoaderInfo:LoaderInfo = _ramenLoader.contentLoaderInfo;
ramenLoaderInfo.addEventListener(Event.COMPLETE, ramenLoaderInfo_completeHandler);
_ramenLoader.load(new URLRequest(RAMEN_URL));
}
/**
* prepare connection
* Union Serverとの接続準備を行います。
*/
private function prepareConnection():void
{
// 第一引数は接続設定をxmlで指定する際に指定。今回は指定しないのでnull
// 第二引数はReactorのtraceログを出力するかどうかのフラグ。
// 今回はflashオーサリング上からの実行時に出力する設定にしてあります
_reactor = new Reactor(null, Capabilities.playerType == "External");
_reactor.addEventListener(ReactorEvent.READY, _reactor_readyHandler);
_reactor.connect(UNION_SERVER_HOST, UNION_SERVER_PORT);
}
/**
* join Room
* Roomインスタンスを作成してjoinします。
* Union Server上のRoomにjoinします。
*/
private function join():void
{
// Reactorインスタンスを使ってRoomインスタンスを生成します。
// 既に存在する部屋(他のクライアントが作成済み)の場合はその部屋のインスタンスを生成します。
_room = _reactor.getRoomManager().createRoom(ROOM_NAME);
_room.addEventListener(RoomEvent.JOIN, _room_joinHandler);
_room.addEventListener(RoomEvent.SYNCHRONIZE, _room_removeClientHandler);
_room.addEventListener(RoomEvent.ADD_CLIENT, _room_addClientHandler);
_room.addEventListener(RoomEvent.REMOVE_CLIENT, _room_removeClientHandler);
_room.addEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, _room_updateRoomAttribute);
_room.addMessageListener(CHAT_MESSAGE, _room_chatMessageHandler);
_room.join();
}
/**
* ユーザーからのイベントを監視開始します。
*/
private function listenUserEvent():void
{
stage.addEventListener(MouseEvent.CLICK, stage_clickHandler);
}
/**
* ラーメンの位置を送信します。
*/
private function sendRamenPosition(ramenX:Number, ramenY:Number):void
{
var attributeValue:String = new Array(ramenX, ramenY).join(RAMEN_SEPARATER);
// Roomの属性にラーメンのポジションを設定します。
_room.setAttribute(RAMEN_POSITION, attributeValue);
// messageを送信します。
_room.sendMessage(CHAT_MESSAGE, true, null, " sets " + attributeValue);
}
/**
* ラーメンの位置を受信します。
*/
private function receiveRamenPosition(ramenPosition:String):void
{
_ramenDonburi.visible = true;
var ramenPositions:Array = ramenPosition.split(RAMEN_SEPARATER);
var ramenX:Number = Number(ramenPositions[0]);
var ramenY:Number = Number(ramenPositions[1]);
_ramenDonburi.x = ramenX;
_ramenDonburi.y = ramenY;
}
//------------------------------
// event handler
//------------------------------
/**
* _ramenLoader.contentLoaderInfoからEvent.COMPLETEイベントが送出された際に呼ばれるハンドラです
* ラーメン画像を良い感じに調整します。
* @param event
*/
private function ramenLoaderInfo_completeHandler(event:Event):void
{
_ramenLoader.width = 120;
// widthを調整したのでheightも比率を保ってスケールを調整する
_ramenLoader.scaleY = _ramenLoader.scaleX;
// ラーメンコンテナーの中央に移動する
_ramenLoader.x -= _ramenLoader.width / 2;
_ramenLoader.y -= _ramenLoader.height / 2;
addChild(_ramenDonburi);
// 接続準備
prepareConnection();
}
/**
* _reactorからReactorEvent.READYイベントが送出された際に呼ばれるハンドラです。
* @param event
*/
private function _reactor_readyHandler(event:ReactorEvent):void
{
join();
}
/**
* _roomからRoomEvent.JOINイベントが送出された際に呼ばれるハンドラです。
* サーバにjoinした際に実行されます。
* @param event
*/
private function _room_joinHandler(event:RoomEvent):void
{
removeChild(_loadingCircle);
listenUserEvent();
// joinしたらランダムな位置へ移動させる
var ramenX:Number = Math.floor(Math.random() * 465) + 1;
var ramenY:Number = Math.floor(Math.random() * 465) + 1;
sendRamenPosition(ramenX, ramenY);
}
/**
* _roomからRoomEvent.SYNCHRONIZEイベントが送出された際に呼ばれるハンドラです。
* サーバとの同期が取れた際に実行されます。
* 自分が入室した際に、既にいるユーザの準備を行うことになると思います。
* @param event
*/
private function _room_synchronizeHandler(event:RoomEvent):void
{
}
/**
* _roomからRoomEvent.ADD_CLIENTイベントが送出された際に呼ばれるハンドラです。
* 自分よりも後に入室した人が居た場合に送出されます。
* 「誰々さんが入室しましたよ!」というメッセージの出力や、新しいユーザの準備などを行うことになると思います。
* @param event
*/
private function _room_addClientHandler(event:RoomEvent):void
{
}
/**
* _roomからRoomEvent.REMOVE_CLIENTイベントが送出された際に呼ばれるハンドラです。
* 自分よりも後に退室した人が居た場合に送出されます。
* 「誰々さんが退室室しましたよ!」というメッセージの出力や、出て行ったユーザの後処理などを行うことになると思います。
* @param event
*/
private function _room_removeClientHandler(event:RoomEvent):void
{
}
/**
* _roomからRoomEvent.UPDATE_ROOM_ATTRIBUTEイベントが送出された際に呼ばれるハンドラです。
* ルームの属性が変更された場合に呼ばれます。ルームで共有する情報更新時の処理を行います。
*/
private function _room_updateRoomAttribute(event:RoomEvent):void
{
var changedAttribute:Attribute = event.getChangedAttr();
if (changedAttribute.name == RAMEN_POSITION)
{
receiveRamenPosition(changedAttribute.value);
}
}
/**
* _roomからMessageが送信された際に呼ばれるハンドラです。
* @param fromClient
* @param message
*/
private function _room_chatMessageHandler(fromClient:IClient, message:String):void
{
_message.appendText("client" + fromClient.getClientID() + message + "\n");
_message.scrollV = _message.maxScrollV;
}
/**
* stageからMouseEvent.CLICKイベントが送出された際に呼ばれるハンドラです。
*/
private function stage_clickHandler(event:MouseEvent):void
{
sendRamenPosition(mouseX, mouseY);
}
}
}
import caurina.transitions.Tweener;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
/**
* simple loding circle
*/
class LoadingCircle extends Sprite
{
// _____________________________________________________ Property
private const DEFAULT_COLOR:uint = 0x000000;
private const DEFAULT_RADIUS:Number = 20;
private const DEFAULT_SIZE:Number = 4.5;
private const DEFAULT_COUNT:uint = 10;
/** color */
private var _color:uint;
/** radius */
private var _radius:Number;
/** per size */
private var _size:Number;
/** circle count */
private var _count:uint;
// _____________________________________________________ Method
/**
* constructor
*/
public function LoadingCircle(initObject:Object = null)
{
super();
if (initObject && initObject.color) _color = initObject.color;
else _color = DEFAULT_COLOR;
if (initObject && initObject.radius) _radius = initObject.radius;
else _radius = DEFAULT_RADIUS;
if (initObject && initObject.size) _size = initObject.size;
else _size = DEFAULT_SIZE;
if (initObject && initObject.count) _count = initObject.count;
else _count = DEFAULT_COUNT;
draw();
play();
}
/**
* draw circle grapic
*/
public function draw():void
{
var i:uint;
var radian:Number;
graphics.clear();
for (i= 0; i < _count; i++)
{
radian = Math.PI * 2 * (i / _count);
graphics.beginFill(_color, (i+1) / _count);
graphics.drawCircle(Math.cos(radian) * _radius, Math.sin(radian) * _radius, _size);
}
}
/**
* play rotate motion
*/
public function play():void
{
visible = true;
Tweener.addTween(this, { rotation:360, time:2, onComplete:play, transition:"easeOutSine", delay:0 } );
}
/**
* stop rotate motion
*/
public function stop():void
{
Tweener.removeTweens(this);
visible = false;
}
}