位置情報の共有(RTMFP:post版)
/**
* Copyright linktale ( http://wonderfl.net/user/linktale )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gCVS
*/
/*
sendToAllNeighborsだと補正なしでいけました!
http://wonderfl.net/c/wHvh
アニメーションの位置情報を共有するデモ
1. 同じLAN内で、複数のPCあるいはブラウザでこのページを表示
2. 左から順にAdd Groupを1回づつクリック
3. 最初にAdd GroupをクリックしたplayerでStartをクリック
4. 左から右にパーティクルが移動
※コマ落ち、送受信のタイムラグあり
動画:https://vimeo.com/42927571
解説1:http://linktale.net/log/as3/rtmfp_1/
解説2:http://linktale.net/log/as3/rtmfp_2/
参考:
http://www.digifie.jp/blog/
http://www.mztm.jp/2012/05/21/rtmfpspeed-test/
http://wonderfl.net/c/vXBY
http://wonderfl.net/c/edvz
*/
package
{
import com.bit101.components.*;
import com.flashdynamix.utils.SWFProfiler;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.TimerEvent;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import flash.utils.getTimer;
import flash.utils.Timer;
import idv.cjcat.stardust.common.actions.Age;
import idv.cjcat.stardust.common.actions.DeathLife;
import idv.cjcat.stardust.common.actions.ScaleCurve;
import idv.cjcat.stardust.common.clocks.SteadyClock;
import idv.cjcat.stardust.common.initializers.Life;
import idv.cjcat.stardust.common.math.UniformRandom;
import idv.cjcat.stardust.twoD.actions.Accelerate;
import idv.cjcat.stardust.twoD.actions.Move;
import idv.cjcat.stardust.twoD.emitters.Emitter2D;
import idv.cjcat.stardust.twoD.handlers.DisplayObjectHandler;
import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass;
import idv.cjcat.stardust.twoD.initializers.Position;
import idv.cjcat.stardust.twoD.initializers.Velocity;
import idv.cjcat.stardust.twoD.zones.LazySectorZone;
import idv.cjcat.stardust.twoD.zones.SinglePoint;
public class Index extends Sprite {
private const SERVER:String = "rtmfp:";
private var nc:NetConnection;
private var netGroup:NetGroup;
private var groupList:Object = new Object();
private var sequence:uint = 1;
private var textArea:TextArea;
private var time:int = 0;
private var timer:Timer;
private var emitter:Emitter2D;
private var point:SinglePoint;
public function Index():void {
//SWFProfiler.init(stage, this);
//Wonderfl.capture_delay(10);
Wonderfl.disable_capture();
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void {
graphics.beginFill(0x121212);
graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
graphics.endFill();
removeEventListener(Event.ADDED_TO_STAGE, init);
setComponents();
setEmitters();
connect();
}
private function setComponents():void {
Style.embedFonts = false;
Style.fontName = "_typewriter";
Style.fontSize = 12;
var addGroupdButton:PushButton = new PushButton(this, 10, stage.stageHeight - 30, "Add Group", addGroup);
var startButton:PushButton = new PushButton(this, 120, stage.stageHeight - 30, "Start", start);
textArea = new TextArea(this, 10, 15);
textArea.width = stage.stageWidth-20;
textArea.height = 100;
}
private function setEmitters():void {
var mc:MovieClip = new MovieClip();
mc.y = 300;
addChild(mc);
var clock: SteadyClock = new SteadyClock(2);
emitter = new Emitter2D(clock);
emitter.particleHandler = new DisplayObjectHandler(mc);
point = new SinglePoint();
//initializer
emitter.addInitializer(new DisplayObjectClass(Circle));
emitter.addInitializer(new Position(point));
emitter.addInitializer(new Velocity(new LazySectorZone(1, 0)));
emitter.addInitializer(new Life(new UniformRandom(30, 0)));
//actions
emitter.addAction(new Age());
emitter.addAction(new DeathLife());
emitter.addAction(new Accelerate(0.025));
emitter.addAction(new Move());
emitter.addAction(new ScaleCurve(15, 15));
}
private function connect():void {
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS,netStatus);
nc.connect(SERVER);
}
private function netStatus(e:NetStatusEvent):void {
//write(e.info.code);
switch(e.info.code){
case "NetConnection.Connect.Success":
setupGroup();
break;
case "NetGroup.Connect.Success":
write("nc.nearID:" + nc.nearID);
break;
case "NetGroup.Neighbor.Connect":
write("e.info.peerID:"+e.info.peerID);
break;
case "NetGroup.Neighbor.Disconnect":
break;
case "NetGroup.Posting.Notify":
if(e.info.message.sequence){
sequence = e.info.message.sequence;
write("sequence:" + e.info.message.sequence);
}else if(e.info.message.start){
startGroup();
write("startGroup");
}else if(e.info.message.time){
updateGroup(e.info.message.time);
}
break;
}
}
private function start(e:MouseEvent = null):void {
addEventListener(Event.ENTER_FRAME, update);
send("start", true);
}
private function startGroup(e:MouseEvent = null):void {
addEventListener(Event.ENTER_FRAME, updateOwnGroup);
}
private function update(e:Event):void {
time += 20;
point.x = ((stage.stageWidth * ((Math.cos(time / 666)-1) * -0.5)) * (sequence - 1)) - (stage.stageWidth * (groupList[nc.nearID]-1) );
point.y = 120 * Math.sin(time / 222);
emitter.step();
send("time", time);
}
private function updateGroup(ptime:int):void {
time = ptime;
point.x = ((stage.stageWidth * ((Math.cos(time / 666)-1) * -0.5)) * (sequence - 1)) - (stage.stageWidth * (groupList[nc.nearID]-1) );
point.y = 120 * Math.sin(time / 222);
}
private function updateOwnGroup(e:Event):void {
time += 20;
point.x = ((stage.stageWidth * ((Math.cos(time / 666)-1) * -0.5)) * (sequence - 1)) - (stage.stageWidth * (groupList[nc.nearID]-1) );
point.y = 120 * Math.sin(time / 222);
emitter.step();
}
private function send(name:String, val:*):void {
var message:Object = new Object();
message.sender = netGroup.convertPeerIDToGroupAddress(nc.nearID);
message[name] = val;
netGroup.post(message);
}
private function setupGroup():void {
var groupspec:GroupSpecifier = new GroupSpecifier("group/linktale");
groupspec.ipMulticastMemberUpdatesEnabled = true;
groupspec.multicastEnabled = true;
groupspec.addIPMulticastAddress("225.225.0.1:44444"); //19350〜65535
groupspec.serverChannelEnabled = true;
groupspec.postingEnabled = true;
groupspec.routingEnabled = true;
netGroup = new NetGroup(nc, groupspec.groupspecWithAuthorizations());
netGroup.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
}
private function addGroup(e:MouseEvent):void {
groupList[nc.nearID] = sequence;
sequence++;
send("sequence", sequence);
}
private function write(text:String):void{
textArea.text += text+"\n";
}
}
}
import flash.display.Sprite;
class Circle extends Sprite {
public function Circle() {
var size:uint = 10;
graphics.beginFill(0xffffff, 0.35);
graphics.drawCircle(0, 0, size);
graphics.beginFill(0xffffff, 1.0);
graphics.drawCircle(0, 0, size/2);
}
}