微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

物体卡在地板上

如何解决物体卡在地板上

好的,我正在可汗学院使用 PJS 制作一个拖放程序,这是我的代码

/*    Just a simple drag and drop program    */ 

// Todo: 
// * Add realistic bouncing
// * Add particles when bouncing

// Changeable variables
var testShapeWidth = 45;
var testShapeHeight = 45;
var testShapeX = 200;
var testShapeY = 200;
var gravityStrength = 0.8;


// Unchangeable variables
var onGround = false;
var mouseDown = false;

var round2 = function (num) {
    num = num / 2;
    num = round(num);
    num *= 2;
    return num;
};

var checkIfClicked = function(x,y,w,h) {
    var mx = mouseX;
    var my = mouseY;
    
    var rightSide = x + w;
    var bottomSide = y + h;
    
    if (mx > x && mx < rightSide && my > y && my < bottomSide) {
        return true;
    }
    
    return false;
};

var draw = function() {
    background(255,255,255);
    fill(0);
    rect(testShapeX,testShapeY,testShapeWidth,testShapeHeight);
    
    testShapeY = round2(testShapeY);
    
    // Check if on the ground or not and update the onGround variable
    if (testShapeY + testShapeHeight < 400) { // If the y coorordinate of the bottom edge of the rectangle is less than 400...
        onGround = false; // The rectangle is not on the ground
    } else if (testShapeY + testShapeHeight >= 400) { // If the y coorordinate of the bottom edge of the rectangle is greater than or equal to 400...
        gravityStrength = round2(gravityStrength * -1) / 2;
    }
    
    if (!onGround && !mouseDown) {
        testShapeY += gravityStrength;
        gravityStrength += 0.2;
    }
    
    if (mouseDown) {
        testShapeX = mouseX - testShapeWidth / 2;
        testShapeY = mouseY - testShapeHeight / 2;
        gravityStrength = 0;
    }
};

var mousepressed = function() {
    if (checkIfClicked(testShapeX,testShapeHeight)) {
        mouseDown = true;
    }
};
var mouseReleased = function() {
    mouseDown = false;
};

我刚刚通过替换这些行添加了弹跳:

else if (testShapeY + testShapeHeight >= 400) { // If the y coorordinate of the bottom edge of the rectangle is greater than or equal to 400...
        testShapeY = 400 - testShapeHeight;
        gravityStrength = 0;
}

这样:

else if (testShapeY + testShapeHeight >= 400) { // If the y coorordinate of the bottom edge of the rectangle is greater than or equal to 400...
        gravityStrength = round2(gravityStrength * -1) / 2;
}

但现在有时矩形会卡在地板上。下面是一个例子:

Example Video

一开始我以为是偶数和奇数的关系,这就是为什么我添加了round2函数(四舍五入到最接近的2)无济于事。我希望 stackoverflow 社区可以帮助我解决这个问题,因为我不能。您会找到指向我的项目 here链接

解决方法

你是个幸运的人,因为我不必筛选所有这些代码来了解问题所在(否则我今晚会帮助其他人,真的,代码太多了)。你的问题是数学。您的解决方案很简单。


问题

这是怎么回事:当物体低到足以穿过地板时,您反转并除以 2 gravityStrength。这正是出错的地方。

如果对象落在地平面下的像素数超过 gravityStrength / 2,则它无法再次上升,因为添加新的 gravityStrength 时它的位置仍将位于地面之下。然后它会再次恢复它的方向和一半 gravityStrength,确保它不会再从这个位置移动(除非你用手移动它)。它绝对卡住了。

解决办法

改变这个:

} else if (testShapeY + testShapeHeight >= 400) { // If the y coorordinate of the bottom edge of the rectangle is greater than or equal to 400...
    gravityStrength = round2(gravityStrength * -1) / 2;
}

为此:

} else if (testShapeY + testShapeHeight >= 400) { // If the y coorordinate of the bottom edge of the rectangle is greater than or equal to 400...
    testShapeY = 400; // now any speed will bounce. Lower this number to make sure that the object will "get stuck" after a while if otherwise it bounces forever
    gravityStrength = round2(gravityStrength * -1) / 2;
}

这里的想法是,您的算法将保持相同的工作方式,但不会让对象下降到足够低的位置,gravityStrength 无法使其恢复弹跳。或者,您可以将 testShapeY = 400; 下移一行,并将 testShapeY 变量基于新的 gravityStrength。那会很不错。

玩得开心!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。