【问题标题】:Blocking the movement of an object in a boundary阻止对象在边界中的移动
【发布时间】:2020-02-18 21:23:08
【问题描述】:

我正在尝试制作一个模拟操纵杆控件的 Web 应用程序。我设法在点击时生成了 2 个圆圈。 (一个静止的作为边界,另一个跟随我的鼠标光标作为操纵杆)。现在我正试图弄清楚如何限制生成边界内的操纵杆运动。任何帮助将不胜感激。

<div class="eye"> </div>
    <div class="ball">

    </div>
</div>
<script>
    var balls = document.getElementsByClassName("ball");
    document.onmousemove = function () {
        var x = event.clientX + "px";
        var y = event.clientY + "px";
        // event.clientX => gets the horizontal coordinate of the mouse
        // event.clientY => gets the vertical coordinate of the mouse
        // window.innerWidth => gets the browser width
        // window.innerHeight => gets the browser height

        for (var i = 0; i < 20; i++) {
            balls[i].style.left = x;
            balls[i].style.top = y;
            balls[i].style.transform = "translate(x , y)"
        }

【问题讨论】:

  • 代码不完整。请修改您的问题...当您针对一个元素时,不要使用 getElementsByClassName ......在这种情况下就是这样。使用 document.querySelector("ball")
  • 另外,你也应该在你的事件处理程序中使用一个参数——通常是一个名为 e 的变量,而不是关闭全局事件对象;不管怎样,它都可以工作。此外,循环仅在更新一堆球时似乎有用,但您不需要通过编辑样式来执行此操作,因为您可以直接访问属性,事实上,如果您使用画布执行此操作,可以导致倾斜问题。我试图提供帮助,所以我写了一个答案,但是,我感觉很有帮助,更多的代码和清晰度会帮助你从其他人那里得到更好的答案。

标签: javascript joystick


【解决方案1】:

也许最快的解决方案是将 x 除为一个数字。棘手但应该可以工作。

balls[i].style.left = x /10;
balls[i].style.top = y/10;

为什么你需要那个循环?它将阻止此解决方案。

【讨论】:

    【解决方案2】:

    鼠标单击时,xs 和 ys 被视为基准点。

            if (x < xs - barrierDist) {
            x = xs - barrierDist;}
        else if (x > xs + barrierDist) {
            x = xs + barrierDist;}
        else {
            x = x;}
        /*      barrier for y movement*/
        if (y < ys - barrierDist) {
            y = ys - barrierDist;}
        else if (y > ys + barrierDist) {
            y = ys + barrierDist;}
        else {
            y = y;}
    

    【讨论】:

    • 这似乎没有考虑到操纵杆图形元素的位置,你可以不用 etra else {x=x;} 和 else {y=y;}
    【解决方案3】:

    嗯,这是一个游戏编程问题,只看到上面的 sn-p,我会说你有一些工作要做,但也许这会有所帮助......

    要创建一个边界,简单的方法是拥有一个不可见的对象,您可能希望在事件处理程序之外进行此操作

    var boundary = {};
    boundary.x = 100; //the top left, x,y position of the bounding box
    boundary.y = 100;
    boundary.width = 400; //you don't really need to keep these unless you create an invisible button
    boundary.height = 400; //which is an area that you'd use to see if the mouse is on it
    boundary.maxX = boundary.x+boundary.width;
    boundary.maxY = boundary.y+boundary.height;
    

    在您的事件处理代码中,您可以将 x 和 y 值放入一个对象中

    pt = {}; //pt means point
    pt.x = event.clientX;
    pt.y = event.clientY;
    

    现在,让我们设置辅助函数,并且再次将它放在事件处理程序之外

    //this is basically a type of collision detection, pt to box collision
    function isPtWithinBoundary (pt,b){
       //x,y are the coordinates of the mouse point, and b is the boundary object
       if(pt.x<b.x |pt.x>b.maxX|pt.y<b.y|pt.y>b.maxY){
          //the pt is outside the boundary
          return False;
       }
       //the pt is inside or on the boundary
       return True;
    }
    

    现在我们从您的事件处理程序中调用辅助函数

    if (isPtWithinBoundary(pt,boundary)){
       //do what needs to be done if it's in the boundaries
    }else{
       //do what needs to be done if it isn't
    }
    

    同样,这个问题更多是关于游戏或 UI 编程的,你可能会被告知最好在 https://gamedev.stackexchange.com/ 之类的地方提出此类问题

    但是,希望它有所帮助...如果您也需要帮助放置图形,那是另一个问题。您只是以某种方式将操纵杆的绘制限制在边界...绘制它以多种方式完成,所以我将由您决定,但是,作为示例,您可以通过将其减少为相对于点。

       joystick.x=pt.x-joystick.width/2; //you could store the repeated division by 2 to optimize
       joystick.y=pt.y-joystick.height/2;
       //remember that b represents the boundary object
       if (joystick.x<b.x){
          joystick.x=b.x;
       }else if (joystick.x+joystick.width>b.maxX){
           joystick.x=b.maxX-joystick.width;
       }
       if (joystick.y<b.y){
            joystick.y=b.y;
       }else if (joystick.y+joystick.height>b.maxY){
            joystick.y=b.maxY-joystick.height;
       }
    
       //or this could be done by radius or a bunch of other ways
    

    让我知道这是否有帮助,或者如果我在某个地方搞砸了,我不小心把你的鼻涕弄糊涂了

    【讨论】:

    • 最后感谢您的回答,我采用了一个简单的解决方案。 ` if (x xs + barrierDist) { x = xs + barrierDist;} else { x = x;} /* y 运动的障碍*/ if (y ys + barrierDist) { y = ys + barrierDist;} else { y = y;} ` 不是最优雅的解决方案,但它有效。
    • 正如我回复您的回答...这似乎没有考虑到操纵杆的图形元素的位置(如果它有宽度或高度),您可能没有额外的 {x=x;} 和其他 {y=y;}
    猜你喜欢
    • 1970-01-01
    • 2017-10-05
    • 2017-05-01
    • 2014-05-19
    • 2017-02-19
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多