TouchEvents Reciever

by civet forked from マルチタッチすきま妖怪 (diff: 289)
see: https://github.com/civet/AS3-TouchRemote
♥0 | Line 433 | Modified 2013-06-07 17:01:46 | MIT License
play

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;
        }
    }
}