package ru.m.tankz.view.gamepad; import flash.display.Stage; import flash.events.MouseEvent; import flash.events.TouchEvent; import haxework.signal.Signal; import haxework.view.SpriteView; import ru.m.control.DeviceAction; import ru.m.control.DeviceType; import ru.m.control.IControlDevice; import ru.m.geom.Point; class GamepadView extends SpriteView implements IControlDevice { public var type(default, null):DeviceType; public var signal(default, null):Signal2; public var areas(default, null):Array; public var activeAreas(default, null):Map; private var builder:IActionAreaBuilder; private var stage:Stage; public function new() { super(); style = "gamepad"; type = SCREEN; builder = new SmartActionAreaBuilder(); signal = new Signal2(); areas = []; activeAreas = new Map(); skin = new GamepadSkin(); content.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); content.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin); } private function onMouseDown(event:MouseEvent):Void { onMouseMove(event); stage = content.stage; stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function onMouseMove(event:MouseEvent):Void { var point = new Point(event.localX, event.localY); updateTouch(-1, point); } private function onMouseUp(event:MouseEvent):Void { endTouch(-1); stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); } private function onTouchBegin(event:TouchEvent):Void { onTouchMove(event); stage = content.stage; stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd); } private function onTouchMove(event:TouchEvent):Void { var point = new Point(event.localX, event.localY); updateTouch(event.touchPointID, point); } private function onTouchEnd(event:TouchEvent):Void { endTouch(event.touchPointID); if (Lambda.count(activeAreas) == 0) { stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove); stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd); } } private function updateTouch(pointID:Int, point:Point):Void { if (activeAreas.exists(pointID)) { var area = activeAreas[pointID]; if (!area.contain(point)) { activeAreas.remove(pointID); signal.emit(area.action, false); toRedraw(); } } else { for (area in areas) { if (area.contain(point)) { activeAreas[pointID] = area; signal.emit(area.action, true); toRedraw(); break; } } } } private function endTouch(pointID:Int):Void { if (activeAreas.exists(pointID)) { signal.emit(activeAreas[pointID].action, false); activeAreas.remove(pointID); toRedraw(); } } override public function update():Void { super.update(); areas = builder.build(width, height); } public function dispose():Void { stage = null; } }