【问题标题】:Attempting to get two simultaneous joysticks working with touch events试图让两个同时使用触摸事件的操纵杆
【发布时间】:2012-10-13 08:10:32
【问题描述】:

我已经为此奋斗了两天。我正在使用一个名为 ImpactJS 的 HTML5/JS 游戏引擎,有人制作了一个非常有用的插件来为移动设备创建操纵杆触摸区。这个想法是您在屏幕上指定一个区域,当该区域被触摸时,操纵杆被激活。

我使用的插件代码是here。我稍微修改了它以添加“curPos”(用户当前触摸的点的 x 和 y 坐标),否则所有代码都是相同的。我一直在尝试自己解决这个问题并联系原始创建者,但目前他们似乎无法联系到,我无处可去。

我确定我在这里做错了什么,但是虽然我可以让触控区域自己完美地工作,但每次我尝试同时使用两个操纵杆时,它们都会部分地相互覆盖。

我在游戏初始化时指定了如下两个区域:

    this.joystick1 = new TouchJoystickZone(0, 0, ig.system.width / 2, ig.system.height);
    this.joystick2 = new TouchJoystickZone(ig.system.width / 2, 0, ig.system.width / 2, ig.system.height);

this.joystick1 负责玩家轮换。 this.joystick2 负责玩家加速。在我的 Player 实体中,我有两个操纵杆的以下移动代码。同样,当我只有一根手指在屏幕上/一个正在使用的操纵杆上时,这非常有效:

            if( ig.ua.mobile ) {
            // ROTATION
            if (ig.game.joystick1.touchStart.x > 0 && ig.game.joystick1.touchStart.x < ig.system.width/2) {
                if (Math.abs(ig.game.joystick1.delta.x) >= 50 || Math.abs(ig.game.joystick1.delta.y) >= 50) {
                    this.joystickAngle = ig.game.Controller.toDegrees(ig.game.Controller.joystickAngle());
                    if (this.angle > this.joystickAngle + 20) {
                        this.angle -= this.turnSpeed * ig.system.tick;
                    }

                    else if (this.angle < this.joystickAngle - 20) {
                        this.angle += this.turnSpeed * ig.system.tick;
                    }

                    else {
                        this.angle = this.joystickAngle;
                    }
                } 
            }

            // THRUST
            if (ig.game.joystick2.touchStart.x > ig.system.width / 2) {
                if (ig.game.joystick2.delta.y <= -50) {
                    this.accel.x = Math.cos(this.angle*Math.PI/180)*this.thrust;
                    this.accel.y = (Math.sin(this.angle*Math.PI/180)*this.thrust);
                    this.fuel -= 0.1;
                }

                else if (ig.game.joystick2.delta.y >= 50) {
                    this.accel.x = Math.cos(this.angle*Math.PI/180)*-this.thrust;
                    this.accel.y = (Math.sin(this.angle*Math.PI/180)*-this.thrust);
                    this.fuel -= 0.1;
                }

            }

            else {
                this.accel.x = 0;
                this.accel.y = 0;
            }
        }

但是,只要我将第二根手指放在屏幕上,第一个操纵杆就会被覆盖。我可以旋转然后移动或移动然后旋转,它工作正常,但我需要同时做这两个。

我发现 touchStart.x 和 touchStart.y 似乎在我点击以使用另一根操纵杆而不只是相关的操纵杆 1 或操纵杆 2 时为两个操纵杆设置,即使在插件代码中这些坐标只是意味着如果该操纵杆的触摸在指定区域内,则会受到影响。我相信这部分是造成这个问题的原因。在这个阶段,我已经花了几个小时试图弄清楚这一点,并且就像我开始时一样迷茫。

有人可以同时使用这两个操纵杆为我指明正确的方向吗?

【问题讨论】:

  • 我认为这在 javascript 中是不可能的,因为它不是多线程来并行处理的
  • 你在什么设备上测试它? - 此设备是否支持捏合/旋转以外的多点触控
  • 对不起,我忘了提及设备详细信息。我正在通过使用 Ejecta 在 Xcode 中编译并部署到 iOS(据称该插件支持并且实际上是为其设计的)在 iPhone 4 上进行测试。创建者的论坛帖子中提到了多点触控 - 有一个未注册的已知错误,但这显然仅适用于我同时使用另一个特定插件的情况,我没有。
  • @memosdp Worker 不能用于那个吗?主线程只需要访问DOM,对吧?

标签: javascript html multi-touch impactjs


【解决方案1】:

您正在使用的操纵杆脚本只是在寻找第一根手指。以下来自第 47-48 行

    var x = ev.touches[0].pageX - pos.left,
        y = ev.touches[0].pageY - pos.top;

“0”确定要跟踪的手指。

脚本将被更改为知道哪个手指在哪个元素上,然后只跟踪那个手指。您可以通过确定首先按下哪个元素或按位置来做到这一点。

JSFiddle 示例:http://jsfiddle.net/7WR88/5/

http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/

【讨论】:

  • 问题是,我认为因为我正在创建该对象的两个实例(一个用于joystick1,另一个用于joystick2),每次使用“ev”时它仅指与相关的触摸那个特别的操纵杆。不是这样吗? (我注意到如果我将两个手指放在每个操纵杆的区域中,joystick1.startTouch.x 和 joystick2.startTouch.x 都有值且不为 0,这些值与第二次触摸的 x 坐标相同)。
  • 如果在您点击第二个区域时另一根手指已经按下,则另一根手指是“第一个”触摸的。棘手的部分是这也适用于相反的方式。 “第一次”触摸是已经按下的触摸。我会尝试在 jsfiddle 中举一个例子。
  • jsfiddle.net/7WR88/5 您可以在 iPhone 上的这个 jsfiddle 中看到,如果您用每根手指按下一个,则每个手指都会记录 2 次触摸。
  • 感谢您的澄清!然而,这是否意味着在我的初始化中创建游戏杆 1 和游戏杆 2 毫无意义?我还将 ev.touches 的长度打印到控制台并始终得到“1”,无论我是否有两个手指向下或一个(奇怪的是,当 first 放下另一个水龙头时,它有时会说“ 2' 几帧,然后回到 1)。但是,两个操纵杆的 startTouch 坐标仍然注册(除了它们在第二次触摸时变得相同)-
  • -我只是不确定为什么该插件据称是为 iOS 上的多点触控而设计的,使用此引擎时需要进行如此多的修改。我只是认为这是我使用不正确的问题。
【解决方案2】:

正如@Dcullen 所提到的,从第一次触摸开始,每个事件中可能会有多次触摸。

遍历 ev.touches 集合并查看每次触摸是否落入热区将是一个简单的解决方案。如果它在热区 1 下,则将其视为操纵杆 1 的触摸。如果它落在热区 2 下,则将其视为操纵杆 2 的触摸。

这意味着触摸出现的顺序无关紧要,因为如果它们靠近它,它们总是会映射到正确的操纵杆。​​p>

【讨论】:

    猜你喜欢
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多