【问题标题】:PhysicsJS - Angular position animationPhysicsJS - 角度位置动画
【发布时间】:2014-04-27 08:22:36
【问题描述】:

我正在使用PhysicsJS 创建一个杂耍游戏。我只有一个球(圆形)和一只鞋(使用凸多边形形状的方形)。鞋子设置为固定并在 mousemove 上沿 x 轴移动。

正方形:

square = Physics.body('convex-polygon', {
    x: 250,
    y: 400,
    vertices: [
        { x: -68, y: 29 },
        { x: 68, y: 29 },
        { x: 69, y: -29 },
        { x: -68, y: -29 }
    ],
    angle: -0.2,
    view: shoeImage,
    fixed: true,
    restitution: 1
});

world.add(square);

鼠标移动事件:

jQuery('canvas').on('mousemove', function (e) {
    var offset = $(this).offset();
    var relativeX = (e.pageX - offset.left);
    square.state.pos.set(relativeX, 400);
});

我还在鞋子上添加了一个点击事件以产生“踢球效果”。到目前为止,我已经通过更改square.state.angular.pos 并使用setTimeout 函数将其设置回之前的角度位置来完成此操作。

jQuery('canvas').on('click', function (e) {
    if (square.state.angular.pos == -0.2) {
        square.state.angular.pos = 0.3;
    }
    else {
        square.state.angular.pos = -0.2;
    }

    setTimeout(function() { resetShoe(square); }, 500);
});

function resetShoe(square) {
    if (square.state.angular.pos == -0.2) {
        square.state.angular.pos = 0.3;
    }
    else {
        square.state.angular.pos = -0.2;
    }
}

你可以看到它在工作here。它工作得很好,但我希望这是动画而不是定格动画。我就是想不出办法。

【问题讨论】:

    标签: javascript html canvas physicsjs


    【解决方案1】:

    好的,所以我想出了解决这个问题的方法。我按照文档中显示的示例进行操作,可以创建new subtypes 并拥有自己的functions

    我使用kick 函数为convex-polygon 创建了一个鞋子类型

    Physics.body('shoe', 'convex-polygon', function( parent ){
    
        return {
    
            kick: function (operator) {
                if (operator == "add") {
                    if (this.state.angular.pos < 0.3) {
                        this.state.angular.pos += 0.1;
                        timer = setTimeout(function() { square.kick("add"); }, 20);
                    }
                    else {
                        timer = setTimeout(function() { square.kick("subtract"); }, 20);
                    }
                }
    
                if (operator == "subtract") {
                    if (this.state.angular.pos > -0.2) {
                        this.state.angular.pos -= 0.1;
                        timer = setTimeout(function() { square.kick("subtract"); }, 20);
                    }
                    else {
                        clearTimeout(timer);
                    }
                }
            }
        };
    });
    

    kick 函数将角度增加到 0.3 并将角度减小到原始角度 -0.2。可能有更好的方法来做到这一点。

    所以当点击事件被触发时,kick 函数被调用:kick("add");

    jQuery('canvas').on('click', function (e) {
    
        clearTimeout(timer);
    
        world.subscribe('step', function( data ){
            square.kick("add");
            // only execute callback once
            world.unsubscribe( 'step', data.handler );
        });
    });
    

    clearTimeout用于消除鞋子的重复动画,以防鼠标重复点击。

    【讨论】:

      【解决方案2】:

      您的总体思路是正确的,但有更好的方法来做到这一点。

      如果您订阅“integrate:positions”事件(这是行为所做的),您可以逐步更改每个步骤的位置,直到达到您想要的位置。

      rotate: function( endAng, vel ){
      
          var shoe = this; // depending on how you implement this...
      
          if ( vel === 0 ){
              return; // ... you'll never get there
          }
      
          // stop any previous animation attempt
          world.unsubscribe('integrate:positions', this.rotateCallback);
      
          this.endAng = endAng % (Math.PI * 2); // mod by 2Pi since it's circular position
          this.vel = vel;
      
          world.subscribe('integrate:positions', this.rotateCallback, this);
      },
      
      rotateCallback: function( data ){
          var shoe = this; // depending on how you implement this...
          var pos = shoe.state.angular.pos % (Math.PI * 2); // mod by 2Pi since it's circular position
      
          pos = shoe.state.angular.pos = pos + this.vel * data.dt; // change in pos = velocity x change in time
      
          // stop at the end
          if ( 
              this.vel > 0 && pos > this.endAng || // increasing
              this.vel < 0 && pos < this.endAng // decreasing
          ){
              world.unsubscribe(data.topic, data.handler);
          }
      }
      

      这些是一些对象上的方法......但这取决于你如何实现它。我假设您在鞋身上使用这些,但您也可以做出“踢”行为并将其作为参数传递给鞋......但这可能是不必要的。

      尚未测试,因此可能存在极端情况错误。但应该是一般的想法。

      注意:在physicsjs 的测试版中会有更好的方法来做到这一点......但在那之前这是一个好方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 2018-04-09
        • 1970-01-01
        • 1970-01-01
        • 2013-09-30
        相关资源
        最近更新 更多