TouchEvents Reciever
forked from マルチタッチすきま妖怪 (diff: 289)
see: https://github.com/civet/AS3-TouchRemote
ActionScript3 source code
/**
* Copyright civet ( http://wonderfl.net/user/civet )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7iEO
*/
// forked from moyashipan's マルチタッチすきま妖怪
package
{
import caurina.transitions.Equations;
import caurina.transitions.Tweener;
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.events.TouchEvent;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.utils.Dictionary;
import flash.ui.Mouse;
/**
* For Flash Player 10.1
* For Multitouch Device
*
* スキマを作って くぱぁ
*
* 参考 :Adobe Labs - Adobe AIR 2 Beta 2 Sample Applications
* labs.adobe.com/technologies/air2/samples/
* @author Shinichiro Sugimoto
*/
public class Main extends Sprite
{
private var _downQueue:Vector.<int> = new Vector.<int>;
private var tPointList:Dictionary = new Dictionary();
private var lastSlit:Slit;
public function Main():void
{
//Logger
setupLogger();
//UI
stage.addChild(new BlobDisplayer());
//Client
client = new Client("127.0.0.1", 8686);
client.onData = onData;
client.start();
Mouse.hide();
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
stage.addEventListener(TouchEvent.TOUCH_BEGIN, tStart, false, 0, true);
}
private function tStart(e:TouchEvent):void
{
if (e.target != e.currentTarget) return;
if (tPointList[e.touchPointID] == null) {
stage.addEventListener(TouchEvent.TOUCH_MOVE, tMove, false, 0, true);
stage.addEventListener(TouchEvent.TOUCH_END, tEnd, false, 0, true);
}
_downQueue.push(e.touchPointID);
tPointList[e.touchPointID] = new Point(e.stageX, e.stageY);
}
private function tMove(e:TouchEvent):void
{
tPointList[e.touchPointID] = new Point(e.stageX, e.stageY);
if (_downQueue.length >= 2) {
this.graphics.clear();
this.graphics.lineStyle(4, 0, 0.2);
this.graphics.moveTo(p0.x, p0.y);
this.graphics.lineTo(p1.x, p1.y);
}else {
this.graphics.clear();
}
}
private function tEnd(e:TouchEvent):void
{
if (_downQueue.length == 2) {
createSlit(p0, p1);
}else {
this.graphics.clear();
}
tPointList[e.touchPointID] = null;
var i:int = _downQueue.indexOf(e.touchPointID);
if (i < 0) return;
_downQueue.splice(i, 1);
}
private function createSlit(p0:Point, p1:Point):void
{
var len:Number = Point.distance(p0, p1);
// 指が近すぎると誤認識するのでその対策
if (len < 200) return;
if (lastSlit != null) {
lastSlit.close();
}
lastSlit = new Slit(p0, p1);
this.addChild(lastSlit);
}
public function get p0():Point { return tPointList[_downQueue[0]]; }
public function get p1():Point { return tPointList[_downQueue[1]]; }
//------
private var client:Client;
private function setupLogger():void
{
Logger.mode = 1;
var output:TextField = Logger.textField;
output.mouseEnabled = false;
output.selectable = false;
output.width = 465;
output.height = 40;
output.defaultTextFormat = new TextFormat("Arial", 12, 0x666666);
output.backgroundColor = 0xffffcc;
output.background = true;
this.addChild(output);
}
private function onData(data:String):void
{
var blocks:Array = data.split("|");
var num:int = blocks.length;
for(var i:int=0; i<num; ++i)
{
var block:String = blocks[i];
if(block && block != "")
{
var args:Array = block.split(",");
var type:String = args[0];
var id:int = parseInt( args[1] );
var mx:int = parseInt( args[2] );
var my:int = parseInt( args[3] );
dispatchTouchEvent( getTarget(mx, my), type, id, mx, my);
}
}
}
private var pt:Point = new Point();
private function getTarget(x:Number, y:Number):DisplayObject
{
var target:DisplayObject;
pt.x = x;
pt.y = y;
var objects:Array = this.stage.getObjectsUnderPoint(pt);
var i:int = objects.length;
while(i--) {
var obj:Object = objects[i];
if(obj is InteractiveObject && !(obj is Blob)) {
target = obj as DisplayObject;
break;
}
}
if(target == null) target = this.stage;
return target;
}
private function dispatchTouchEvent(target:DisplayObject, eventType:String, pointID:int, stageX:int, stageY:int):void
{
var evt:TouchEvent = new TouchEvent(eventType, true, false, pointID);
pt.x = stageX;
pt.y = stageY;
var localPoint:Point = target.globalToLocal(pt);
evt.localX = localPoint.x;
evt.localY = localPoint.y;
target.dispatchEvent(evt);
}
}
}
import flash.events.SecurityErrorEvent;
import caurina.transitions.Tweener;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.TouchEvent;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.utils.Dictionary;
//スキマ
class Slit extends Sprite
{
// くぱぁ可能領域(線)の太さ
private static const kuparableThickness:uint = 96;
private var p0:Point;
private var p1:Point;
private var g:Graphics;
private var _downQueue:Vector.<int> = new Vector.<int>;
private var tPointList:Dictionary = new Dictionary();
private var controlPoint0:Point;
private var controlPoint1:Point;
private var anchorPoint0:Point;
private var anchorPoint1:Point;
private var middlePoint:Point;
private var distPoint:Point;
private var len:Number;
private var texture:BitmapData;
public function Slit(p0:Point, p1:Point)
{
super();
this.p0 = p0;
this.p1 = p1;
g = graphics;
middlePoint = Point.interpolate(p0, p1, .5);
distPoint = p1.subtract(p0);
len = distPoint.length;
var normalVec:Point = Point.polar(1, Math.atan2(distPoint.x, distPoint.y));
normalVec.x *= len * 0.02;
normalVec.y *= len * 0.02;
controlPoint0 = middlePoint.add(normalVec);
controlPoint1 = middlePoint.subtract(normalVec);
anchorPoint0 = controlPoint0.clone();
anchorPoint1 = controlPoint1.clone();
filters = [new BlurFilter()];
createTexture();
draw();
this.addEventListener(TouchEvent.TOUCH_BEGIN, tStart, false, 0, true);
}
private function createTexture():void
{
texture = new BitmapData(100, 100, false, 0x300020);
var eye:Sprite = new Sprite();
var g:Graphics = eye.graphics;
g.lineStyle();
g.beginFill(0xffffff, 1);
g.moveTo(40, 0);
g.curveTo(0, 20, -40, 0);
g.curveTo(0, -20, 40, 0);
g.endFill();
g.beginFill(0xb00000, 1);
g.drawCircle(0, 0, 10);
g.endFill();
g.beginFill(0, 1);
g.drawCircle(0, 0, 4);
g.endFill();
texture.draw(eye, new Matrix(1, 0, 0, 1, 40, 25));
texture.draw(eye, new Matrix(1, 0, 0, 1, 60, 75));
eye = null;
}
public function close():void {
mouseChildren =
mouseEnabled = false;
Tweener.addTween(this, {delay:6, time: 4, alpha:0, transition:"easeoutquart", onUpdate:shutEye, onComplete:function():void { this.parent.removeChild(this); } } );
}
private function shutEye():void
{
controlPoint0 = Point.interpolate(middlePoint, controlPoint0, 0.1);
controlPoint1 = Point.interpolate(middlePoint, controlPoint1, 0.1);
draw();
}
private function draw():void {
g.clear();
var kuparablePoint0:Point = getKuparablePoint(controlPoint0);
var kuparablePoint1:Point = getKuparablePoint(controlPoint1);
g.lineStyle(4, 0, 0.5);
//g.beginFill(0x300020);
g.beginBitmapFill(texture, new Matrix(1, 0, 0, 1, middlePoint.x, middlePoint.y));
g.moveTo(p0.x, p0.y);
g.curveTo(controlPoint0.x, controlPoint0.y, p1.x, p1.y);
g.curveTo(controlPoint1.x, controlPoint1.y, p0.x, p0.y);
g.endFill();
g.lineStyle(kuparableThickness, 0xff0000, 0);
g.moveTo(p0.x, p0.y);
g.curveTo(kuparablePoint0.x, kuparablePoint0.y, p1.x, p1.y);
g.curveTo(kuparablePoint1.x, kuparablePoint1.y, p0.x, p0.y);
}
private function getKuparablePoint(controlPoint:Point):Point
{
return Point.interpolate(middlePoint, controlPoint, 0);
}
private function tStart(e:TouchEvent):void
{
if (tPointList[e.touchPointID] == null) {
stage.addEventListener(TouchEvent.TOUCH_MOVE, tMove, false, 0, true);
stage.addEventListener(TouchEvent.TOUCH_END, tEnd, false, 0, true);
}
_downQueue.push(e.touchPointID);
tPointList[e.touchPointID] = new Point(e.stageX, e.stageY);
}
private function tMove(e:TouchEvent):void
{
var tp:Point = new Point(e.stageX, e.stageY);
tPointList[e.touchPointID] = tp.clone();
if (Point.distance(tp, controlPoint0) < Point.distance(tp, controlPoint1)) {
controlPoint0 = tp;
}else {
controlPoint1 = tp;
}
draw();
}
private function tEnd(e:TouchEvent):void
{
tPointList[e.touchPointID] = null;
var i:int = _downQueue.indexOf(e.touchPointID);
if (i < 0) return;
_downQueue.splice(i, 1);
if (_downQueue.length < 1) {
stage.removeEventListener(TouchEvent.TOUCH_MOVE, tMove);
stage.removeEventListener(TouchEvent.TOUCH_END, tEnd);
//ピタリと閉じる
//if (Point.distance(controlPoint0, controlPoint1) < 50) {
//this.removeEventListener(TouchEvent.TOUCH_BEGIN, tStart);
//this.parent.removeChild(this);
//}
}
}
public function get tp0():Point { return tPointList[_downQueue[0]]; }
public function get tp1():Point { return tPointList[_downQueue[1]]; }
}
//------
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.utils.setTimeout;
class Client
{
private var _socket:Socket;
private var _address:String;
private var _port:int;
public function Client(address:String, port:int)
{
_socket = new Socket();
_address = address;
_port = port;
}
public function start():void
{
_socket.addEventListener(Event.CONNECT, onConnect);
_socket.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
_socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
_socket.addEventListener(Event.CLOSE, onServerClose);
_socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
_socket.connect(_address, _port);
}
private function onConnect(event:Event):void
{
Logger.log( "Connected!");
}
private function onSocketData(event:ProgressEvent):void
{
var message:String = _socket.readUTFBytes(_socket.bytesAvailable);
//Logger.log( message );
if(onData != null) onData( message );
}
private function onIOError(event:IOErrorEvent):void
{
Logger.log( event.text );
Logger.log( "Reconnect after 5 sec...");
setTimeout(_socket.connect, 5000, _address, _port);
}
private function onSecurityError(event:SecurityErrorEvent):void
{
Logger.log( event.text );
Logger.log( "Reconnect after 5 sec..." );
setTimeout(_socket.connect, 5000, _address, _port);
}
private function onServerClose(event:Event):void
{
Logger.log( "Server closed." );
Logger.log( "Reconnect after 5 sec..." );
setTimeout(_socket.connect, 5000, _address, _port);
}
public function get connected():Boolean { return _socket.connected; }
public var onData:Function;
}
//------
import flash.display.Sprite;
import flash.filters.GlowFilter;
class Blob extends Sprite
{
public function Blob()
{
this.graphics.beginFill(0x0, 0);
this.graphics.drawCircle(0, 0, 20);
this.graphics.endFill();
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(0, 0, 20);
this.graphics.drawCircle(0, 0, 15);
this.graphics.endFill();
this.filters = [new GlowFilter(0x0, 1.0, 4, 4, 1)];
}
}
//------
import flash.display.DisplayObject;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.TouchEvent;
import flash.geom.Point;
class BlobDisplayer extends Sprite
{
public function BlobDisplayer()
{
this.stage ? initialize() : this.addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(event:Event=null):void
{
if(event) this.removeEventListener(event.type, initialize);
this.stage.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
this.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
this.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
protected function onTouchBegin(event:TouchEvent):void
{
var blob:Sprite = getBlob(event.touchPointID);
if(blob) {
blob.x = event.stageX;
blob.y = event.stageY;
this.addChild(blob);
}
}
protected function onTouchMove(event:TouchEvent):void
{
var blob:Sprite = getBlob(event.touchPointID);
if(blob) {
blob.x = event.stageX;
blob.y = event.stageY;
}
}
protected function onTouchEnd(event:TouchEvent):void
{
var blob:Sprite = getBlob(event.touchPointID);
if(blob) {
if(blob.stage) this.removeChild(blob);
disposeBlob(event.touchPointID, blob);
}
}
//------Object Pool------
protected var _blobPool:Array = [];
protected var _blobHash:Object = {};
protected function getBlob(id:int):Sprite
{
var blob:Sprite = _blobHash[id.toString()];
if(!blob) {
blob = createBlob();
_blobHash[id.toString()] = blob;
}
return blob;
}
protected function createBlob():Sprite
{
return _blobPool.pop() || new Blob();
}
protected function disposeBlob(id:int, blob:Sprite):void
{
_blobHash[id.toString()] = null;
_blobPool.push(blob);
}
}
//------
import flash.text.TextField;
class Logger
{
public static const DEBUG:int = 0;
public static const INFO:int = 1;
public static const WARN:int = 2;
public static const ERROR:int = 3;
public static var labels:Array = ["debug", "info", "warn", "error"];
public static var mode:int = 0;
public static var textField:TextField = new TextField();
public static function log(msg:String, level:int=0):void
{
msg = "[" + labels[level] + "] " + msg;
if(mode == 0) {
trace(msg);
}
else if(mode == 1) {
textField.appendText(msg + "\n");
textField.scrollV = textField.maxScrollV;
}
}
}