【问题标题】:Algorithm to throw an element across screen [closed]在屏幕上抛出元素的算法[关闭]
【发布时间】:2021-06-18 02:02:50
【问题描述】:

我有一个应用程序,我希望用户能够在屏幕上扔/轻弹一个对象。本质上,他们会在屏幕上快速拖动元素并松开,然后它会继续以相同的速度向拖动它的方向移动,然后减速直到停止。

任何语言或伪代码的答案将不胜感激。或者,如果您可以指出该算法的名称,那也会有所帮助。 谢谢

【问题讨论】:

    标签: algorithm computer-science physics


    【解决方案1】:

    我会找到鼠标移动的速度并将对象的速度设置为鼠标的速度。 物体速度=鼠标速度 然后每滴答降低该速度,直到达到 0。

    如果你想让它更逼真,我会看这里:https://physics.stackexchange.com/questions/391318/how-to-calculate-a-change-in-velocity-as-a-result-of-friction

    【讨论】:

      【解决方案2】:

      这是我的尝试:

      1. 用户开始在(x1, y1) 位置拖动对象t1
      2. 用户在时间t2释放位置(x2, y2)的对象
      3. 使用点(x1, y1)(x2, y2) 的基本三角函数为您提供移动方向,以及两个点之间的距离
      4. 使用t1t2之间的距离时间差来计算移动的初速度
      5. 定义一个常数来定义速度随时间的下降,我们称之为减速
      6. 对于每个刻度:
        1. 根据前一次速度减速量计算当前速度
        2. 使用当前速度方向计算对象的新位置。
      7. 当前速度达到零时结束。

      这是一个非常基本的 JavaScript 实现,它只使用方向向量而不是分别计算方向和速度:

      class Flick {
        static tick = 10;
        static deceleration = .875;
        
        constructor(element) {
          this.element = element;
          this.element.addEventListener('dragstart', (e) => this.start(e));
          this.element.addEventListener('dragend', (e) => this.end(e));
          this.interval = null;
        }
        
        start(e) {
          const {screenX, screenY} = e;
          this.p1 = [screenX, screenY];
          this.t1 = Date.now();
          this.clear();
        }
        
        end(e) {
          const {screenX, screenY} = e;
          this.p2 = [screenX, screenY];
          this.t2 = Date.now();
          this.animate();
        }
        
        animate() {
          const [x1, y1] = this.p1
          const [x2, y2] = this.p2
          const [dx, dy] = [x2 - x1, y2 - y1];
          const t = this.t2 - this.t1
          
          this.move(dx, dy);
          this.vector = [dx * Flick.tick / t, dy * Flick.tick / t];
          this.interval = setInterval(() => {
            const [dx, dy] = this.vector;
            
            if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
              this.clear();
            } else {
              this.move(dx, dy);      
              this.vector = [dx * Flick.deceleration, dy * Flick.deceleration];
            }
          }, Flick.tick);
        }
        
        move(dx, dy) {
          const {x, y} = this.element.getBoundingClientRect();
         
          this.element.style.left = Math.round(x + dx) + 'px';
          this.element.style.top = Math.round(y + dy) + 'px';
        }
        
        clear() {
          this.interval && clearInterval(this.interval);
        }
      }
      
      new Flick(document.getElementById('object'));
      #object {
        width: 50px;
        height: 50px;
        background-color: teal;
        position: absolute;
      }
      &lt;div id="object" draggable="true"&gt;&lt;/div&gt;

      【讨论】:

      • 那部分我明白了。我遇到问题的部分是我如何让它朝着同一个方向移动?以及如何以一定的速度移动它?我猜我会有一个循环,它会在每次迭代中移动它,并且每次都会抑制速度直到变为零。但是基于轨迹我如何计算循环的每次迭代的 x,y 值?以及如何控制时间以使其开始以相同的速度移动?谢谢
      • 我的回答解释了这一切……移动方向只是一个向量,您可以按照步骤 3 中的说明计算。如何使用该信息来更新对象的位置在步骤 6 中进行了说明。它是只是基本的三角函数和算术。
      • 谢谢,我试过运行它,但它似乎只是拖动对象,松开后它不会继续移动,或者bock消失了。
      猜你喜欢
      • 1970-01-01
      • 2018-10-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      相关资源
      最近更新 更多