As3 中同时使用多个虚拟摇杆

Multiple virtual Joystick use simultaneously in As3

我目前正在 android 上制作 space 射击游戏(A.K.A:地狱子弹)。所以我为 2 个操纵杆制作了一个底座 class,我将它们分别用于 Move 和 Fire。现在,如果我一次只移动一个,但不是同时移动,我的代码就可以工作。所以我做了一些研究并找到了有关多点触控的信息,我尝试了一些方法但没有任何效果。

有人知道为什么吗?

Joystick.as (使用 mouseEvent 一次工作一个) :

package LP {

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;

public class Joystick extends MovieClip {

    private var _startX: Number = 0;
    private var _startY: Number = 0;
    private var _tension: Number = 0.3;
    private var _xSpeed: Number = 0;
    public var _isDragging: Boolean = false;
    public var _angle: int;
    private var _radius: int;
    public var _amplitudeX: Number;
    public var _amplitudeY: Number;

    public function Joystick() {
        this.addEventListener(Event.ADDED_TO_STAGE, stageInit);
    }

    private function stageInit(e: Event): void {
        this.removeEventListener(Event.ADDED_TO_STAGE, stageInit);

        _startX = x;
        _startY = y;
        _radius = background.width / 2

        addEventListener(MouseEvent.MOUSE_DOWN, on_mouseDown);
        stage.addEventListener(MouseEvent.MOUSE_UP, on_mouseUp);
        stage.addEventListener(Event.ENTER_FRAME, on_enterFrame);
    }

    protected function on_mouseDown(e: MouseEvent): void {
        _isDragging = true;
    }


    protected function on_mouseUp(e: MouseEvent): void {
        _isDragging = false;
    }

    protected function on_enterFrame(e: Event): void {

        if (_isDragging) {
            _angle = Math.atan2(root.mouseY - _startY, root.mouseX - _startX) / (Math.PI / 180);
            rotation = _angle;
            stick.rotation = -_angle;

            stick.x = mouseX;
            if (stick.x > _radius) {
                stick.x = _radius;
            }
        } else {
            _xSpeed = -stick.x * _tension;
            stick.x += _xSpeed;
        }

        _amplitudeY = Math.sin(_angle * (Math.PI / 180)) * (stick.x / 8);
        _amplitudeX = Math.cos(_angle * (Math.PI / 180)) * (stick.x / 8);


    }


}

}

这是我对 MultitouchInputMode.GESTURE 的尝试(不起作用,没有任何反应,也没有错误)

package LP {

import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;

public class Joystick extends MovieClip {

    Multitouch.inputMode = MultitouchInputMode.GESTURE;

    private var _startX: Number = 0;
    private var _startY: Number = 0;
    private var _tension: Number = 0.3;
    private var _xSpeed: Number = 0;
    public var _isDragging: Boolean = false;
    public var _angle: int;
    private var _radius: int;
    public var _amplitudeX: Number;
    public var _amplitudeY: Number;

    public function Joystick() {
        this.addEventListener(Event.ADDED_TO_STAGE, stageInit);
    }

    private function stageInit(e: Event): void {
        this.removeEventListener(Event.ADDED_TO_STAGE, stageInit);

        _startX = x;
        _startY = y;
        _radius = background.width / 2

        addEventListener(TouchEvent.TOUCH_BEGIN, on_Touch);
        stage.addEventListener(TouchEvent.TOUCH_END, on_TouchEnd);

        stage.addEventListener(Event.ENTER_FRAME, on_enterFrame);
    }

    protected function on_Touch(e: TouchEvent): void {
        _isDragging = true;
    }

    protected function on_TouchEnd(e: TouchEvent): void {
        _isDragging = false;
    }

    protected function on_enterFrame(e: Event): void {

        if (_isDragging) {
            _angle = Math.atan2(root.mouseY - _startY, root.mouseX - _startX) / (Math.PI / 180);
            rotation = _angle;
            stick.rotation = -_angle;


            stick.x = mouseX;
            if (stick.x > _radius) {
                stick.x = _radius;
            }
        } else {
            _xSpeed = -stick.x * _tension;
            stick.x += _xSpeed;
        }

        _amplitudeY = Math.sin(_angle * (Math.PI / 180)) * (stick.x / 8);
        _amplitudeX = Math.cos(_angle * (Math.PI / 180)) * (stick.x / 8);


    }


}
}

您必须通过触摸事件的父坐标分隔您的操纵杆,包括 TOUCH_DRAG 以更新您的操纵杆的内部位置。然后,如果注册了 TOUCH_BEGIN 事件,每个操纵杆应通过查询自己的 (x,y) 坐标并与 localToGlobal 结果或 [=14= 进行比较来检查其坐标是否在该操纵杆的区域中] 和 e.stageY,如果不是他们的,则退出事件侦听器。此外,您应该使用其他多点触控模式 MultitouchInputMode.TOUCH_POINT 才能正常工作,因为只有此模式才能调度正确的触摸 drag/move 事件。一个例子:

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
private var _touchIndex:int; 
private function stageInit(e: Event): void {
    this.removeEventListener(Event.ADDED_TO_STAGE, stageInit);

    _startX = x;
    _startY = y;
    _radius = background.width / 2

    stage.addEventListener(TouchEvent.TOUCH_BEGIN, on_Touch);
    stage.addEventListener(TouchEvent.TOUCH_END, on_TouchEnd);
    stage.addEventListener(TouchEvent.TOUCH_DRAG, on_TouchDrag);
}
protected function on_Touch(e: TouchEvent): void {
    var pe:Point=new Point(e.stageX,e.stageY);
    var pc:Point=localToGlobal(new Point()); 
    // what if joystick was moved past placing? Otherwise use center X and Y stored
    // it's critical that these points must be in same coordinate system
    if (Point.distance(pe,pc)<_radius) {
        // this touch is ours, keep it
        _isDragging=true;
        // grab touch point ID
        _touchIndex=e.touchPointID;
    }
}
protected function on_TouchEnd(e: TouchEvent): void {
    if (!_isDragging) return;
    if (e.touchPointID==_touchIndex) {
        // it is "our" touch that's been released
        _isDragging = false;
    }
}
    protected function on_TouchDrag(e: TouchEvent): void {
    if (!_isDragging) return;
    if (e.touchPointID==_touchIndex) {
        // it is "our" touch that's been dragged
        // do your maths to update the joystick
        // make sure you will use local coordinates to update parts of joystick!
    }
}

为了更大的利益,不要忘记在 Event.REMOVED_FROM_STAGE 听众中清除那些舞台附加听众。

使用Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

不要使用TouchEvent.DRAG,使用TouchEvent.MOVE

你不需要像我之前说的那样分开你的触摸事件,因为你有两个不同的 Joystick.