113 lines
3.5 KiB
Haxe
113 lines
3.5 KiB
Haxe
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<DeviceAction, Bool>;
|
|
|
|
public var areas(default, null):Array<IActionArea>;
|
|
public var activeAreas(default, null):Map<Int, IActionArea>;
|
|
|
|
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;
|
|
}
|
|
}
|