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
.
我目前正在 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
.